mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-01-14 20:29:32 +01:00
added RGB555 pixel output support to NTSC filters
This commit is contained in:
parent
aae753a9e7
commit
67bed12429
@ -1,7 +1,6 @@
|
|||||||
/* md_ntsc 0.1.2. http://www.slack.net/~ant/ */
|
/* md_ntsc 0.1.2. http://www.slack.net/~ant/ */
|
||||||
|
|
||||||
/* Added a custom blitter to double the height md_ntsc_blit_y2 -- AamirM */
|
/* Modified to work with Genesis Plus GX -- EkeEke*/
|
||||||
/* Added a custom blitter to work with Genesis Plus GX -- EkeEke*/
|
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "md_ntsc.h"
|
#include "md_ntsc.h"
|
||||||
@ -86,12 +85,12 @@ void md_ntsc_init( md_ntsc_t* ntsc, md_ntsc_setup_t const* setup )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MD_NTSC_NO_BLITTERS
|
|
||||||
/* modified blitters to work on a line basis with genesis plus renderer*/
|
|
||||||
void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
|
void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
|
||||||
int in_width, int vline)
|
int in_width, int vline)
|
||||||
{
|
{
|
||||||
int const chunk_count = in_width / md_ntsc_in_chunk - 1;
|
int const chunk_count = in_width / md_ntsc_in_chunk - 1;
|
||||||
|
|
||||||
|
/* use palette entry 0 for unused pixels */
|
||||||
MD_NTSC_IN_T border = table[0];
|
MD_NTSC_IN_T border = table[0];
|
||||||
|
|
||||||
MD_NTSC_BEGIN_ROW( ntsc, border,
|
MD_NTSC_BEGIN_ROW( ntsc, border,
|
||||||
@ -116,24 +115,24 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
|
|||||||
{
|
{
|
||||||
/* order of input and output pixels must not be altered */
|
/* order of input and output pixels must not be altered */
|
||||||
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 0, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 1, *line_out++ );
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 2, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 3, *line_out++ );
|
||||||
|
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
line_out += 12;
|
line_out += 12;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 4, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 5, *line_out++ );
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 6, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 7, *line_out++ );
|
||||||
|
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
line_out += 12;
|
line_out += 12;
|
||||||
@ -142,23 +141,22 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
|
|||||||
|
|
||||||
/* finish final pixels */
|
/* finish final pixels */
|
||||||
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 0, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 1, *line_out++ );
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 1, ntsc, border );
|
MD_NTSC_COLOR_IN( 1, ntsc, border );
|
||||||
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 2, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 3, *line_out++ );
|
||||||
|
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
line_out += 12;
|
line_out += 12;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 2, ntsc, border );
|
MD_NTSC_COLOR_IN( 2, ntsc, border );
|
||||||
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 4, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 5, *line_out++ );
|
||||||
|
|
||||||
MD_NTSC_COLOR_IN( 3, ntsc, border );
|
MD_NTSC_COLOR_IN( 3, ntsc, border );
|
||||||
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 6, *line_out++ );
|
||||||
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
|
MD_NTSC_RGB_OUT( 7, *line_out++ );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -45,10 +45,9 @@ md_ntsc_t object. Can pass NULL for either parameter. */
|
|||||||
typedef struct md_ntsc_t md_ntsc_t;
|
typedef struct md_ntsc_t md_ntsc_t;
|
||||||
void md_ntsc_init( md_ntsc_t* ntsc, md_ntsc_setup_t const* setup );
|
void md_ntsc_init( md_ntsc_t* ntsc, md_ntsc_setup_t const* setup );
|
||||||
|
|
||||||
/* Filters one or more rows of pixels. Input pixel format is set by MD_NTSC_IN_FORMAT
|
/* Filters one row of pixels. Input pixel format is set by MD_NTSC_IN_FORMAT
|
||||||
and output RGB depth is set by MD_NTSC_OUT_DEPTH. Both default to 16-bit RGB.
|
and output RGB depth is defined by MD_NTSC_RGB_OUT_. Both default to 16-bit RGB.
|
||||||
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
In_row_width is the number of pixels to get to the next input row. */
|
||||||
is the number of *bytes* to get to the next output row. */
|
|
||||||
void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
|
void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
|
||||||
int in_width, int vline);
|
int in_width, int vline);
|
||||||
|
|
||||||
@ -70,9 +69,9 @@ enum { md_ntsc_out_chunk = 8 }; /* number of output pixels generated per chunk *
|
|||||||
enum { md_ntsc_black = 0 }; /* palette index for black */
|
enum { md_ntsc_black = 0 }; /* palette index for black */
|
||||||
|
|
||||||
/* Begin outputting row and start three pixels. First pixel will be cut off a bit.
|
/* Begin outputting row and start three pixels. First pixel will be cut off a bit.
|
||||||
Use md_ntsc_black for unused pixels. Declares variables, so must be before first
|
Declares variables, so must be before first statement in a block (unless you're using C++). */
|
||||||
statement in a block (unless you're using C++). */
|
|
||||||
#define MD_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2, pixel3 ) \
|
#define MD_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2, pixel3 ) \
|
||||||
|
md_ntsc_rgb_t raw_;\
|
||||||
unsigned const md_pixel0_ = (pixel0);\
|
unsigned const md_pixel0_ = (pixel0);\
|
||||||
md_ntsc_rgb_t const* kernel0 = MD_NTSC_IN_FORMAT( ntsc, md_pixel0_ );\
|
md_ntsc_rgb_t const* kernel0 = MD_NTSC_IN_FORMAT( ntsc, md_pixel0_ );\
|
||||||
unsigned const md_pixel1_ = (pixel1);\
|
unsigned const md_pixel1_ = (pixel1);\
|
||||||
@ -90,17 +89,13 @@ statement in a block (unless you're using C++). */
|
|||||||
#define MD_NTSC_COLOR_IN( index, ntsc, color ) \
|
#define MD_NTSC_COLOR_IN( index, ntsc, color ) \
|
||||||
MD_NTSC_COLOR_IN_( index, color, MD_NTSC_IN_FORMAT, ntsc )
|
MD_NTSC_COLOR_IN_( index, color, MD_NTSC_IN_FORMAT, ntsc )
|
||||||
|
|
||||||
/* Generate output pixel. Bits can be 24, 16, 15, 32 (treated as 24), or 0:
|
/* Generate output pixel */
|
||||||
24: RRRRRRRR GGGGGGGG BBBBBBBB
|
#define MD_NTSC_RGB_OUT( x, rgb_out ) {\
|
||||||
16: RRRRRGGG GGGBBBBB
|
raw_ =\
|
||||||
15: RRRRRGG GGGBBBBB
|
|
||||||
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
|
||||||
#define MD_NTSC_RGB_OUT( x, rgb_out, bits ) {\
|
|
||||||
md_ntsc_rgb_t raw_ =\
|
|
||||||
kernel0 [x+ 0] + kernel1 [(x+6)%8+16] + kernel2 [(x+4)%8 ] + kernel3 [(x+2)%8+16] +\
|
kernel0 [x+ 0] + kernel1 [(x+6)%8+16] + kernel2 [(x+4)%8 ] + kernel3 [(x+2)%8+16] +\
|
||||||
kernelx0 [x+ 8] + kernelx1 [(x+6)%8+24] + kernelx2 [(x+4)%8+8] + kernelx3 [(x+2)%8+24];\
|
kernelx0 [x+ 8] + kernelx1 [(x+6)%8+24] + kernelx2 [(x+4)%8+8] + kernelx3 [(x+2)%8+24];\
|
||||||
MD_NTSC_CLAMP_( raw_, 0 );\
|
MD_NTSC_CLAMP_( raw_, 0 );\
|
||||||
MD_NTSC_RGB_OUT_( rgb_out, bits, 0 );\
|
MD_NTSC_RGB_OUT_( rgb_out, 0 );\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -118,6 +113,11 @@ struct md_ntsc_t {
|
|||||||
((n << 9 & 0x3800) | (n & 0x0700) | (n >> 8 & 0x00E0)) *\
|
((n << 9 & 0x3800) | (n & 0x0700) | (n >> 8 & 0x00E0)) *\
|
||||||
(md_ntsc_entry_size * sizeof (md_ntsc_rgb_t) / 32))
|
(md_ntsc_entry_size * sizeof (md_ntsc_rgb_t) / 32))
|
||||||
|
|
||||||
|
#define MD_NTSC_RGB15( ntsc, n ) \
|
||||||
|
(md_ntsc_rgb_t*) ((char*) (ntsc)->table +\
|
||||||
|
((n << 8 & 0x1C00) | (n & 0x0380) | (n >> 8 & 0x0070)) *\
|
||||||
|
(md_ntsc_entry_size * sizeof (md_ntsc_rgb_t) / 16))
|
||||||
|
|
||||||
/* common ntsc macros */
|
/* common ntsc macros */
|
||||||
#define md_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
#define md_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
||||||
#define md_ntsc_clamp_mask (md_ntsc_rgb_builder * 3 / 2)
|
#define md_ntsc_clamp_mask (md_ntsc_rgb_builder * 3 / 2)
|
||||||
@ -137,9 +137,15 @@ struct md_ntsc_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* x is always zero except in snes_ntsc library */
|
/* x is always zero except in snes_ntsc library */
|
||||||
#define MD_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
#ifdef USE_15BPP_RENDERING
|
||||||
|
#define MD_NTSC_RGB_OUT_( rgb_out, x ) {\
|
||||||
|
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define MD_NTSC_RGB_OUT_( rgb_out, x ) {\
|
||||||
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,16 @@
|
|||||||
#define MD_NTSC_CONFIG_H
|
#define MD_NTSC_CONFIG_H
|
||||||
|
|
||||||
/* Format of source pixels */
|
/* Format of source pixels */
|
||||||
|
#ifdef USE_15BPP_RENDERING
|
||||||
|
#define MD_NTSC_IN_FORMAT MD_NTSC_RGB15
|
||||||
|
#else
|
||||||
#define MD_NTSC_IN_FORMAT MD_NTSC_RGB16
|
#define MD_NTSC_IN_FORMAT MD_NTSC_RGB16
|
||||||
|
#endif
|
||||||
|
#define MD_NTSC_IN_FORMAT MD_NTSC_RGB16
|
||||||
|
|
||||||
|
/* Original CRAM format */
|
||||||
/* #define MD_NTSC_IN_FORMAT MD_NTSC_BGR9 */
|
/* #define MD_NTSC_IN_FORMAT MD_NTSC_BGR9 */
|
||||||
|
|
||||||
/* The following affect the built-in blitter only; a custom blitter can
|
|
||||||
handle things however it wants. */
|
|
||||||
|
|
||||||
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
|
||||||
#define MD_NTSC_OUT_DEPTH 16
|
|
||||||
|
|
||||||
/* Type of input pixel values */
|
/* Type of input pixel values */
|
||||||
#define MD_NTSC_IN_T unsigned short
|
#define MD_NTSC_IN_T unsigned short
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ details. You should have received a copy of the GNU Lesser General Public
|
|||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
/* Added a custom blitter to work with Genesis Plus GX -- EkeEke*/
|
/* Modified to work with Genesis Plus GX -- EkeEke */
|
||||||
|
|
||||||
sms_ntsc_setup_t const sms_ntsc_monochrome = { 0,-1, 0, 0,.2, 0, .2,-.2,-.2,-1, 0, 0 };
|
sms_ntsc_setup_t const sms_ntsc_monochrome = { 0,-1, 0, 0,.2, 0, .2,-.2,-.2,-1, 0, 0 };
|
||||||
sms_ntsc_setup_t const sms_ntsc_composite = { 0, 0, 0, 0, 0, 0,.25, 0, 0, 0, 0, 0 };
|
sms_ntsc_setup_t const sms_ntsc_composite = { 0, 0, 0, 0, 0, 0,.25, 0, 0, 0, 0, 0 };
|
||||||
@ -84,9 +84,6 @@ void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SMS_NTSC_NO_BLITTERS
|
|
||||||
|
|
||||||
/* modified blitters to work on a line basis with genesis plus renderer*/
|
|
||||||
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
|
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
|
||||||
int in_width, int vline)
|
int in_width, int vline)
|
||||||
{
|
{
|
||||||
@ -97,6 +94,7 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
|
|||||||
unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */
|
unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */
|
||||||
unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2;
|
unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2;
|
||||||
|
|
||||||
|
/* use palette entry 0 for unused pixels */
|
||||||
SMS_NTSC_IN_T border = table[0];
|
SMS_NTSC_IN_T border = table[0];
|
||||||
|
|
||||||
SMS_NTSC_BEGIN_ROW( ntsc, border,
|
SMS_NTSC_BEGIN_ROW( ntsc, border,
|
||||||
@ -122,76 +120,75 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
|
|||||||
/* order of input and output pixels must not be altered */
|
/* order of input and output pixels must not be altered */
|
||||||
SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 0, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 0, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 1, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 1, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 0, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 1, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 2, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 2, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 3, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 3, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 2, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 3, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 4, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 4, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 5, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 5, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 6, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 6, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 4, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 5, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 6, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 6, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finish final pixels */
|
/* finish final pixels */
|
||||||
SMS_NTSC_COLOR_IN( 0, ntsc, border );
|
SMS_NTSC_COLOR_IN( 0, ntsc, border );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 0, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 0, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 1, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 1, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 0, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 1, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SMS_NTSC_COLOR_IN( 1, ntsc, border );
|
SMS_NTSC_COLOR_IN( 1, ntsc, border );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 2, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 2, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 3, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 3, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 2, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 3, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SMS_NTSC_COLOR_IN( 2, ntsc, border );
|
SMS_NTSC_COLOR_IN( 2, ntsc, border );
|
||||||
#ifdef NGC
|
#ifdef NGC
|
||||||
SMS_NTSC_RGB_OUT( 4, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 4, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 5, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 5, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
SMS_NTSC_RGB_OUT( 6, line_out[offset++], SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 6, line_out[offset++] );
|
||||||
if ((offset % 4) == 0) offset += 12;
|
if ((offset % 4) == 0) offset += 12;
|
||||||
#else
|
#else
|
||||||
SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 4, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 5, *line_out++ );
|
||||||
SMS_NTSC_RGB_OUT( 6, *line_out++, SMS_NTSC_OUT_DEPTH );
|
SMS_NTSC_RGB_OUT( 6, *line_out++ );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -45,10 +45,9 @@ sms_ntsc_t object. Can pass NULL for either parameter. */
|
|||||||
typedef struct sms_ntsc_t sms_ntsc_t;
|
typedef struct sms_ntsc_t sms_ntsc_t;
|
||||||
void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup );
|
void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup );
|
||||||
|
|
||||||
/* Filters one or more rows of pixels. Input pixel format is set by SMS_NTSC_IN_FORMAT
|
/* Filters one row of pixels. Input pixel format is set by SMS_NTSC_IN_FORMAT
|
||||||
and output RGB depth is set by SMS_NTSC_OUT_DEPTH. Both default to 16-bit RGB.
|
and output RGB depth is defined by SMS_NTSC_RGB_OUT_. Both default to 16-bit RGB.
|
||||||
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
In_row_width is the number of pixels to get to the next input row. */
|
||||||
is the number of *bytes* to get to the next output row. */
|
|
||||||
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
|
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
|
||||||
int in_width, int vline);
|
int in_width, int vline);
|
||||||
|
|
||||||
@ -67,11 +66,9 @@ value. */
|
|||||||
|
|
||||||
enum { sms_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
enum { sms_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
||||||
enum { sms_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
enum { sms_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
||||||
enum { sms_ntsc_black = 0 }; /* palette index for black */
|
|
||||||
|
|
||||||
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
||||||
Use sms_ntsc_black for unused pixels. Declares variables, so must be before first
|
Declares variables, so must be before first statement in a block (unless you're using C++). */
|
||||||
statement in a block (unless you're using C++). */
|
|
||||||
#define SMS_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2 ) \
|
#define SMS_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2 ) \
|
||||||
SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SMS_NTSC_IN_FORMAT, ntsc )
|
SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SMS_NTSC_IN_FORMAT, ntsc )
|
||||||
|
|
||||||
@ -79,14 +76,14 @@ statement in a block (unless you're using C++). */
|
|||||||
#define SMS_NTSC_COLOR_IN( in_index, ntsc, color_in ) \
|
#define SMS_NTSC_COLOR_IN( in_index, ntsc, color_in ) \
|
||||||
SMS_NTSC_COLOR_IN_( in_index, color_in, SMS_NTSC_IN_FORMAT, ntsc )
|
SMS_NTSC_COLOR_IN_( in_index, color_in, SMS_NTSC_IN_FORMAT, ntsc )
|
||||||
|
|
||||||
/* Generates output pixel. Bits can be 24, 16, 15, 32 (treated as 24), or 0:
|
/* Generates output pixel */
|
||||||
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
|
#define SMS_NTSC_RGB_OUT( x, rgb_out ) {\
|
||||||
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
|
raw_ =\
|
||||||
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
|
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
||||||
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
||||||
#define SMS_NTSC_RGB_OUT( index, rgb_out, bits ) \
|
SMS_NTSC_CLAMP_( raw_, 0 );\
|
||||||
SMS_NTSC_RGB_OUT_14_( index, rgb_out, bits, 0 )
|
SMS_NTSC_RGB_OUT_( rgb_out, 0 );\
|
||||||
|
}
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
enum { sms_ntsc_entry_size = 3 * 14 };
|
enum { sms_ntsc_entry_size = 3 * 14 };
|
||||||
@ -109,6 +106,7 @@ struct sms_ntsc_t {
|
|||||||
|
|
||||||
/* common 3->7 ntsc macros */
|
/* common 3->7 ntsc macros */
|
||||||
#define SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
#define SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
||||||
|
sms_ntsc_rgb_t raw_;\
|
||||||
unsigned const sms_ntsc_pixel0_ = (pixel0);\
|
unsigned const sms_ntsc_pixel0_ = (pixel0);\
|
||||||
sms_ntsc_rgb_t const* kernel0 = ENTRY( table, sms_ntsc_pixel0_ );\
|
sms_ntsc_rgb_t const* kernel0 = ENTRY( table, sms_ntsc_pixel0_ );\
|
||||||
unsigned const sms_ntsc_pixel1_ = (pixel1);\
|
unsigned const sms_ntsc_pixel1_ = (pixel1);\
|
||||||
@ -119,13 +117,6 @@ struct sms_ntsc_t {
|
|||||||
sms_ntsc_rgb_t const* kernelx1 = kernel0;\
|
sms_ntsc_rgb_t const* kernelx1 = kernel0;\
|
||||||
sms_ntsc_rgb_t const* kernelx2 = kernel0
|
sms_ntsc_rgb_t const* kernelx2 = kernel0
|
||||||
|
|
||||||
#define SMS_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
|
|
||||||
sms_ntsc_rgb_t raw_ =\
|
|
||||||
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
|
||||||
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
|
||||||
SMS_NTSC_CLAMP_( raw_, shift );\
|
|
||||||
SMS_NTSC_RGB_OUT_( rgb_out, bits, shift );\
|
|
||||||
}
|
|
||||||
|
|
||||||
/* common ntsc macros */
|
/* common ntsc macros */
|
||||||
#define sms_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
#define sms_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
||||||
@ -146,9 +137,15 @@ struct sms_ntsc_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* x is always zero except in snes_ntsc library */
|
/* x is always zero except in snes_ntsc library */
|
||||||
#define SMS_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
#ifdef USE_15BPP_RENDERING
|
||||||
|
#define SMS_NTSC_RGB_OUT_( rgb_out, x ) {\
|
||||||
|
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define SMS_NTSC_RGB_OUT_( rgb_out, x) {\
|
||||||
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,18 @@
|
|||||||
#define SMS_NTSC_CONFIG_H
|
#define SMS_NTSC_CONFIG_H
|
||||||
|
|
||||||
/* Format of source pixels */
|
/* Format of source pixels */
|
||||||
|
#ifdef USE_15BPP_RENDERING
|
||||||
|
#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB15
|
||||||
|
#else
|
||||||
#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB16
|
#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB16
|
||||||
/* #define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB15 */
|
#endif
|
||||||
|
|
||||||
|
/* Original CRAM format */
|
||||||
/* #define SMS_NTSC_IN_FORMAT SMS_NTSC_BGR12 */
|
/* #define SMS_NTSC_IN_FORMAT SMS_NTSC_BGR12 */
|
||||||
|
|
||||||
/* The following affect the built-in blitter only; a custom blitter can
|
/* The following affect the built-in blitter only; a custom blitter can
|
||||||
handle things however it wants. */
|
handle things however it wants. */
|
||||||
|
|
||||||
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
|
||||||
#define SMS_NTSC_OUT_DEPTH 16
|
|
||||||
|
|
||||||
/* Type of input pixel values */
|
/* Type of input pixel values */
|
||||||
#define SMS_NTSC_IN_T unsigned short
|
#define SMS_NTSC_IN_T unsigned short
|
||||||
|
|
||||||
|
@ -4128,8 +4128,8 @@ void remap_line(int line)
|
|||||||
line = (line * 2) + odd_frame;
|
line = (line * 2) + odd_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NTSC Filter (only supported for 16-bit pixels rendering) */
|
/* NTSC Filter (only supported for 15 or 16-bit pixels rendering) */
|
||||||
#ifdef USE_16BPP_RENDERING
|
#if defined(USE_15BPP_RENDERING) || defined(USE_16BPP_RENDERING)
|
||||||
if (config.ntsc)
|
if (config.ntsc)
|
||||||
{
|
{
|
||||||
if (reg[12] & 0x01)
|
if (reg[12] & 0x01)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user