1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef NTSC_FILTER_HXX |
19 | #define NTSC_FILTER_HXX |
20 | |
21 | class TIASurface; |
22 | class Settings; |
23 | |
24 | #include "bspf.hxx" |
25 | #include "AtariNTSC.hxx" |
26 | |
27 | /** |
28 | This class is based on the Blargg NTSC filter code from Atari800, |
29 | and is derived from 'filter_ntsc.(h|c)'. Original code based on |
30 | implementation from http://www.slack.net/~ant. |
31 | |
32 | The class is basically a thin wrapper around the AtariNTSC class. |
33 | */ |
34 | class NTSCFilter |
35 | { |
36 | public: |
37 | NTSCFilter(); |
38 | |
39 | public: |
40 | // Set one of the available preset adjustments (Composite, S-Video, RGB, etc) |
41 | enum class Preset { |
42 | OFF, |
43 | RGB, |
44 | SVIDEO, |
45 | COMPOSITE, |
46 | BAD, |
47 | CUSTOM |
48 | }; |
49 | |
50 | /* Normally used in conjunction with custom mode, contains all |
51 | aspects currently adjustable in NTSC TV emulation. */ |
52 | struct Adjustable { |
53 | uInt32 hue, saturation, contrast, brightness, gamma, |
54 | sharpness, resolution, artifacts, fringing, bleed; |
55 | }; |
56 | |
57 | public: |
58 | /* Informs the NTSC filter about the current TIA palette. The filter |
59 | uses this as a baseline for calculating its own internal palette |
60 | in YIQ format. |
61 | */ |
62 | inline void setTIAPalette(const uInt32* palette) { |
63 | uInt8* ptr = myTIAPalette; |
64 | |
65 | // Set palette for normal fill |
66 | for(uInt32 i = 0; i < AtariNTSC::palette_size; ++i) |
67 | { |
68 | *ptr++ = (palette[i] >> 16) & 0xff; |
69 | *ptr++ = (palette[i] >> 8) & 0xff; |
70 | *ptr++ = palette[i] & 0xff; |
71 | } |
72 | myNTSC.initializePalette(myTIAPalette); |
73 | } |
74 | |
75 | inline void setPhosphorPalette(uInt8 palette[256][256]) { |
76 | myNTSC.setPhosphorPalette(palette); |
77 | } |
78 | |
79 | // The following are meant to be used strictly for toggling from the GUI |
80 | string setPreset(Preset preset); |
81 | |
82 | // Get current preset info encoded as a string |
83 | string getPreset() const; |
84 | |
85 | // Get adjustables for the given preset |
86 | // Values will be scaled to 0 - 100 range, independent of how |
87 | // they're actually stored internally |
88 | void getAdjustables(Adjustable& adjustable, Preset preset) const; |
89 | |
90 | // Set custom adjustables to given values |
91 | // Values will be scaled to 0 - 100 range, independent of how |
92 | // they're actually stored internally |
93 | void setCustomAdjustables(Adjustable& adjustable); |
94 | |
95 | // The following methods cycle through each custom adjustable |
96 | // They are used in conjunction with the increase/decrease |
97 | // methods, which change the currently selected adjustable |
98 | // Changes are made this way since otherwise 20 key-combinations |
99 | // would be needed to dynamically change each setting, and now |
100 | // only 4 combinations are necessary |
101 | string setNextAdjustable(); |
102 | string setPreviousAdjustable(); |
103 | string increaseAdjustable(); |
104 | string decreaseAdjustable(); |
105 | |
106 | // Load and save NTSC-related settings |
107 | void loadConfig(const Settings& settings); |
108 | void saveConfig(Settings& settings) const; |
109 | |
110 | // Perform Blargg filtering on input buffer, place results in |
111 | // output buffer |
112 | inline void render(uInt8* src_buf, uInt32 src_width, uInt32 src_height, |
113 | uInt32* dest_buf, uInt32 dest_pitch) |
114 | { |
115 | myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch); |
116 | } |
117 | inline void render(uInt8* src_buf, uInt32 src_width, uInt32 src_height, |
118 | uInt32* dest_buf, uInt32 dest_pitch, uInt32* prev_buf) |
119 | { |
120 | myNTSC.render(src_buf, src_width, src_height, dest_buf, dest_pitch, prev_buf); |
121 | } |
122 | |
123 | // Enable threading for the NTSC rendering |
124 | inline void enableThreading(bool enable) |
125 | { |
126 | myNTSC.enableThreading(enable); |
127 | } |
128 | |
129 | private: |
130 | // Convert from atari_ntsc_setup_t values to equivalent adjustables |
131 | void convertToAdjustable(Adjustable& adjustable, |
132 | const AtariNTSC::Setup& setup) const; |
133 | |
134 | private: |
135 | // The NTSC object |
136 | AtariNTSC myNTSC; |
137 | |
138 | // Contains controls used to adjust the palette in the NTSC filter |
139 | // This is the main setup object used by the underlying ntsc code |
140 | AtariNTSC::Setup mySetup; |
141 | |
142 | // This setup is used only in custom mode (after it is modified, |
143 | // it is copied to mySetup) |
144 | static AtariNTSC::Setup myCustomSetup; |
145 | |
146 | // Current preset in use |
147 | Preset myPreset; |
148 | |
149 | // The base 2600 palette contains 128 normal colours |
150 | // and 128 black&white colours (PAL colour loss) |
151 | // Each colour is represented by 3 bytes, in R,G,B order |
152 | uInt8 myTIAPalette[AtariNTSC::palette_size * 3]; |
153 | |
154 | struct AdjustableTag { |
155 | const char* const type; |
156 | float* value; |
157 | }; |
158 | uInt32 myCurrentAdjustable; |
159 | static const AdjustableTag ourCustomAdjustables[10]; |
160 | |
161 | private: |
162 | // Following constructors and assignment operators not supported |
163 | NTSCFilter(const NTSCFilter&) = delete; |
164 | NTSCFilter(NTSCFilter&&) = delete; |
165 | NTSCFilter& operator=(const NTSCFilter&) = delete; |
166 | NTSCFilter& operator=(NTSCFilter&&) = delete; |
167 | }; |
168 | |
169 | #endif |
170 | |