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
21class Event;
22class Switches;
23class System;
24class TIA;
25class M6502;
26class M6532;
27class Cartridge;
28class CompuMate;
29class Debugger;
30class AudioQueue;
31class 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*/
49struct 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*/
64class 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