Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx32/core/ntsc/sms_ntsc.h
2 views
1
/* Sega Master System/Game Gear/TI 99/4A NTSC video filter */
2
3
/* sms_ntsc 0.2.3 */
4
#ifndef SMS_NTSC_H
5
#define SMS_NTSC_H
6
7
#include "sms_ntsc_config.h"
8
9
#ifdef __cplusplus
10
extern "C" {
11
#endif
12
13
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
14
in parenthesis and should remain fairly stable in future versions. */
15
typedef struct sms_ntsc_setup_t
16
{
17
/* Basic parameters */
18
double hue; /* -1 = -180 degrees +1 = +180 degrees */
19
double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */
20
double contrast; /* -1 = dark (0.5) +1 = light (1.5) */
21
double brightness; /* -1 = dark (0.5) +1 = light (1.5) */
22
double sharpness; /* edge contrast enhancement/blurring */
23
24
/* Advanced parameters */
25
double gamma; /* -1 = dark (1.5) +1 = light (0.5) */
26
double resolution; /* image resolution */
27
double artifacts; /* artifacts caused by color changes */
28
double fringing; /* color artifacts caused by brightness changes */
29
double bleed; /* color bleed (color resolution reduction) */
30
float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */
31
32
unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */
33
} sms_ntsc_setup_t;
34
35
/* Video format presets */
36
extern sms_ntsc_setup_t const sms_ntsc_composite; /* color bleeding + artifacts */
37
extern sms_ntsc_setup_t const sms_ntsc_svideo; /* color bleeding only */
38
extern sms_ntsc_setup_t const sms_ntsc_rgb; /* crisp image */
39
extern sms_ntsc_setup_t const sms_ntsc_monochrome;/* desaturated + artifacts */
40
41
enum { sms_ntsc_palette_size = 4096 };
42
43
/* Initializes and adjusts parameters. Can be called multiple times on the same
44
sms_ntsc_t object. Can pass NULL for either parameter. */
45
typedef struct sms_ntsc_t sms_ntsc_t;
46
void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup );
47
48
/* Filters one row of pixels. Input pixel format is set by SMS_NTSC_IN_FORMAT
49
and output RGB depth is set by SMS_NTSC_OUT_DEPTH. Both default to 16-bit RGB.
50
In_row_width is the number of pixels to get to the next input row. */
51
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
52
int in_width, int vline);
53
54
/* Number of output pixels written by blitter for given input width. */
55
#define SMS_NTSC_OUT_WIDTH( in_width ) \
56
(((in_width) / sms_ntsc_in_chunk + 1) * sms_ntsc_out_chunk)
57
58
/* Number of input pixels that will fit within given output width. Might be
59
rounded down slightly; use SMS_NTSC_OUT_WIDTH() on result to find rounded
60
value. */
61
#define SMS_NTSC_IN_WIDTH( out_width ) \
62
(((out_width) / sms_ntsc_out_chunk - 1) * sms_ntsc_in_chunk + 2)
63
64
65
/* Interface for user-defined custom blitters */
66
67
enum { sms_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
68
enum { sms_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
69
70
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
71
Declares variables, so must be before first statement in a block (unless you're using C++). */
72
#define SMS_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2 ) \
73
SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SMS_NTSC_IN_FORMAT, ntsc )
74
75
/* Begins input pixel */
76
#define SMS_NTSC_COLOR_IN( in_index, ntsc, color_in ) \
77
SMS_NTSC_COLOR_IN_( in_index, color_in, SMS_NTSC_IN_FORMAT, ntsc )
78
79
/* Generates output pixel */
80
#define SMS_NTSC_RGB_OUT( x, rgb_out ) {\
81
raw_ =\
82
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
83
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
84
SMS_NTSC_CLAMP_( raw_, 0 );\
85
SMS_NTSC_RGB_OUT_( rgb_out, 0 );\
86
}
87
88
/* private */
89
enum { sms_ntsc_entry_size = 3 * 14 };
90
typedef unsigned long sms_ntsc_rgb_t;
91
struct sms_ntsc_t {
92
sms_ntsc_rgb_t table [sms_ntsc_palette_size] [sms_ntsc_entry_size];
93
};
94
95
#define SMS_NTSC_BGR12( ntsc, n ) (ntsc)->table [n & 0xFFF]
96
97
#define SMS_NTSC_RGB16( ntsc, n ) \
98
(sms_ntsc_rgb_t const*) ((char const*) (ntsc)->table +\
99
((n << 10 & 0x7800) | (n & 0x0780) | (n >> 9 & 0x0078)) *\
100
(sms_ntsc_entry_size * sizeof (sms_ntsc_rgb_t) / 8))
101
102
#define SMS_NTSC_RGB15( ntsc, n ) \
103
(sms_ntsc_rgb_t const*) ((char const*) (ntsc)->table +\
104
((n << 9 & 0x3C00) | (n & 0x03C0) | (n >> 9 & 0x003C)) *\
105
(sms_ntsc_entry_size * sizeof (sms_ntsc_rgb_t) / 4))
106
107
/* common 3->7 ntsc macros */
108
#define SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
109
sms_ntsc_rgb_t raw_;\
110
unsigned const sms_ntsc_pixel0_ = (pixel0);\
111
sms_ntsc_rgb_t const* kernel0 = ENTRY( table, sms_ntsc_pixel0_ );\
112
unsigned const sms_ntsc_pixel1_ = (pixel1);\
113
sms_ntsc_rgb_t const* kernel1 = ENTRY( table, sms_ntsc_pixel1_ );\
114
unsigned const sms_ntsc_pixel2_ = (pixel2);\
115
sms_ntsc_rgb_t const* kernel2 = ENTRY( table, sms_ntsc_pixel2_ );\
116
sms_ntsc_rgb_t const* kernelx0;\
117
sms_ntsc_rgb_t const* kernelx1 = kernel0;\
118
sms_ntsc_rgb_t const* kernelx2 = kernel0
119
120
121
/* common ntsc macros */
122
#define sms_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
123
#define sms_ntsc_clamp_mask (sms_ntsc_rgb_builder * 3 / 2)
124
#define sms_ntsc_clamp_add (sms_ntsc_rgb_builder * 0x101)
125
#define SMS_NTSC_CLAMP_( io, shift ) {\
126
sms_ntsc_rgb_t sub = (io) >> (9-(shift)) & sms_ntsc_clamp_mask;\
127
sms_ntsc_rgb_t clamp = sms_ntsc_clamp_add - sub;\
128
io |= clamp;\
129
clamp -= sub;\
130
io &= clamp;\
131
}
132
133
#define SMS_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\
134
unsigned color_;\
135
kernelx##index = kernel##index;\
136
kernel##index = (color_ = (color), ENTRY( table, color_ ));\
137
}
138
139
/* x is always zero except in snes_ntsc library */
140
#if SMS_NTSC_OUT_DEPTH == 15
141
#define SMS_NTSC_RGB_OUT_( rgb_out, x ) {\
142
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
143
}
144
#elif SMS_NTSC_OUT_DEPTH == 16
145
#define SMS_NTSC_RGB_OUT_( rgb_out, x) {\
146
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
147
}
148
#endif
149
150
#ifdef __cplusplus
151
}
152
#endif
153
154
#endif
155
156