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 CONSOLE_HXX |
19 | #define CONSOLE_HXX |
20 | |
21 | class Event; |
22 | class Switches; |
23 | class System; |
24 | class TIA; |
25 | class M6502; |
26 | class M6532; |
27 | class Cartridge; |
28 | class CompuMate; |
29 | class Debugger; |
30 | class AudioQueue; |
31 | class AudioSettings; |
32 | |
33 | #include "bspf.hxx" |
34 | #include "ConsoleIO.hxx" |
35 | #include "Control.hxx" |
36 | #include "Props.hxx" |
37 | #include "TIAConstants.hxx" |
38 | #include "FrameBuffer.hxx" |
39 | #include "Serializable.hxx" |
40 | #include "EventHandlerConstants.hxx" |
41 | #include "NTSCFilter.hxx" |
42 | #include "EmulationTiming.hxx" |
43 | #include "ConsoleTiming.hxx" |
44 | #include "frame-manager/AbstractFrameManager.hxx" |
45 | |
46 | /** |
47 | Contains detailed info about a console. |
48 | */ |
49 | struct ConsoleInfo |
50 | { |
51 | string BankSwitch; |
52 | string CartName; |
53 | string CartMD5; |
54 | string Control0; |
55 | string Control1; |
56 | string DisplayFormat; |
57 | }; |
58 | |
59 | /** |
60 | This class represents the entire game console. |
61 | |
62 | @author Bradford W. Mott |
63 | */ |
64 | class Console : public Serializable, public ConsoleIO |
65 | { |
66 | public: |
67 | /** |
68 | Create a new console for emulating the specified game using the |
69 | given game image and operating system. |
70 | |
71 | @param osystem The OSystem object to use |
72 | @param cart The cartridge to use with this console |
73 | @param props The properties for the cartridge |
74 | */ |
75 | Console(OSystem& osystem, unique_ptr<Cartridge>& cart, |
76 | const Properties& props, AudioSettings& audioSettings); |
77 | |
78 | /** |
79 | Destructor |
80 | */ |
81 | virtual ~Console(); |
82 | |
83 | public: |
84 | |
85 | /** |
86 | Sets the left and right controllers for the console. |
87 | */ |
88 | void setControllers(const string& roMd5); |
89 | |
90 | /** |
91 | Get the controller plugged into the specified jack |
92 | |
93 | @return The specified controller |
94 | */ |
95 | Controller& leftController() const override { return *myLeftControl; } |
96 | Controller& rightController() const override { return *myRightControl; } |
97 | |
98 | /** |
99 | Get the TIA for this console |
100 | |
101 | @return The TIA |
102 | */ |
103 | TIA& tia() const { return *myTIA; } |
104 | |
105 | /** |
106 | Get the properties being used by the game |
107 | |
108 | @return The properties being used by the game |
109 | */ |
110 | const Properties& properties() const { return myProperties; } |
111 | |
112 | /** |
113 | Get the console switches |
114 | |
115 | @return The console switches |
116 | */ |
117 | Switches& switches() const override { return *mySwitches; } |
118 | |
119 | /** |
120 | Get the 6502 based system used by the console to emulate the game |
121 | |
122 | @return The 6502 based system |
123 | */ |
124 | System& system() const { return *mySystem; } |
125 | |
126 | /** |
127 | Get the cartridge used by the console which contains the ROM code |
128 | |
129 | @return The cartridge for this console |
130 | */ |
131 | Cartridge& cartridge() const { return *myCart; } |
132 | |
133 | /** |
134 | Get the 6532 used by the console |
135 | |
136 | @return The 6532 for this console |
137 | */ |
138 | M6532& riot() const { return *myRiot; } |
139 | |
140 | /** |
141 | Saves the current state of this console class to the given Serializer. |
142 | |
143 | @param out The serializer device to save to. |
144 | @return The result of the save. True on success, false on failure. |
145 | */ |
146 | bool save(Serializer& out) const override; |
147 | |
148 | /** |
149 | Loads the current state of this console class from the given Serializer. |
150 | |
151 | @param in The Serializer device to load from. |
152 | @return The result of the load. True on success, false on failure. |
153 | */ |
154 | bool load(Serializer& in) override; |
155 | |
156 | /** |
157 | Set the properties to those given |
158 | |
159 | @param props The properties to use for the current game |
160 | */ |
161 | void setProperties(const Properties& props); |
162 | |
163 | /** |
164 | Query detailed information about this console. |
165 | */ |
166 | const ConsoleInfo& about() const { return myConsoleInfo; } |
167 | |
168 | /** |
169 | Timing information for this console. |
170 | */ |
171 | ConsoleTiming timing() const { return myConsoleTiming; } |
172 | |
173 | /** |
174 | Set up the console to use the debugger. |
175 | */ |
176 | void attachDebugger(Debugger& dbg); |
177 | |
178 | /** |
179 | Informs the Console of a change in EventHandler state. |
180 | */ |
181 | void stateChanged(EventHandlerState state); |
182 | |
183 | /** |
184 | Retrieve emulation timing provider. |
185 | */ |
186 | EmulationTiming& emulationTiming() { return myEmulationTiming; } |
187 | |
188 | public: |
189 | /** |
190 | Toggle between NTSC/PAL/SECAM (and variants) display format. |
191 | |
192 | @param direction +1 indicates increase, -1 indicates decrease. |
193 | */ |
194 | void toggleFormat(int direction = 1); |
195 | |
196 | /** |
197 | Set NTSC/PAL/SECAM (and variants) display format. |
198 | */ |
199 | void setFormat(uInt32 format); |
200 | |
201 | /** |
202 | Get NTSC/PAL/SECAM (and variants) display format name |
203 | */ |
204 | string getFormatString() const { return myDisplayFormat; } |
205 | |
206 | /** |
207 | Toggle between the available palettes. |
208 | */ |
209 | void togglePalette(); |
210 | |
211 | /** |
212 | Sets the palette according to the given palette name. |
213 | |
214 | @param palette The palette to switch to. |
215 | */ |
216 | void setPalette(const string& palette); |
217 | |
218 | /** |
219 | Toggles phosphor effect. |
220 | */ |
221 | void togglePhosphor(); |
222 | |
223 | /** |
224 | Change the "Display.PPBlend" variable. |
225 | |
226 | @param direction +1 indicates increase, -1 indicates decrease. |
227 | */ |
228 | void changePhosphor(int direction); |
229 | |
230 | /** |
231 | Toggles the PAL color-loss effect. |
232 | */ |
233 | void toggleColorLoss(); |
234 | void enableColorLoss(bool state); |
235 | |
236 | /** |
237 | Initialize the video subsystem wrt this class. |
238 | This is required for changing window size, title, etc. |
239 | |
240 | @param full Whether we want a full initialization, |
241 | or only reset certain attributes. |
242 | |
243 | @return The results from FrameBuffer::initialize() |
244 | */ |
245 | FBInitStatus initializeVideo(bool full = true); |
246 | |
247 | /** |
248 | Initialize the audio subsystem wrt this class. |
249 | This is required any time the sound settings change. |
250 | */ |
251 | void initializeAudio(); |
252 | |
253 | /** |
254 | "Fry" the Atari (mangle memory/TIA contents) |
255 | */ |
256 | void fry() const; |
257 | |
258 | /** |
259 | Change the "Display.YStart" variable. |
260 | |
261 | @param direction +1 indicates increase, -1 indicates decrease. |
262 | */ |
263 | void changeYStart(int direction); |
264 | |
265 | /** |
266 | Returns the current framerate. |
267 | */ |
268 | float getFramerate() const; |
269 | |
270 | /** |
271 | Toggles the TIA bit specified in the method name. |
272 | */ |
273 | void toggleP0Bit() const { toggleTIABit(P0Bit, "P0" ); } |
274 | void toggleP1Bit() const { toggleTIABit(P1Bit, "P1" ); } |
275 | void toggleM0Bit() const { toggleTIABit(M0Bit, "M0" ); } |
276 | void toggleM1Bit() const { toggleTIABit(M1Bit, "M1" ); } |
277 | void toggleBLBit() const { toggleTIABit(BLBit, "BL" ); } |
278 | void togglePFBit() const { toggleTIABit(PFBit, "PF" ); } |
279 | void toggleBits() const; |
280 | |
281 | /** |
282 | Toggles the TIA collisions specified in the method name. |
283 | */ |
284 | void toggleP0Collision() const { toggleTIACollision(P0Bit, "P0" ); } |
285 | void toggleP1Collision() const { toggleTIACollision(P1Bit, "P1" ); } |
286 | void toggleM0Collision() const { toggleTIACollision(M0Bit, "M0" ); } |
287 | void toggleM1Collision() const { toggleTIACollision(M1Bit, "M1" ); } |
288 | void toggleBLCollision() const { toggleTIACollision(BLBit, "BL" ); } |
289 | void togglePFCollision() const { toggleTIACollision(PFBit, "PF" ); } |
290 | void toggleCollisions() const; |
291 | |
292 | /** |
293 | Toggles the TIA 'fixed debug colors' mode. |
294 | */ |
295 | void toggleFixedColors() const; |
296 | |
297 | /** |
298 | Toggles the TIA 'scanline jitter' mode. |
299 | */ |
300 | void toggleJitter() const; |
301 | |
302 | /** |
303 | * Update yatart and run autodetection if necessary. |
304 | */ |
305 | void updateYStart(uInt32 ystart); |
306 | |
307 | private: |
308 | /** |
309 | * Dry-run the emulation and detect the frame layout (PAL / NTSC). |
310 | */ |
311 | void autodetectFrameLayout(bool reset = true); |
312 | |
313 | /** |
314 | * Dryrun the emulation and detect ystart (the first visible scanline). |
315 | */ |
316 | void autodetectYStart(bool reset = true); |
317 | |
318 | /** |
319 | * Rerun frame layout autodetection |
320 | */ |
321 | void redetectFrameLayout(); |
322 | |
323 | /** |
324 | * Rerun ystart autodetection. |
325 | */ |
326 | void redetectYStart(); |
327 | |
328 | /** |
329 | Sets various properties of the TIA (YStart, Height, etc) based on |
330 | the current display format. |
331 | */ |
332 | void setTIAProperties(); |
333 | |
334 | /** |
335 | Create the audio queue |
336 | */ |
337 | void createAudioQueue(); |
338 | |
339 | /** |
340 | Selects the left or right controller depending on ROM properties |
341 | */ |
342 | unique_ptr<Controller> getControllerPort(const Controller::Type type, |
343 | const Controller::Jack port, const string& romMd5); |
344 | |
345 | /** |
346 | Loads a user-defined palette file (from OSystem::paletteFile), filling the |
347 | appropriate user-defined palette arrays. |
348 | */ |
349 | void loadUserPalette(); |
350 | |
351 | /** |
352 | Loads all defined palettes with PAL color-loss data, even those that |
353 | normally can't have it enabled (NTSC), since it's also used for |
354 | 'greying out' the frame in the debugger. |
355 | */ |
356 | void generateColorLossPalette(); |
357 | |
358 | void toggleTIABit(TIABit bit, const string& bitname, bool show = true) const; |
359 | void toggleTIACollision(TIABit bit, const string& bitname, bool show = true) const; |
360 | |
361 | private: |
362 | // Reference to the osystem object |
363 | OSystem& myOSystem; |
364 | |
365 | // Reference to the event object to use |
366 | const Event& myEvent; |
367 | |
368 | // Properties for the game |
369 | Properties myProperties; |
370 | |
371 | // Pointer to the 6502 based system being emulated |
372 | unique_ptr<System> mySystem; |
373 | |
374 | // Pointer to the M6502 CPU |
375 | unique_ptr<M6502> my6502; |
376 | |
377 | // Pointer to the 6532 (aka RIOT) (the debugger needs it) |
378 | // A RIOT of my own! (...with apologies to The Clash...) |
379 | unique_ptr<M6532> myRiot; |
380 | |
381 | // Pointer to the TIA object |
382 | unique_ptr<TIA> myTIA; |
383 | |
384 | // The frame manager instance that is used during emulation |
385 | unique_ptr<AbstractFrameManager> myFrameManager; |
386 | |
387 | // The audio fragment queue that connects TIA and audio driver |
388 | shared_ptr<AudioQueue> myAudioQueue; |
389 | |
390 | // Pointer to the Cartridge (the debugger needs it) |
391 | unique_ptr<Cartridge> myCart; |
392 | |
393 | // Pointer to the switches on the front of the console |
394 | unique_ptr<Switches> mySwitches; |
395 | |
396 | // Pointers to the left and right controllers |
397 | unique_ptr<Controller> myLeftControl, myRightControl; |
398 | |
399 | // Pointer to CompuMate handler (only used in CompuMate ROMs) |
400 | shared_ptr<CompuMate> myCMHandler; |
401 | |
402 | // The currently defined display format (NTSC/PAL/SECAM) |
403 | string myDisplayFormat; |
404 | |
405 | // Display format currently in use |
406 | uInt32 myCurrentFormat; |
407 | |
408 | // Autodetected ystart. |
409 | uInt32 myAutodetectedYstart; |
410 | |
411 | // Is ystart currently autodetected? |
412 | bool myYStartAutodetected; |
413 | |
414 | // Is the TV format autodetected? |
415 | bool myFormatAutodetected; |
416 | |
417 | // Indicates whether an external palette was found and |
418 | // successfully loaded |
419 | bool myUserPaletteDefined; |
420 | |
421 | // Contains detailed info about this console |
422 | ConsoleInfo myConsoleInfo; |
423 | |
424 | // Contains timing information for this console |
425 | ConsoleTiming myConsoleTiming; |
426 | |
427 | // Emulation timing provider. This ties together the timing of the core emulation loop |
428 | // and the parameters that govern audio synthesis |
429 | EmulationTiming myEmulationTiming; |
430 | |
431 | // The audio settings |
432 | AudioSettings& myAudioSettings; |
433 | |
434 | // Table of RGB values for NTSC, PAL and SECAM |
435 | static uInt32 ourNTSCPalette[256]; |
436 | static uInt32 ourPALPalette[256]; |
437 | static uInt32 ourSECAMPalette[256]; |
438 | |
439 | // Table of RGB values for NTSC, PAL and SECAM - Z26 version |
440 | static uInt32 ourNTSCPaletteZ26[256]; |
441 | static uInt32 ourPALPaletteZ26[256]; |
442 | static uInt32 ourSECAMPaletteZ26[256]; |
443 | |
444 | // Table of RGB values for NTSC, PAL and SECAM - user-defined |
445 | static uInt32 ourUserNTSCPalette[256]; |
446 | static uInt32 ourUserPALPalette[256]; |
447 | static uInt32 ourUserSECAMPalette[256]; |
448 | |
449 | private: |
450 | // Following constructors and assignment operators not supported |
451 | Console() = delete; |
452 | Console(const Console&) = delete; |
453 | Console(Console&&) = delete; |
454 | Console& operator=(const Console&) = delete; |
455 | Console& operator=(Console&&) = delete; |
456 | }; |
457 | |
458 | #endif |
459 | |