//Pascal &or the FreePascal use of nintendo 2ds, 3ds regime // c file & header origin author (Steveice10) // // Copyright (c) 2013, 2015, 2017 Kenneth Dwayne Lee Bsc. // all rights reserved. // {$ifdef 3dsintf} {* * @file y2r.h * @brief Y2R service for hardware YUV->RGB conversions } {* * @brief Input color formats * * For the 16-bit per component formats, bits 15-8 are padding and 7-0 contains the value. } {/< 8-bit per component, planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples).\n Usually named YUV422P. } {/< 8-bit per component, planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples).\n Usually named YUV420P. } {/< 16-bit per component, planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples).\n Usually named YUV422P16. } {/< 16-bit per component, planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples).\n Usually named YUV420P16. } {/< 8-bit per component, packed YUV 4:2:2, 16bpp, (Y0 Cb Y1 Cr).\n Usually named YUYV422. } type Y2R_InputFormat = (INPUT_YUV422_INDIV_8 := $0,INPUT_YUV420_INDIV_8 := $1, INPUT_YUV422_INDIV_16 := $2,INPUT_YUV420_INDIV_16 := $3, INPUT_YUV422_BATCH := $4); {* * @brief Output color formats * * Those are the same as the framebuffer and GPU texture formats. } {/< The alpha component is the 8-bit value set by @ref Y2RU_SetAlpha } {/< The alpha bit is the 7th bit of the alpha value set by @ref Y2RU_SetAlpha } Y2R_OutputFormat = (OUTPUT_RGB_32 := $0,OUTPUT_RGB_24 := $1, OUTPUT_RGB_16_555 := $2,OUTPUT_RGB_16_565 := $3 ); {* * @brief Rotation to be applied to the output } Y2R_Rotation = (ROTATION_NONE := $0,ROTATION_CLOCKWISE_90 := $1, ROTATION_CLOCKWISE_180 := $2,ROTATION_CLOCKWISE_270 := $3 ); {* * @brief Block alignment of output * * Defines the way the output will be laid out in memory. } {/< The s32 buffer will be laid out in linear format, the usual way. } {/< The s32 will be stored as 8x8 blocks in Z-order.\n Useful for textures since it is the format used by the PICA200. } Y2R_BlockAlignment = (BLOCK_LINE := $0,BLOCK_8_BY_8 := $1); {* * @brief Coefficients of the YUV->RGB conversion formula. * * A set of coefficients configuring the RGB to YUV conversion. Coefficients 0-4 are unsigned 2.8 * fixed pointer numbers representing entries on the conversion matrix, while coefficient 5-7 are * signed 11.5 fixed point numbers added as offsets to the RGB s32. * * The overall conversion process formula is: * @code * R = trunc((rgb_Y * Y + r_V * V) + 0.75 + r_offset) * G = trunc((rgb_Y * Y - g_U * U - g_V * V) + 0.75 + g_offset) * B = trunc((rgb_Y * Y + b_U * U ) + 0.75 + b_offset) * @endcode } Y2R_ColorCoefficients = record rgb_Y : u16; r_V : u16; g_V : u16; g_U : u16; b_U : u16; r_offset : u16; g_offset : u16; b_offset : u16; end; PY2R_ColorCoefficients = ^Y2R_ColorCoefficients; {* * @brief Preset conversion coefficients based on ITU standards for the YUV->RGB formula. * * For more details refer to @ref Y2R_ColorCoefficients } {/< Coefficients from the ITU-R BT.601 standard with PC ranges. } {/< Coefficients from the ITU-R BT.709 standard with PC ranges. } {/< Coefficients from the ITU-R BT.601 standard with TV ranges. } {/< Coefficients from the ITU-R BT.709 standard with TV ranges. } Y2R_StandardCoefficient = (COEFFICIENT_ITU_R_BT_601 := $0,COEFFICIENT_ITU_R_BT_709 := $1, COEFFICIENT_ITU_R_BT_601_SCALING := $2, COEFFICIENT_ITU_R_BT_709_SCALING := $3 ); PY2R_StandardCoefficient = ^Y2R_StandardCoefficient; {* * @brief Structure used to configure all parameters at once. * * You can send a batch of configuration parameters using this structure and @ref Y2RU_SetConversionParams. * } {/< Value passed to @ref Y2RU_SetInputFormat } {/< Value passed to @ref Y2RU_SetOutputFormat } {/< Value passed to @ref Y2RU_SetRotation } {/< Value passed to @ref Y2RU_SetBlockAlignment } {/< Value passed to @ref Y2RU_SetInputLineWidth } {/< Value passed to @ref Y2RU_SetInputLines } {/< Value passed to @ref Y2RU_SetStandardCoefficient } {/< Value passed to @ref Y2RU_SetAlpha } Y2R_ConversionParams = record flag0 : longint; input_line_width : s16; input_lines : s16; flag1 : word; unused : u8; alpha : u16; end; PY2R_ConversionParams = ^Y2R_ConversionParams; const bm_Y2R_ConversionParams_input_format = $FF; bp_Y2R_ConversionParams_input_format = 0; bm_Y2R_ConversionParams_output_format = $FF00; bp_Y2R_ConversionParams_output_format = 8; bm_Y2R_ConversionParams_rotation = $FF0000; bp_Y2R_ConversionParams_rotation = 16; bm_Y2R_ConversionParams_block_alignment = $FF000000; bp_Y2R_ConversionParams_block_alignment = 24; bm_Y2R_ConversionParams_standard_coefficient = $FF; bp_Y2R_ConversionParams_standard_coefficient = 0; function input_format(var a : Y2R_ConversionParams) : Y2R_InputFormat; procedure set_input_format(var a : Y2R_ConversionParams; __input_format : Y2R_InputFormat); function output_format(var a : Y2R_ConversionParams) : Y2R_OutputFormat; procedure set_output_format(var a : Y2R_ConversionParams; __output_format : Y2R_OutputFormat); function rotation(var a : Y2R_ConversionParams) : Y2R_Rotation; procedure set_rotation(var a : Y2R_ConversionParams; __rotation : Y2R_Rotation); function block_alignment(var a : Y2R_ConversionParams) : Y2R_BlockAlignment; procedure set_block_alignment(var a : Y2R_ConversionParams; __block_alignment : Y2R_BlockAlignment); function standard_coefficient(var a : Y2R_ConversionParams) : Y2R_StandardCoefficient; procedure set_standard_coefficient(var a : Y2R_ConversionParams; __standard_coefficient : Y2R_StandardCoefficient); {* * @brief Initializes the y2r service. * * This will internally get the handle of the service, and on success call Y2RU_DriverInitialize. } function y2rInit:s32;cdecl;external; {* * @brief Closes the y2r service. * * This will internally call Y2RU_DriverFinalize and close the handle of the service. } function y2rExit:s32;cdecl;external; {* * @brief Used to configure the input format. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetInputFormat(format:Y2R_InputFormat):s32;cdecl;external; {* * @brief Used to configure the output format. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetOutputFormat(format:Y2R_OutputFormat):s32;cdecl;external; {* * @brief Used to configure the rotation of the output. * * It seems to apply the rotation per batch of 8 lines, so the output will be (height/8) images of size 8 x width. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetRotation(rotation:Y2R_Rotation):s32;cdecl;external; {* * @brief Used to configure the alignment of the output buffer. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetBlockAlignment(alignment:Y2R_BlockAlignment):s32;cdecl;external; {* * @brief Used to configure the width of the image. * @param line_width Width of the image in pixels. Must be a multiple of 8, up to 1024. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetInputLineWidth(line_width:u16):s32;cdecl;external; {* * @brief Used to configure the height of the image. * @param num_lines Number of lines to be converted. * * A multiple of 8 seems to be preferred. * If using the @ref BLOCK_8_BY_8 mode, it must be a multiple of 8. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetInputLines(num_lines:u16):s32;cdecl;external; {* * @brief Used to configure the color conversion formula. * * See @ref Y2R_ColorCoefficients for more information about the coefficients. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } (* Const before type ignored *) function Y2RU_SetCoefficients(coefficients:PY2R_ColorCoefficients):s32;cdecl;external; {* * @brief Used to configure the color conversion formula with ITU stantards coefficients. * * See @ref Y2R_ColorCoefficients for more information about the coefficients. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetStandardCoefficient(coefficient:Y2R_StandardCoefficient):s32;cdecl;external; {* * @brief Used to configure the alpha value of the output. * @param alpha 8-bit value to be used for the output when the format requires it. * * @note Prefer using @ref Y2RU_SetConversionParams if you have to set multiple parameters. } function Y2RU_SetAlpha(alpha:u16):s32;cdecl;external; {* * @brief Used to enable the end of conversion interrupt. * @param should_interrupt Enables the interrupt if true, disable it if false. * * It is possible to fire an interrupt when the conversion is finished, and that the DMA is done copying the data. * This interrupt will then be used to fire an event. See @ref Y2RU_GetTransferEndEvent. * By default the interrupt is enabled. * * @note It seems that the event can be fired too soon in some cases, depending the transfer_unit size.\n Please see the note at @ref Y2RU_SetReceiving } function Y2RU_SetTransferEndInterrupt(should_interrupt:bool):s32;cdecl;external; {* * @brief Gets an handle to the end of conversion event. * @param end_event Pointer to the event handle to be set to the end of conversion event. It isn't necessary to create or close this handle. * * To enable this event you have to use @codeC Y2RU_SetTransferEndInterrupt(true);@endcode * The event will be triggered when the corresponding interrupt is fired. * * @note It is recommended to use a timeout when waiting on this event, as it sometimes (but rarely) isn't triggered. } function Y2RU_GetTransferEndEvent(end_event:PHandle):s32;cdecl;external; {* * @brief Configures the Y plane buffer. * @param src_buf A pointer to the beginning of your Y data buffer. * @param image_size The total size of the data buffer. * @param transfer_unit Specifies the size of 1 DMA transfer. Usually set to 1 line. This has to be a divisor of image_size. * @param transfer_gap Specifies the gap (offset) to be added after each transfer. Can be used to convert images with stride or only a part of it. * * @warning transfer_unit+transfer_gap must be less than 32768 (0x8000) * * This specifies the Y data buffer for the planar input formats (INPUT_YUV42*_INDIV_*). * The actual transfer will only happen after calling @ref Y2RU_StartConversion. } (* Const before type ignored *) function Y2RU_SetSendingY(src_buf:pointer; image_size:u32; transfer_unit:s16; transfer_gap:s16):s32;cdecl;external; {* * @brief Configures the U plane buffer. * @param src_buf A pointer to the beginning of your Y data buffer. * @param image_size The total size of the data buffer. * @param transfer_unit Specifies the size of 1 DMA transfer. Usually set to 1 line. This has to be a divisor of image_size. * @param transfer_gap Specifies the gap (offset) to be added after each transfer. Can be used to convert images with stride or only a part of it. * * @warning transfer_unit+transfer_gap must be less than 32768 (0x8000) * * This specifies the U data buffer for the planar input formats (INPUT_YUV42*_INDIV_*). * The actual transfer will only happen after calling @ref Y2RU_StartConversion. } (* Const before type ignored *) function Y2RU_SetSendingU(src_buf:pointer; image_size:u32; transfer_unit:s16; transfer_gap:s16):s32;cdecl;external; {* * @brief Configures the V plane buffer. * @param src_buf A pointer to the beginning of your Y data buffer. * @param image_size The total size of the data buffer. * @param transfer_unit Specifies the size of 1 DMA transfer. Usually set to 1 line. This has to be a divisor of image_size. * @param transfer_gap Specifies the gap (offset) to be added after each transfer. Can be used to convert images with stride or only a part of it. * * @warning transfer_unit+transfer_gap must be less than 32768 (0x8000) * * This specifies the V data buffer for the planar input formats (INPUT_YUV42*_INDIV_*). * The actual transfer will only happen after calling @ref Y2RU_StartConversion. } (* Const before type ignored *) function Y2RU_SetSendingV(src_buf:pointer; image_size:u32; transfer_unit:s16; transfer_gap:s16):s32;cdecl;external; {* * @brief Configures the YUYV source buffer. * @param src_buf A pointer to the beginning of your Y data buffer. * @param image_size The total size of the data buffer. * @param transfer_unit Specifies the size of 1 DMA transfer. Usually set to 1 line. This has to be a divisor of image_size. * @param transfer_gap Specifies the gap (offset) to be added after each transfer. Can be used to convert images with stride or only a part of it. * * @warning transfer_unit+transfer_gap must be less than 32768 (0x8000) * * This specifies the YUYV data buffer for the packed input format @ref INPUT_YUV422_BATCH. * The actual transfer will only happen after calling @ref Y2RU_StartConversion. } (* Const before type ignored *) function Y2RU_SetSendingYUYV(src_buf:pointer; image_size:u32; transfer_unit:s16; transfer_gap:s16):s32;cdecl;external; {* * @brief Configures the destination buffer. * @param src_buf A pointer to the beginning of your destination buffer in FCRAM * @param image_size The total size of the data buffer. * @param transfer_unit Specifies the size of 1 DMA transfer. Usually set to 1 line. This has to be a divisor of image_size. * @param transfer_gap Specifies the gap (offset) to be added after each transfer. Can be used to convert images with stride or only a part of it. * * This specifies the destination buffer of the conversion. * The actual transfer will only happen after calling @ref Y2RU_StartConversion. * The buffer does NOT need to be allocated in the linear heap. * * @warning transfer_unit+transfer_gap must be less than 32768 (0x8000) * * @note * It seems that depending on the size of the image and of the transfer unit,\n * it is possible for the end of conversion interrupt to be triggered right after the conversion began.\n * One line as transfer_unit seems to trigger this issue for 400x240, setting to 2/4/8 lines fixes it. * * @note Setting a transfer_unit of 4 or 8 lines seems to bring the best s32s in terms of speed for a 400x240 image. } function Y2RU_SetReceiving(dst_buf:pointer; image_size:u32; transfer_unit:s16; transfer_gap:s16):s32;cdecl;external; {* * @brief Checks if the DMA has finished sending the Y buffer. * @param is_done pointer to the boolean that will hold the s32 * * True if the DMA has finished transferring the Y plane, false otherwise. To be used with @ref Y2RU_SetSendingY. } function Y2RU_IsDoneSendingY(is_done:Pbool):s32;cdecl;external; {* * @brief Checks if the DMA has finished sending the U buffer. * @param is_done pointer to the boolean that will hold the s32 * * True if the DMA has finished transferring the U plane, false otherwise. To be used with @ref Y2RU_SetSendingU. } function Y2RU_IsDoneSendingU(is_done:Pbool):s32;cdecl;external; {* * @brief Checks if the DMA has finished sending the V buffer. * @param is_done pointer to the boolean that will hold the s32 * * True if the DMA has finished transferring the V plane, false otherwise. To be used with @ref Y2RU_SetSendingV. } function Y2RU_IsDoneSendingV(is_done:Pbool):s32;cdecl;external; {* * @brief Checks if the DMA has finished sending the YUYV buffer. * @param is_done pointer to the boolean that will hold the s32 * * True if the DMA has finished transferring the YUYV buffer, false otherwise. To be used with @ref Y2RU_SetSendingYUYV. } function Y2RU_IsDoneSendingYUYV(is_done:Pbool):s32;cdecl;external; {* * @brief Checks if the DMA has finished sending the converted s32. * @param is_done pointer to the boolean that will hold the s32 * * True if the DMA has finished transferring data to your destination buffer, false otherwise. } function Y2RU_IsDoneReceiving(is_done:Pbool):s32;cdecl;external; type y2rUnkPara= array[0..15] of u16; function Y2RU_SetUnknownParams(params:y2rUnkPara):s32;cdecl;external; {* * @brief Sets all the parameters of Y2R_ConversionParams at once. * * Faster than calling the individual value through Y2R_Set* because only one system call is made. } (* Const before type ignored *) function Y2RU_SetConversionParams(params:PY2R_ConversionParams):s32;cdecl;external; {* * @brief Starts the conversion process } function Y2RU_StartConversion:s32;cdecl;external; {* * @brief Cancels the conversion } function Y2RU_StopConversion:s32;cdecl;external; {* * @brief Check if the conversion and DMA transfer are finished * * This can have the same problems as the event and interrupt. See @ref Y2RU_SetTransferEndInterrupt. } function Y2RU_IsBusyConversion(is_busy:Pbool):s32;cdecl;external; { Seems to check whether y2r is ready to be used } function Y2RU_PingProcess(ping:Pu8):s32;cdecl;external; function Y2RU_DriverInitialize:s32;cdecl;external; function Y2RU_DriverFinalize:s32;cdecl;external; {$endif 3dsintf} {$ifdef 3dsimpl} function input_format(var a : Y2R_ConversionParams) : Y2R_InputFormat; begin input_format:=Y2R_InputFormat((a.flag0 and bm_Y2R_ConversionParams_input_format) shr bp_Y2R_ConversionParams_input_format); end; procedure set_input_format(var a : Y2R_ConversionParams; __input_format : Y2R_InputFormat); begin a.flag0:= a.flag0 or ((u32(__input_format) shl bp_Y2R_ConversionParams_input_format) and bm_Y2R_ConversionParams_input_format); end; function output_format(var a : Y2R_ConversionParams) : Y2R_OutputFormat; begin output_format:= Y2R_OutputFormat((a.flag0 and bm_Y2R_ConversionParams_output_format) shr bp_Y2R_ConversionParams_output_format); end; procedure set_output_format(var a : Y2R_ConversionParams; __output_format : Y2R_OutputFormat); begin a.flag0:=a.flag0 or ((u32(__output_format) shl bp_Y2R_ConversionParams_output_format) and bm_Y2R_ConversionParams_output_format); end; function rotation(var a : Y2R_ConversionParams) : Y2R_Rotation; begin rotation:=Y2R_Rotation((a.flag0 and bm_Y2R_ConversionParams_rotation) shr bp_Y2R_ConversionParams_rotation); end; procedure set_rotation(var a : Y2R_ConversionParams; __rotation : Y2R_Rotation); begin a.flag0:=a.flag0 or ((u32(__rotation) shl bp_Y2R_ConversionParams_rotation) and bm_Y2R_ConversionParams_rotation); end; function block_alignment(var a : Y2R_ConversionParams) : Y2R_BlockAlignment; begin block_alignment:=Y2R_BlockAlignment((a.flag0 and bm_Y2R_ConversionParams_block_alignment) shr bp_Y2R_ConversionParams_block_alignment); end; procedure set_block_alignment(var a : Y2R_ConversionParams; __block_alignment : Y2R_BlockAlignment); begin a.flag0:=a.flag0 or ((u32(__block_alignment) shl bp_Y2R_ConversionParams_block_alignment) and bm_Y2R_ConversionParams_block_alignment); end; function standard_coefficient(var a : Y2R_ConversionParams) : Y2R_StandardCoefficient; begin standard_coefficient:=Y2R_StandardCoefficient((a.flag1 and bm_Y2R_ConversionParams_standard_coefficient) shr bp_Y2R_ConversionParams_standard_coefficient); end; procedure set_standard_coefficient(var a : Y2R_ConversionParams; __standard_coefficient : Y2R_StandardCoefficient); begin a.flag1:=a.flag1 or ((u32(__standard_coefficient) shl bp_Y2R_ConversionParams_standard_coefficient) and bm_Y2R_ConversionParams_standard_coefficient); end; {$endif 3dsimpl}