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-2021 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 #include "Console.hxx"
19 #include "EventHandler.hxx"
20 #include "M6502.hxx"
21 #include "OSystem.hxx"
22 #include "RewindManager.hxx"
23 #include "Settings.hxx"
24 #include "StateManager.hxx"
25 #include "TIA.hxx"
26 
27 #include "DevSettingsHandler.hxx"
28 
29 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DevSettingsHandler(OSystem & osystem)30 DevSettingsHandler::DevSettingsHandler(OSystem& osystem)
31   : myOSystem(osystem)
32 {
33 }
34 
35 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
loadSettings(SettingsSet set)36 void DevSettingsHandler::loadSettings(SettingsSet set)
37 {
38   bool devSettings = set == SettingsSet::developer;
39   const string& prefix = devSettings ? "dev." : "plr.";
40   const Settings& settings = myOSystem.settings();
41 
42   myFrameStats[set] = settings.getBool(prefix + "stats");
43   myDetectedInfo[set] = settings.getBool(prefix + "detectedinfo");
44   myConsole[set] = settings.getString(prefix + "console") == "7800" ? 1 : 0;
45   // Randomization
46   myRandomBank[set] = settings.getBool(prefix + "bankrandom");
47   myRandomizeTIA[set] = settings.getBool(prefix + "tiarandom");
48   myRandomizeRAM[set] = settings.getBool(prefix + "ramrandom");
49   myRandomizeCPU[set] = settings.getString(prefix + "cpurandom");
50   // Undriven TIA pins
51   myUndrivenPins[set] = devSettings ? settings.getBool("dev.tiadriven") : false;
52 #ifdef DEBUGGER_SUPPORT
53   // Read from write ports break
54   myRWPortBreak[set] = devSettings ? settings.getBool("dev.rwportbreak") : false;
55   // Write to read ports break
56   myWRPortBreak[set] = devSettings ? settings.getBool("dev.wrportbreak") : false;
57 #endif
58   // Thumb ARM emulation exception
59   myThumbException[set] = devSettings ? settings.getBool("dev.thumb.trapfatal") : false;
60   // AtariVox/SaveKey/PlusROM access
61   myExternAccess[set] = settings.getBool(prefix + "extaccess");
62 
63   // TIA tab
64   myTIAType[set] = devSettings ? settings.getString("dev.tia.type") : "standard";
65   myPlInvPhase[set] = devSettings ? settings.getBool("dev.tia.plinvphase") : false;
66   myMsInvPhase[set] = devSettings ? settings.getBool("dev.tia.msinvphase") : false;
67   myBlInvPhase[set] = devSettings ? settings.getBool("dev.tia.blinvphase") : false;
68   myPFBits[set] = devSettings ? settings.getBool("dev.tia.delaypfbits") : false;
69   myPFColor[set] = devSettings ? settings.getBool("dev.tia.delaypfcolor") : false;
70   myBKColor[set] = devSettings ? settings.getBool("dev.tia.delaybkcolor") : false;
71   myPlSwap[set] = devSettings ? settings.getBool("dev.tia.delayplswap") : false;
72   myBlSwap[set] = devSettings ? settings.getBool("dev.tia.delayblswap") : false;
73 
74   // Debug colors
75   myDebugColors[set] = settings.getBool(prefix + "debugcolors");
76   // PAL color-loss effect
77   myColorLoss[set] = settings.getBool(prefix + "colorloss");
78   // Jitter
79   myTVJitter[set] = settings.getBool(prefix + "tv.jitter");
80   myTVJitterRec[set] = settings.getInt(prefix + "tv.jitter_recovery");
81 
82   // States
83   myTimeMachine[set] = settings.getBool(prefix + "timemachine");
84   myStateSize[set] = settings.getInt(prefix + "tm.size");
85   myUncompressed[set] = settings.getInt(prefix + "tm.uncompressed");
86   myStateInterval[set] = settings.getString(prefix + "tm.interval");
87   myStateHorizon[set] = settings.getString(prefix + "tm.horizon");
88 }
89 
90 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
saveSettings(SettingsSet set)91 void DevSettingsHandler::saveSettings(SettingsSet set)
92 {
93   bool devSettings = set == SettingsSet::developer;
94   const string& prefix = devSettings ? "dev." : "plr.";
95   Settings& settings = myOSystem.settings();
96 
97   settings.setValue(prefix + "stats", myFrameStats[set]);
98   settings.setValue(prefix + "detectedinfo", myDetectedInfo[set]);
99   settings.setValue(prefix + "console", myConsole[set] == 1 ? "7800" : "2600");
100   if(myOSystem.hasConsole())
101     myOSystem.eventHandler().set7800Mode();
102 
103   // Randomization
104   settings.setValue(prefix + "bankrandom", myRandomBank[set]);
105   settings.setValue(prefix + "tiarandom", myRandomizeTIA[set]);
106   settings.setValue(prefix + "ramrandom", myRandomizeRAM[set]);
107   settings.setValue(prefix + "cpurandom", myRandomizeCPU[set]);
108 
109   if(devSettings)
110   {
111     // Undriven TIA pins
112     settings.setValue("dev.tiadriven", myUndrivenPins[set]);
113   #ifdef DEBUGGER_SUPPORT
114     // Read from write ports break
115     settings.setValue("dev.rwportbreak", myRWPortBreak[set]);
116     // Write to read ports break
117     settings.setValue("dev.wrportbreak", myWRPortBreak[set]);
118   #endif
119     // Thumb ARM emulation exception
120     settings.setValue("dev.thumb.trapfatal", myThumbException[set]);
121   }
122 
123   // AtariVox/SaveKey/PlusROM access
124   settings.setValue(prefix + "extaccess", myExternAccess[set]);
125 
126   // TIA tab
127   if(devSettings)
128   {
129     settings.setValue("dev.tia.type", myTIAType[set]);
130     if(BSPF::equalsIgnoreCase("custom", myTIAType[set]))
131     {
132       settings.setValue("dev.tia.plinvphase", myPlInvPhase[set]);
133       settings.setValue("dev.tia.msinvphase", myMsInvPhase[set]);
134       settings.setValue("dev.tia.blinvphase", myBlInvPhase[set]);
135       settings.setValue("dev.tia.delaypfbits", myPFBits[set]);
136       settings.setValue("dev.tia.delaypfcolor", myPFColor[set]);
137       settings.setValue("dev.tia.delaybkcolor", myBKColor[set]);
138       settings.setValue("dev.tia.delayplswap", myPlSwap[set]);
139       settings.setValue("dev.tia.delayblswap", myBlSwap[set]);
140     }
141   }
142 
143   // Debug colors
144   settings.setValue(prefix + "debugcolors", myDebugColors[set]);
145   // PAL color loss
146   settings.setValue(prefix + "colorloss", myColorLoss[set]);
147   // Jitter
148   settings.setValue(prefix + "tv.jitter", myTVJitter[set]);
149   settings.setValue(prefix + "tv.jitter_recovery", myTVJitterRec[set]);
150 
151   // States
152   settings.setValue(prefix + "timemachine", myTimeMachine[set]);
153   settings.setValue(prefix + "tm.size", myStateSize[set]);
154   settings.setValue(prefix + "tm.uncompressed", myUncompressed[set]);
155   settings.setValue(prefix + "tm.interval", myStateInterval[set]);
156   settings.setValue(prefix + "tm.horizon", myStateHorizon[set]);
157 }
158 
159 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
applySettings(SettingsSet set)160 void DevSettingsHandler::applySettings(SettingsSet set)
161 {
162   // *** Emulation tab ***
163   myOSystem.frameBuffer().showFrameStats(myFrameStats[set]);
164 
165   if(myOSystem.hasConsole())
166   {
167     myOSystem.console().tia().driveUnusedPinsRandom(myUndrivenPins[set]);
168     // Notes:
169     // - thumb exceptions not updated, because set in cart constructor
170     // - other missing settings are used on-the-fly
171   }
172 
173 #ifdef DEBUGGER_SUPPORT
174   // Read from write ports and write to read ports breaks
175   if(myOSystem.hasConsole())
176   {
177     myOSystem.console().system().m6502().setReadFromWritePortBreak(myRWPortBreak[set]);
178     myOSystem.console().system().m6502().setWriteToReadPortBreak(myWRPortBreak[set]);
179   }
180 #endif
181 
182   // *** TIA tab ***
183   if(myOSystem.hasConsole())
184   {
185     myOSystem.console().tia().setPlInvertedPhaseClock(myPlInvPhase[set]);
186     myOSystem.console().tia().setMsInvertedPhaseClock(myMsInvPhase[set]);
187     myOSystem.console().tia().setBlInvertedPhaseClock(myBlInvPhase[set]);
188     myOSystem.console().tia().setPFBitsDelay(myPFBits[set]);
189     myOSystem.console().tia().setPFColorDelay(myPFColor[set]);
190     myOSystem.console().tia().setBKColorDelay(myBKColor[set]);
191     myOSystem.console().tia().setPlSwapDelay(myPlSwap[set]);
192     myOSystem.console().tia().setBlSwapDelay(myBlSwap[set]);
193   }
194 
195   // *** Video tab ***
196   if(myOSystem.hasConsole())
197   {
198     // TV Jitter
199     myOSystem.console().tia().toggleJitter(myTVJitter[set] ? 1 : 0);
200     myOSystem.console().tia().setJitterRecoveryFactor(myTVJitterRec[set]);
201     // PAL color loss
202     myOSystem.console().enableColorLoss(myColorLoss[set]);
203   }
204 
205   // Debug colours
206   handleEnableDebugColors(myDebugColors[set]);
207 
208   // *** Time Machine tab ***
209   // update RewindManager
210   myOSystem.state().rewindManager().setup();
211   myOSystem.state().setRewindMode(myTimeMachine[set] ?
212     StateManager::Mode::TimeMachine : StateManager::Mode::Off);
213 }
214 
215 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
handleEnableDebugColors(bool enable)216 void DevSettingsHandler::handleEnableDebugColors(bool enable)
217 {
218   if(myOSystem.hasConsole())
219   {
220     bool fixed = myOSystem.console().tia().usingFixedColors();
221     if(fixed != enable)
222       myOSystem.console().tia().toggleFixedColors();
223   }
224 }
225