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 | #include "bspf.hxx" |
19 | #include "OSystem.hxx" |
20 | #include "Joystick.hxx" |
21 | #include "Paddles.hxx" |
22 | #include "PointingDevice.hxx" |
23 | #include "SaveKey.hxx" |
24 | #include "AtariVox.hxx" |
25 | #include "Settings.hxx" |
26 | #include "EditTextWidget.hxx" |
27 | #include "PopUpWidget.hxx" |
28 | #include "RadioButtonWidget.hxx" |
29 | #include "ColorWidget.hxx" |
30 | #include "TabWidget.hxx" |
31 | #include "Widget.hxx" |
32 | #include "Font.hxx" |
33 | #include "Console.hxx" |
34 | #include "TIA.hxx" |
35 | #include "OSystem.hxx" |
36 | #include "EventHandler.hxx" |
37 | #include "StateManager.hxx" |
38 | #include "RewindManager.hxx" |
39 | #include "M6502.hxx" |
40 | #ifdef DEBUGGER_SUPPORT |
41 | #include "Debugger.hxx" |
42 | #include "CartDebug.hxx" |
43 | #include "DebuggerDialog.hxx" |
44 | #endif |
45 | #include "DeveloperDialog.hxx" |
46 | |
47 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
48 | DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent, |
49 | const GUI::Font& font, int max_w, int max_h) |
50 | : Dialog(osystem, parent, font, "Developer settings" ) |
51 | { |
52 | const int VGAP = 4; |
53 | const int lineHeight = font.getLineHeight(), |
54 | fontWidth = font.getMaxCharWidth(), |
55 | buttonHeight = font.getLineHeight() + 4; |
56 | int xpos, ypos; |
57 | |
58 | // Set real dimensions |
59 | setSize(54 * fontWidth + 10, 16 * (lineHeight + VGAP) + 14 + _th, max_w, max_h); |
60 | |
61 | // The tab widget |
62 | xpos = 2; ypos = 4; |
63 | myTab = new TabWidget(this, font, xpos, ypos + _th, _w - 2 * xpos, _h - _th - buttonHeight - 16 - ypos); |
64 | addTabWidget(myTab); |
65 | |
66 | addEmulationTab(font); |
67 | addTiaTab(font); |
68 | addVideoTab(font); |
69 | addTimeMachineTab(font); |
70 | addDebuggerTab(font); |
71 | |
72 | WidgetArray wid; |
73 | addDefaultsOKCancelBGroup(wid, font); |
74 | addBGroupToFocusList(wid); |
75 | |
76 | // Activate the first tab |
77 | myTab->setActiveTab(0); |
78 | } |
79 | |
80 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
81 | void DeveloperDialog::addEmulationTab(const GUI::Font& font) |
82 | { |
83 | const int HBORDER = 10; |
84 | const int INDENT = 16+4; |
85 | const int VBORDER = 8; |
86 | const int VGAP = 4; |
87 | int ypos = VBORDER; |
88 | int lineHeight = font.getLineHeight(); |
89 | WidgetArray wid; |
90 | VariantList items; |
91 | int tabID = myTab->addTab(" Emulation " , TabWidget::AUTO_WIDTH); |
92 | |
93 | // settings set |
94 | mySettingsGroupEmulation = new RadioButtonGroup(); |
95 | RadioButtonWidget* r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
96 | "Player settings" , mySettingsGroupEmulation, kPlrSettings); |
97 | wid.push_back(r); |
98 | ypos += lineHeight + VGAP; |
99 | r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
100 | "Developer settings" , mySettingsGroupEmulation, kDevSettings); |
101 | wid.push_back(r); |
102 | ypos += lineHeight + VGAP * 1; |
103 | |
104 | myFrameStatsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Console info overlay" ); |
105 | wid.push_back(myFrameStatsWidget); |
106 | ypos += lineHeight + VGAP; |
107 | |
108 | // 2600/7800 mode |
109 | items.clear(); |
110 | VarList::push_back(items, "Atari 2600" , "2600" ); |
111 | VarList::push_back(items, "Atari 7800" , "7800" ); |
112 | int lwidth = font.getStringWidth("Console " ); |
113 | int pwidth = font.getStringWidth("Atari 2600" ); |
114 | |
115 | myConsoleWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 1, ypos, pwidth, lineHeight, items, |
116 | "Console " , lwidth, kConsole); |
117 | wid.push_back(myConsoleWidget); |
118 | ypos += lineHeight + VGAP; |
119 | |
120 | // Randomize items |
121 | myLoadingROMLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT*1, ypos + 1, "When loading a ROM:" ); |
122 | wid.push_back(myLoadingROMLabel); |
123 | ypos += lineHeight + VGAP; |
124 | |
125 | myRandomBankWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, |
126 | "Random startup bank" ); |
127 | wid.push_back(myRandomBankWidget); |
128 | ypos += lineHeight + VGAP; |
129 | |
130 | // Randomize RAM |
131 | myRandomizeRAMWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, |
132 | "Randomize zero-page and extended RAM" , kRandRAMID); |
133 | wid.push_back(myRandomizeRAMWidget); |
134 | ypos += lineHeight + VGAP; |
135 | |
136 | // Randomize CPU |
137 | myRandomizeCPULabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Randomize CPU " ); |
138 | wid.push_back(myRandomizeCPULabel); |
139 | |
140 | int xpos = myRandomizeCPULabel->getRight() + 10; |
141 | const char* const cpuregs[] = { "SP" , "A" , "X" , "Y" , "PS" }; |
142 | for(int i = 0; i < 5; ++i) |
143 | { |
144 | myRandomizeCPUWidget[i] = new CheckboxWidget(myTab, font, xpos, ypos + 1, |
145 | cpuregs[i], kRandCPUID); |
146 | wid.push_back(myRandomizeCPUWidget[i]); |
147 | xpos += CheckboxWidget::boxSize() + font.getStringWidth("XX" ) + 20; |
148 | } |
149 | ypos += lineHeight + VGAP; |
150 | |
151 | // How to handle undriven TIA pins |
152 | myUndrivenPinsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
153 | "Drive unused TIA pins randomly on a read/peek" ); |
154 | wid.push_back(myUndrivenPinsWidget); |
155 | ypos += lineHeight + VGAP; |
156 | |
157 | #ifdef DEBUGGER_SUPPORT |
158 | myRWPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
159 | "Break on reads from write ports" ); |
160 | wid.push_back(myRWPortBreakWidget); |
161 | ypos += lineHeight + VGAP; |
162 | |
163 | myWRPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
164 | "Break on writes to read ports" ); |
165 | wid.push_back(myWRPortBreakWidget); |
166 | ypos += lineHeight + VGAP; |
167 | #endif |
168 | |
169 | // Thumb ARM emulation exception |
170 | myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
171 | "Fatal ARM emulation error throws exception" ); |
172 | wid.push_back(myThumbExceptionWidget); |
173 | ypos += lineHeight + VGAP; |
174 | |
175 | // AtariVox/SaveKey EEPROM access |
176 | myEEPROMAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
177 | "Display AtariVox/SaveKey EEPROM R/W access" ); |
178 | wid.push_back(myEEPROMAccessWidget); |
179 | |
180 | // Add items for tab 0 |
181 | addToFocusList(wid, myTab, tabID); |
182 | } |
183 | |
184 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
185 | void DeveloperDialog::addTiaTab(const GUI::Font& font) |
186 | { |
187 | const int HBORDER = 10; |
188 | const int INDENT = 16 + 4; |
189 | const int VBORDER = 8; |
190 | const int VGAP = 4; |
191 | int ypos = VBORDER; |
192 | int lineHeight = font.getLineHeight(); |
193 | int pwidth = font.getStringWidth("Faulty Cosmic Ark stars" ); |
194 | WidgetArray wid; |
195 | VariantList items; |
196 | int tabID = myTab->addTab(" TIA " , TabWidget::AUTO_WIDTH); |
197 | |
198 | wid.clear(); |
199 | |
200 | // settings set |
201 | mySettingsGroupTia = new RadioButtonGroup(); |
202 | RadioButtonWidget* r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
203 | "Player settings" , mySettingsGroupTia, kPlrSettings); |
204 | wid.push_back(r); |
205 | ypos += lineHeight + VGAP; |
206 | r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
207 | "Developer settings" , mySettingsGroupTia, kDevSettings); |
208 | wid.push_back(r); |
209 | ypos += lineHeight + VGAP * 1; |
210 | |
211 | items.clear(); |
212 | VarList::push_back(items, "Standard" , "standard" ); |
213 | VarList::push_back(items, "Faulty Kool-Aid Man" , "koolaidman" ); |
214 | VarList::push_back(items, "Faulty Cosmic Ark stars" , "cosmicark" ); |
215 | VarList::push_back(items, "Glitched Pesco" , "pesco" ); |
216 | VarList::push_back(items, "Glitched Quick Step!" , "quickstep" ); |
217 | VarList::push_back(items, "Glitched He-Man title" , "heman" ); |
218 | VarList::push_back(items, "Custom" , "custom" ); |
219 | myTIATypeWidget = new PopUpWidget(myTab, font, HBORDER + INDENT, ypos - 1, |
220 | pwidth, lineHeight, items, "Chip type " , 0, kTIAType); |
221 | wid.push_back(myTIATypeWidget); |
222 | ypos += lineHeight + VGAP * 1; |
223 | |
224 | myInvPhaseLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, |
225 | "Inverted HMOVE clock phase for" ); |
226 | wid.push_back(myInvPhaseLabel); |
227 | ypos += lineHeight + VGAP * 1; |
228 | |
229 | myPlInvPhaseWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, |
230 | "Players" ); |
231 | wid.push_back(myPlInvPhaseWidget); |
232 | |
233 | myMsInvPhaseWidget = new CheckboxWidget(myTab, font, myPlInvPhaseWidget->getRight() + 20, ypos + 1, |
234 | "Missiles" ); |
235 | wid.push_back(myMsInvPhaseWidget); |
236 | |
237 | myBlInvPhaseWidget = new CheckboxWidget(myTab, font, myMsInvPhaseWidget->getRight() + 20, ypos + 1, |
238 | "Ball" ); |
239 | wid.push_back(myBlInvPhaseWidget); |
240 | ypos += lineHeight + VGAP * 1; |
241 | |
242 | myPlayfieldLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, |
243 | "Delayed playfield" ); |
244 | wid.push_back(myPlayfieldLabel); |
245 | ypos += lineHeight + VGAP * 1; |
246 | |
247 | myPFBitsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, "Bits" ); |
248 | wid.push_back(myPFBitsWidget); |
249 | //ypos += lineHeight + VGAP * 1; |
250 | |
251 | myPFColorWidget = new CheckboxWidget(myTab, font, myPFBitsWidget->getRight() + 20, ypos + 1, "Color" ); |
252 | wid.push_back(myPFColorWidget); |
253 | ypos += lineHeight + VGAP * 1; |
254 | |
255 | mySwapLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, |
256 | "Delayed VDEL" + ELLIPSIS + " swap for" ); |
257 | wid.push_back(mySwapLabel); |
258 | ypos += lineHeight + VGAP * 1; |
259 | |
260 | myPlSwapWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, "Players" ); |
261 | wid.push_back(myPlSwapWidget); |
262 | |
263 | myBlSwapWidget = new CheckboxWidget(myTab, font, myPlSwapWidget->getRight() + 20, ypos + 1, "Ball" ); |
264 | wid.push_back(myBlSwapWidget); |
265 | |
266 | // Add items for tab 2 |
267 | addToFocusList(wid, myTab, tabID); |
268 | } |
269 | |
270 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
271 | void DeveloperDialog::addVideoTab(const GUI::Font& font) |
272 | { |
273 | const int HBORDER = 10; |
274 | const int INDENT = 16 + 4; |
275 | const int VBORDER = 8; |
276 | const int VGAP = 4; |
277 | int ypos = VBORDER; |
278 | int lineHeight = font.getLineHeight(); |
279 | int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); |
280 | int lwidth = font.getStringWidth("Intensity " ); |
281 | int pwidth = font.getMaxCharWidth() * 6; |
282 | WidgetArray wid; |
283 | VariantList items; |
284 | int tabID = myTab->addTab(" Video " , TabWidget::AUTO_WIDTH); |
285 | |
286 | wid.clear(); |
287 | |
288 | // settings set |
289 | mySettingsGroupVideo = new RadioButtonGroup(); |
290 | RadioButtonWidget* r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
291 | "Player settings" , mySettingsGroupVideo, kPlrSettings); |
292 | wid.push_back(r); |
293 | ypos += lineHeight + VGAP; |
294 | r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
295 | "Developer settings" , mySettingsGroupVideo, kDevSettings); |
296 | wid.push_back(r); |
297 | ypos += lineHeight + VGAP * 1; |
298 | |
299 | // TV jitter effect |
300 | myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
301 | "Jitter/roll effect" , kTVJitter); |
302 | wid.push_back(myTVJitterWidget); |
303 | myTVJitterRecWidget = new SliderWidget(myTab, font, |
304 | myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1, |
305 | "Recovery " , 0, kTVJitterChanged); |
306 | myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20); |
307 | myTVJitterRecWidget->setTickmarkIntervals(5); |
308 | wid.push_back(myTVJitterRecWidget); |
309 | myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font, |
310 | myTVJitterRecWidget->getRight() + 4, |
311 | myTVJitterRecWidget->getTop() + 2, |
312 | 5 * fontWidth, fontHeight, "" ); |
313 | ypos += lineHeight + VGAP; |
314 | |
315 | myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
316 | "PAL color-loss" ); |
317 | wid.push_back(myColorLossWidget); |
318 | ypos += lineHeight + VGAP; |
319 | |
320 | // debug colors |
321 | myDebugColorsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, |
322 | "Debug colors (*)" ); |
323 | wid.push_back(myDebugColorsWidget); |
324 | ypos += lineHeight + VGAP + 2; |
325 | |
326 | items.clear(); |
327 | VarList::push_back(items, "Red" , "r" ); |
328 | VarList::push_back(items, "Orange" , "o" ); |
329 | VarList::push_back(items, "Yellow" , "y" ); |
330 | VarList::push_back(items, "Green" , "g" ); |
331 | VarList::push_back(items, "Purple" , "p" ); |
332 | VarList::push_back(items, "Blue" , "b" ); |
333 | |
334 | static constexpr int dbg_cmds[DEBUG_COLORS] = { |
335 | kP0ColourChangedCmd, kM0ColourChangedCmd, kP1ColourChangedCmd, |
336 | kM1ColourChangedCmd, kPFColourChangedCmd, kBLColourChangedCmd |
337 | }; |
338 | |
339 | auto createDebugColourWidgets = [&](int idx, const string& desc) |
340 | { |
341 | int x = HBORDER + INDENT * 1; |
342 | myDbgColour[idx] = new PopUpWidget(myTab, font, x, ypos - 1, |
343 | pwidth, lineHeight, items, desc, lwidth, dbg_cmds[idx]); |
344 | wid.push_back(myDbgColour[idx]); |
345 | x += myDbgColour[idx]->getWidth() + 10; |
346 | myDbgColourSwatch[idx] = new ColorWidget(myTab, font, x, ypos - 1, |
347 | uInt32(2 * lineHeight), lineHeight); |
348 | ypos += lineHeight + VGAP * 1; |
349 | }; |
350 | |
351 | createDebugColourWidgets(0, "Player 0 " ); |
352 | createDebugColourWidgets(1, "Missile 0 " ); |
353 | createDebugColourWidgets(2, "Player 1 " ); |
354 | createDebugColourWidgets(3, "Missile 1 " ); |
355 | createDebugColourWidgets(4, "Playfield " ); |
356 | createDebugColourWidgets(5, "Ball " ); |
357 | |
358 | // Add message concerning usage |
359 | const GUI::Font& infofont = instance().frameBuffer().infoFont(); |
360 | ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; |
361 | new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Colors identical for player and developer settings" ); |
362 | |
363 | // Add items for tab 2 |
364 | addToFocusList(wid, myTab, tabID); |
365 | } |
366 | |
367 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
368 | void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) |
369 | { |
370 | const string INTERVALS[NUM_INTERVALS] = { |
371 | " 1 frame" , |
372 | " 3 frames" , |
373 | "10 frames" , |
374 | "30 frames" , |
375 | " 1 second" , |
376 | " 3 seconds" , |
377 | "10 seconds" |
378 | }; |
379 | const string INT_SETTINGS[NUM_INTERVALS] = { |
380 | "1f" , |
381 | "3f" , |
382 | "10f" , |
383 | "30f" , |
384 | "1s" , |
385 | "3s" , |
386 | "10s" |
387 | }; |
388 | const string HORIZONS[NUM_HORIZONS] = { |
389 | " 3 seconds" , |
390 | "10 seconds" , |
391 | "30 seconds" , |
392 | " 1 minute" , |
393 | " 3 minutes" , |
394 | "10 minutes" , |
395 | "30 minutes" , |
396 | "60 minutes" |
397 | }; |
398 | const string HOR_SETTINGS[NUM_HORIZONS] = { |
399 | "3s" , |
400 | "10s" , |
401 | "30s" , |
402 | "1m" , |
403 | "3m" , |
404 | "10m" , |
405 | "30m" , |
406 | "60m" |
407 | }; |
408 | const int HBORDER = 10; |
409 | const int INDENT = 16+4; |
410 | const int VBORDER = 8; |
411 | const int VGAP = 4; |
412 | int ypos = VBORDER; |
413 | int lineHeight = font.getLineHeight(), |
414 | fontHeight = font.getFontHeight(), |
415 | fontWidth = font.getMaxCharWidth(), |
416 | lwidth = fontWidth * 11; |
417 | WidgetArray wid; |
418 | VariantList items; |
419 | int tabID = myTab->addTab(" Time Machine " , TabWidget::AUTO_WIDTH); |
420 | |
421 | // settings set |
422 | mySettingsGroupTM = new RadioButtonGroup(); |
423 | RadioButtonWidget* r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
424 | "Player settings" , mySettingsGroupTM, kPlrSettings); |
425 | wid.push_back(r); |
426 | ypos += lineHeight + VGAP; |
427 | r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, |
428 | "Developer settings" , mySettingsGroupTM, kDevSettings); |
429 | wid.push_back(r); |
430 | ypos += lineHeight + VGAP * 1; |
431 | |
432 | myTimeMachineWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT, ypos + 1, |
433 | "Time Machine" , kTimeMachine); |
434 | wid.push_back(myTimeMachineWidget); |
435 | ypos += lineHeight + VGAP; |
436 | |
437 | int swidth = fontWidth * 12 + 5; // width of PopUpWidgets below |
438 | myStateSizeWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight, |
439 | "Buffer size (*) " , 0, kSizeChanged, lwidth, " states" ); |
440 | myStateSizeWidget->setMinValue(20); |
441 | #ifdef RETRON77 |
442 | myStateSizeWidget->setMaxValue(100); |
443 | #else |
444 | myStateSizeWidget->setMaxValue(1000); |
445 | #endif |
446 | myStateSizeWidget->setStepValue(20); |
447 | myStateSizeWidget->setTickmarkIntervals(5); |
448 | wid.push_back(myStateSizeWidget); |
449 | ypos += lineHeight + VGAP; |
450 | |
451 | myUncompressedWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight, |
452 | "Uncompressed size " , 0, kUncompressedChanged, lwidth, " states" ); |
453 | myUncompressedWidget->setMinValue(0); |
454 | #ifdef RETRON77 |
455 | myUncompressedWidget->setMaxValue(100); |
456 | #else |
457 | myUncompressedWidget->setMaxValue(1000); |
458 | #endif |
459 | myUncompressedWidget->setStepValue(20); |
460 | myUncompressedWidget->setTickmarkIntervals(5); |
461 | wid.push_back(myUncompressedWidget); |
462 | ypos += lineHeight + VGAP; |
463 | |
464 | items.clear(); |
465 | for(int i = 0; i < NUM_INTERVALS; ++i) |
466 | VarList::push_back(items, INTERVALS[i], INT_SETTINGS[i]); |
467 | int pwidth = font.getStringWidth("10 seconds" ); |
468 | myStateIntervalWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth, |
469 | lineHeight, items, "Interval " , 0, kIntervalChanged); |
470 | wid.push_back(myStateIntervalWidget); |
471 | ypos += lineHeight + VGAP; |
472 | |
473 | items.clear(); |
474 | for(int i = 0; i < NUM_HORIZONS; ++i) |
475 | VarList::push_back(items, HORIZONS[i], HOR_SETTINGS[i]); |
476 | myStateHorizonWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth, |
477 | lineHeight, items, "Horizon ~ " , 0, kHorizonChanged); |
478 | wid.push_back(myStateHorizonWidget); |
479 | |
480 | ypos += lineHeight + VGAP * 2; |
481 | new StaticTextWidget(myTab, font, HBORDER, ypos + 1, |
482 | "When exiting emulation:" ); |
483 | ypos += lineHeight + VGAP; |
484 | mySaveOnExitGroup = new RadioButtonGroup(); |
485 | r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, |
486 | "Save nothing" , mySaveOnExitGroup); |
487 | wid.push_back(r); |
488 | ypos += lineHeight + VGAP; |
489 | r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, |
490 | "Save current state in current slot" , mySaveOnExitGroup); |
491 | wid.push_back(r); |
492 | ypos += lineHeight + VGAP; |
493 | r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, |
494 | "Save all states" , mySaveOnExitGroup); |
495 | wid.push_back(r); |
496 | ypos += lineHeight + VGAP; |
497 | |
498 | // Add message concerning usage |
499 | const GUI::Font& infofont = instance().frameBuffer().infoFont(); |
500 | ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; |
501 | new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Any size change clears the buffer" ); |
502 | |
503 | addToFocusList(wid, myTab, tabID); |
504 | } |
505 | |
506 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
507 | void DeveloperDialog::addDebuggerTab(const GUI::Font& font) |
508 | { |
509 | int tabID = myTab->addTab(" Debugger " , TabWidget::AUTO_WIDTH); |
510 | WidgetArray wid; |
511 | |
512 | #ifdef DEBUGGER_SUPPORT |
513 | const int HBORDER = 10; |
514 | const int VBORDER = 8; |
515 | const int VGAP = 4; |
516 | |
517 | VariantList items; |
518 | int fontWidth = font.getMaxCharWidth(), |
519 | fontHeight = font.getFontHeight(), |
520 | lineHeight = font.getLineHeight(); |
521 | int xpos, ypos, pwidth; |
522 | const Common::Size& ds = instance().frameBuffer().desktopSize(); |
523 | |
524 | xpos = HBORDER; |
525 | ypos = VBORDER; |
526 | |
527 | // font size |
528 | items.clear(); |
529 | VarList::push_back(items, "Small" , "small" ); |
530 | VarList::push_back(items, "Medium" , "medium" ); |
531 | VarList::push_back(items, "Large" , "large" ); |
532 | pwidth = font.getStringWidth("Medium" ); |
533 | myDebuggerFontSize = |
534 | new PopUpWidget(myTab, font, HBORDER, ypos + 1, pwidth, lineHeight, items, |
535 | "Font size (*) " , 0, kDFontSizeChanged); |
536 | wid.push_back(myDebuggerFontSize); |
537 | ypos += lineHeight + 4; |
538 | |
539 | // Font style (bold label vs. text, etc) |
540 | items.clear(); |
541 | VarList::push_back(items, "All normal font" , "0" ); |
542 | VarList::push_back(items, "Bold labels only" , "1" ); |
543 | VarList::push_back(items, "Bold non-labels only" , "2" ); |
544 | VarList::push_back(items, "All bold font" , "3" ); |
545 | pwidth = font.getStringWidth("Bold non-labels only" ); |
546 | myDebuggerFontStyle = |
547 | new PopUpWidget(myTab, font, HBORDER, ypos + 1, pwidth, lineHeight, items, |
548 | "Font style (*) " , 0); |
549 | wid.push_back(myDebuggerFontStyle); |
550 | |
551 | ypos += lineHeight + VGAP * 4; |
552 | |
553 | // Debugger width and height |
554 | myDebuggerWidthSlider = new SliderWidget(myTab, font, xpos, ypos-1, "Debugger width (*) " , |
555 | 0, 0, 6 * fontWidth, "px" ); |
556 | myDebuggerWidthSlider->setMinValue(DebuggerDialog::kSmallFontMinW); |
557 | myDebuggerWidthSlider->setMaxValue(ds.w); |
558 | myDebuggerWidthSlider->setStepValue(10); |
559 | // one tickmark every ~100 pixel |
560 | myDebuggerWidthSlider->setTickmarkIntervals((ds.w - DebuggerDialog::kSmallFontMinW + 50) / 100); |
561 | wid.push_back(myDebuggerWidthSlider); |
562 | ypos += lineHeight + VGAP; |
563 | |
564 | myDebuggerHeightSlider = new SliderWidget(myTab, font, xpos, ypos-1, "Debugger height (*) " , |
565 | 0, 0, 6 * fontWidth, "px" ); |
566 | myDebuggerHeightSlider->setMinValue(DebuggerDialog::kSmallFontMinH); |
567 | myDebuggerHeightSlider->setMaxValue(ds.h); |
568 | myDebuggerHeightSlider->setStepValue(10); |
569 | // one tickmark every ~100 pixel |
570 | myDebuggerHeightSlider->setTickmarkIntervals((ds.h - DebuggerDialog::kSmallFontMinH + 50) / 100); |
571 | wid.push_back(myDebuggerHeightSlider); |
572 | ypos += lineHeight + VGAP * 4; |
573 | |
574 | myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1, |
575 | "Trap on 'ghost' reads" ); |
576 | wid.push_back(myGhostReadsTrapWidget); |
577 | |
578 | // Add message concerning usage |
579 | const GUI::Font& infofont = instance().frameBuffer().infoFont(); |
580 | ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; |
581 | new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Changes require a ROM reload" ); |
582 | |
583 | // Debugger is only realistically available in windowed modes 800x600 or greater |
584 | // (and when it's actually been compiled into the app) |
585 | bool debuggerAvailable = |
586 | #if defined(DEBUGGER_SUPPORT) && defined(WINDOWED_SUPPORT) |
587 | (ds.w >= 800 && ds.h >= 600); // TODO - maybe this logic can disappear? |
588 | #else |
589 | false; |
590 | #endif |
591 | if(!debuggerAvailable) |
592 | { |
593 | myDebuggerWidthSlider->clearFlags(Widget::FLAG_ENABLED); |
594 | myDebuggerHeightSlider->clearFlags(Widget::FLAG_ENABLED); |
595 | } |
596 | #else |
597 | new StaticTextWidget(myTab, font, 0, 20, _w - 20, font.getFontHeight(), |
598 | "Debugger support not included" , TextAlign::Center); |
599 | #endif |
600 | |
601 | addToFocusList(wid, myTab, tabID); |
602 | } |
603 | |
604 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
605 | void DeveloperDialog::loadSettings(SettingsSet set) |
606 | { |
607 | bool devSettings = set == SettingsSet::developer; |
608 | const string& prefix = devSettings ? "dev." : "plr." ; |
609 | |
610 | myFrameStats[set] = instance().settings().getBool(prefix + "stats" ); |
611 | myConsole[set] = instance().settings().getString(prefix + "console" ) == "7800" ? 1 : 0; |
612 | // Randomization |
613 | myRandomBank[set] = instance().settings().getBool(prefix + "bankrandom" ); |
614 | myRandomizeRAM[set] = instance().settings().getBool(prefix + "ramrandom" ); |
615 | myRandomizeCPU[set] = instance().settings().getString(prefix + "cpurandom" ); |
616 | // Undriven TIA pins |
617 | myUndrivenPins[set] = devSettings ? instance().settings().getBool("dev.tiadriven" ) : false; |
618 | #ifdef DEBUGGER_SUPPORT |
619 | // Read from write ports break |
620 | myRWPortBreak[set] = devSettings ? instance().settings().getBool("dev.rwportbreak" ) : false; |
621 | // Write to read ports break |
622 | myWRPortBreak[set] = devSettings ? instance().settings().getBool("dev.wrportbreak" ) : false; |
623 | #endif |
624 | // Thumb ARM emulation exception |
625 | myThumbException[set] = devSettings ? instance().settings().getBool("dev.thumb.trapfatal" ) : false; |
626 | // AtariVox/SaveKey EEPROM access |
627 | myEEPROMAccess[set] = instance().settings().getBool(prefix + "eepromaccess" ); |
628 | |
629 | // TIA tab |
630 | myTIAType[set] = devSettings ? instance().settings().getString("dev.tia.type" ) : "standard" ; |
631 | myPlInvPhase[set] = devSettings ? instance().settings().getBool("dev.tia.plinvphase" ) : false; |
632 | myMsInvPhase[set] = devSettings ? instance().settings().getBool("dev.tia.msinvphase" ) : false; |
633 | myBlInvPhase[set] = devSettings ? instance().settings().getBool("dev.tia.blinvphase" ) : false; |
634 | myPFBits[set] = devSettings ? instance().settings().getBool("dev.tia.delaypfbits" ) : false; |
635 | myPFColor[set] = devSettings ? instance().settings().getBool("dev.tia.delaypfcolor" ) : false; |
636 | myPlSwap[set] = devSettings ? instance().settings().getBool("dev.tia.delayplswap" ) : false; |
637 | myBlSwap[set] = devSettings ? instance().settings().getBool("dev.tia.delayblswap" ) : false; |
638 | |
639 | // Debug colors |
640 | myDebugColors[set] = instance().settings().getBool(prefix + "debugcolors" ); |
641 | // PAL color-loss effect |
642 | myColorLoss[set] = instance().settings().getBool(prefix + "colorloss" ); |
643 | // Jitter |
644 | myTVJitter[set] = instance().settings().getBool(prefix + "tv.jitter" ); |
645 | myTVJitterRec[set] = instance().settings().getInt(prefix + "tv.jitter_recovery" ); |
646 | |
647 | // States |
648 | myTimeMachine[set] = instance().settings().getBool(prefix + "timemachine" ); |
649 | myStateSize[set] = instance().settings().getInt(prefix + "tm.size" ); |
650 | myUncompressed[set] = instance().settings().getInt(prefix + "tm.uncompressed" ); |
651 | myStateInterval[set] = instance().settings().getString(prefix + "tm.interval" ); |
652 | myStateHorizon[set] = instance().settings().getString(prefix + "tm.horizon" ); |
653 | |
654 | |
655 | } |
656 | |
657 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
658 | void DeveloperDialog::saveSettings(SettingsSet set) |
659 | { |
660 | bool devSettings = set == SettingsSet::developer; |
661 | const string& prefix = devSettings ? "dev." : "plr." ; |
662 | |
663 | instance().settings().setValue(prefix + "stats" , myFrameStats[set]); |
664 | instance().settings().setValue(prefix + "console" , myConsole[set] == 1 ? "7800" : "2600" ); |
665 | if(instance().hasConsole()) |
666 | instance().eventHandler().set7800Mode(); |
667 | |
668 | // Randomization |
669 | instance().settings().setValue(prefix + "bankrandom" , myRandomBank[set]); |
670 | instance().settings().setValue(prefix + "ramrandom" , myRandomizeRAM[set]); |
671 | instance().settings().setValue(prefix + "cpurandom" , myRandomizeCPU[set]); |
672 | // Undriven TIA pins |
673 | if(devSettings) |
674 | instance().settings().setValue("dev.tiadriven" , myUndrivenPins[set]); |
675 | #ifdef DEBUGGER_SUPPORT |
676 | if (devSettings) |
677 | { |
678 | // Read from write ports break |
679 | instance().settings().setValue("dev.rwportbreak" , myRWPortBreak[set]); |
680 | // Write to read ports break |
681 | instance().settings().setValue("dev.wrportbreak" , myWRPortBreak[set]); |
682 | } |
683 | #endif |
684 | if(devSettings) |
685 | // Thumb ARM emulation exception |
686 | instance().settings().setValue("dev.thumb.trapfatal" , myThumbException[set]); |
687 | // AtariVox/SaveKey EEPROM access |
688 | instance().settings().setValue(prefix + "eepromaccess" , myEEPROMAccess[set]); |
689 | |
690 | // TIA tab |
691 | if (devSettings) |
692 | { |
693 | instance().settings().setValue("dev.tia.type" , myTIAType[set]); |
694 | if (BSPF::equalsIgnoreCase("custom" , myTIAType[set])) |
695 | { |
696 | instance().settings().setValue("dev.tia.plinvphase" , myPlInvPhase[set]); |
697 | instance().settings().setValue("dev.tia.msinvphase" , myMsInvPhase[set]); |
698 | instance().settings().setValue("dev.tia.blinvphase" , myBlInvPhase[set]); |
699 | instance().settings().setValue("dev.tia.delaypfbits" , myPFBits[set]); |
700 | instance().settings().setValue("dev.tia.delaypfcolor" , myPFColor[set]); |
701 | instance().settings().setValue("dev.tia.delayplswap" , myPlSwap[set]); |
702 | instance().settings().setValue("dev.tia.delayblswap" , myBlSwap[set]); |
703 | } |
704 | } |
705 | |
706 | // Debug colors |
707 | instance().settings().setValue(prefix + "debugcolors" , myDebugColors[set]); |
708 | // PAL color loss |
709 | instance().settings().setValue(prefix + "colorloss" , myColorLoss[set]); |
710 | // Jitter |
711 | instance().settings().setValue(prefix + "tv.jitter" , myTVJitter[set]); |
712 | instance().settings().setValue(prefix + "tv.jitter_recovery" , myTVJitterRec[set]); |
713 | |
714 | // States |
715 | instance().settings().setValue(prefix + "timemachine" , myTimeMachine[set]); |
716 | instance().settings().setValue(prefix + "tm.size" , myStateSize[set]); |
717 | instance().settings().setValue(prefix + "tm.uncompressed" , myUncompressed[set]); |
718 | instance().settings().setValue(prefix + "tm.interval" , myStateInterval[set]); |
719 | instance().settings().setValue(prefix + "tm.horizon" , myStateHorizon[set]); |
720 | } |
721 | |
722 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
723 | void DeveloperDialog::getWidgetStates(SettingsSet set) |
724 | { |
725 | myFrameStats[set] = myFrameStatsWidget->getState(); |
726 | myConsole[set] = myConsoleWidget->getSelected() == 1; |
727 | // Randomization |
728 | myRandomBank[set] = myRandomBankWidget->getState(); |
729 | myRandomizeRAM[set] = myRandomizeRAMWidget->getState(); |
730 | string cpurandom; |
731 | const char* const cpuregs[] = { "S" , "A" , "X" , "Y" , "P" }; |
732 | for(int i = 0; i < 5; ++i) |
733 | if(myRandomizeCPUWidget[i]->getState()) |
734 | cpurandom += cpuregs[i]; |
735 | myRandomizeCPU[set] = cpurandom; |
736 | // Undriven TIA pins |
737 | myUndrivenPins[set] = myUndrivenPinsWidget->getState(); |
738 | #ifdef DEBUGGER_SUPPORT |
739 | // Read from write ports break |
740 | myRWPortBreak[set] = myRWPortBreakWidget->getState(); |
741 | myWRPortBreak[set] = myWRPortBreakWidget->getState(); |
742 | #endif |
743 | // Thumb ARM emulation exception |
744 | myThumbException[set] = myThumbExceptionWidget->getState(); |
745 | // AtariVox/SaveKey EEPROM access |
746 | myEEPROMAccess[set] = myEEPROMAccessWidget->getState(); |
747 | |
748 | // TIA tab |
749 | myTIAType[set] = myTIATypeWidget->getSelectedTag().toString(); |
750 | myPlInvPhase[set] = myPlInvPhaseWidget->getState(); |
751 | myMsInvPhase[set] = myMsInvPhaseWidget->getState(); |
752 | myBlInvPhase[set] = myBlInvPhaseWidget->getState(); |
753 | myPFBits[set] = myPFBitsWidget->getState(); |
754 | myPFColor[set] = myPFColorWidget->getState(); |
755 | myPlSwap[set] = myPlSwapWidget->getState(); |
756 | myBlSwap[set] = myBlSwapWidget->getState(); |
757 | |
758 | // Debug colors |
759 | myDebugColors[set] = myDebugColorsWidget->getState(); |
760 | // PAL color-loss effect |
761 | myColorLoss[set] = myColorLossWidget->getState(); |
762 | // Jitter |
763 | myTVJitter[set] = myTVJitterWidget->getState(); |
764 | myTVJitterRec[set] = myTVJitterRecWidget->getValue(); |
765 | |
766 | // States |
767 | myTimeMachine[set] = myTimeMachineWidget->getState(); |
768 | myStateSize[set] = myStateSizeWidget->getValue(); |
769 | myUncompressed[set] = myUncompressedWidget->getValue(); |
770 | myStateInterval[set] = myStateIntervalWidget->getSelected(); |
771 | myStateInterval[set] = myStateIntervalWidget->getSelectedTag().toString(); |
772 | myStateHorizon[set] = myStateHorizonWidget->getSelectedTag().toString(); |
773 | } |
774 | |
775 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
776 | void DeveloperDialog::setWidgetStates(SettingsSet set) |
777 | { |
778 | myFrameStatsWidget->setState(myFrameStats[set]); |
779 | myConsoleWidget->setSelectedIndex(myConsole[set]); |
780 | // Randomization |
781 | myRandomBankWidget->setState(myRandomBank[set]); |
782 | myRandomizeRAMWidget->setState(myRandomizeRAM[set]); |
783 | |
784 | const string& cpurandom = myRandomizeCPU[set]; |
785 | const char* const cpuregs[] = { "S" , "A" , "X" , "Y" , "P" }; |
786 | for(int i = 0; i < 5; ++i) |
787 | myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, cpuregs[i])); |
788 | // Undriven TIA pins |
789 | myUndrivenPinsWidget->setState(myUndrivenPins[set]); |
790 | #ifdef DEBUGGER_SUPPORT |
791 | // Read from write ports break |
792 | myRWPortBreakWidget->setState(myRWPortBreak[set]); |
793 | myWRPortBreakWidget->setState(myWRPortBreak[set]); |
794 | #endif |
795 | // Thumb ARM emulation exception |
796 | myThumbExceptionWidget->setState(myThumbException[set]); |
797 | // AtariVox/SaveKey EEPROM access |
798 | myEEPROMAccessWidget->setState(myEEPROMAccess[set]); |
799 | handleConsole(); |
800 | |
801 | // TIA tab |
802 | myTIATypeWidget->setSelected(myTIAType[set], "standard" ); |
803 | handleTia(); |
804 | |
805 | // Debug colors |
806 | myDebugColorsWidget->setState(myDebugColors[set]); |
807 | // PAL color-loss effect |
808 | myColorLossWidget->setState(myColorLoss[set]); |
809 | // Jitter |
810 | myTVJitterWidget->setState(myTVJitter[set]); |
811 | myTVJitterRecWidget->setValue(myTVJitterRec[set]); |
812 | |
813 | handleTVJitterChange(myTVJitterWidget->getState()); |
814 | |
815 | // States |
816 | myTimeMachineWidget->setState(myTimeMachine[set]); |
817 | myStateSizeWidget->setValue(myStateSize[set]); |
818 | myUncompressedWidget->setValue(myUncompressed[set]); |
819 | myStateIntervalWidget->setSelected(myStateInterval[set]); |
820 | myStateHorizonWidget->setSelected(myStateHorizon[set]); |
821 | |
822 | handleTimeMachine(); |
823 | handleSize(); |
824 | handleUncompressed(); |
825 | handleInterval(); |
826 | handleHorizon(); |
827 | } |
828 | |
829 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
830 | void DeveloperDialog::loadConfig() |
831 | { |
832 | bool devSettings = instance().settings().getBool("dev.settings" ); |
833 | handleSettings(devSettings); |
834 | mySettings = devSettings; |
835 | mySettingsGroupEmulation->setSelected(devSettings ? 1 : 0); |
836 | mySettingsGroupTia->setSelected(devSettings ? 1 : 0); |
837 | mySettingsGroupVideo->setSelected(devSettings ? 1 : 0); |
838 | mySettingsGroupTM->setSelected(devSettings ? 1 : 0); |
839 | |
840 | // load both setting sets... |
841 | loadSettings(SettingsSet::player); |
842 | loadSettings(SettingsSet::developer); |
843 | // ...and select the current one |
844 | setWidgetStates(SettingsSet(mySettingsGroupEmulation->getSelected())); |
845 | |
846 | // Debug colours |
847 | handleDebugColours(instance().settings().getString("tia.dbgcolors" )); |
848 | |
849 | // Save on exit |
850 | string saveOnExit = instance().settings().getString("saveonexit" ); |
851 | mySaveOnExitGroup->setSelected(saveOnExit == "all" ? 2 : saveOnExit == "current" ? 1 : 0); |
852 | |
853 | #ifdef DEBUGGER_SUPPORT |
854 | uInt32 w, h; |
855 | |
856 | // Debugger size |
857 | const Common::Size& ds = instance().settings().getSize("dbg.res" ); |
858 | w = ds.w; h = ds.h; |
859 | |
860 | myDebuggerWidthSlider->setValue(w); |
861 | myDebuggerHeightSlider->setValue(h); |
862 | |
863 | // Debugger font size |
864 | string size = instance().settings().getString("dbg.fontsize" ); |
865 | myDebuggerFontSize->setSelected(size, "medium" ); |
866 | |
867 | // Debugger font style |
868 | int style = instance().settings().getInt("dbg.fontstyle" ); |
869 | myDebuggerFontStyle->setSelected(style, "0" ); |
870 | |
871 | // Ghost reads trap |
872 | myGhostReadsTrapWidget->setState(instance().settings().getBool("dbg.ghostreadstrap" )); |
873 | |
874 | handleFontSize(); |
875 | #endif |
876 | |
877 | myTab->loadConfig(); |
878 | } |
879 | |
880 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
881 | void DeveloperDialog::saveConfig() |
882 | { |
883 | instance().settings().setValue("dev.settings" , mySettingsGroupEmulation->getSelected() == SettingsSet::developer); |
884 | // copy current widget status into set... |
885 | getWidgetStates(SettingsSet(mySettingsGroupEmulation->getSelected())); |
886 | // ...and save both sets |
887 | saveSettings(SettingsSet::player); |
888 | saveSettings(SettingsSet::developer); |
889 | |
890 | // activate the current settings |
891 | instance().frameBuffer().showFrameStats(myFrameStatsWidget->getState()); |
892 | // jitter |
893 | if(instance().hasConsole()) |
894 | { |
895 | instance().console().tia().toggleJitter(myTVJitterWidget->getState() ? 1 : 0); |
896 | instance().console().tia().setJitterRecoveryFactor(myTVJitterRecWidget->getValue()); |
897 | } |
898 | |
899 | // TIA tab |
900 | if(instance().hasConsole()) |
901 | { |
902 | instance().console().tia().setPlInvertedPhaseClock(myPlInvPhaseWidget->getState()); |
903 | instance().console().tia().setMsInvertedPhaseClock(myMsInvPhaseWidget->getState()); |
904 | instance().console().tia().setBlInvertedPhaseClock(myBlInvPhaseWidget->getState()); |
905 | instance().console().tia().setPFBitsDelay(myPFBitsWidget->getState()); |
906 | instance().console().tia().setPFColorDelay(myPFColorWidget->getState()); |
907 | instance().console().tia().setPlSwapDelay(myPlSwapWidget->getState()); |
908 | instance().console().tia().setBlSwapDelay(myBlSwapWidget->getState()); |
909 | } |
910 | |
911 | handleEnableDebugColors(); |
912 | // PAL color loss |
913 | if(instance().hasConsole()) |
914 | instance().console().enableColorLoss(myColorLossWidget->getState()); |
915 | |
916 | // Debug colours |
917 | string dbgcolors; |
918 | for(int i = 0; i < DEBUG_COLORS; ++i) |
919 | dbgcolors += myDbgColour[i]->getSelectedTag().toString(); |
920 | if(instance().hasConsole() && |
921 | instance().console().tia().setFixedColorPalette(dbgcolors)) |
922 | instance().settings().setValue("tia.dbgcolors" , dbgcolors); |
923 | |
924 | // update RewindManager |
925 | instance().state().rewindManager().setup(); |
926 | instance().state().setRewindMode(myTimeMachineWidget->getState() ? |
927 | StateManager::Mode::TimeMachine : StateManager::Mode::Off); |
928 | |
929 | // Save on exit |
930 | int saveOnExit = mySaveOnExitGroup->getSelected(); |
931 | instance().settings().setValue("saveonexit" , |
932 | saveOnExit == 0 ? "none" : saveOnExit == 1 ? "current" : "all" ); |
933 | |
934 | #ifdef DEBUGGER_SUPPORT |
935 | // Debugger font style |
936 | instance().settings().setValue("dbg.fontstyle" , |
937 | myDebuggerFontStyle->getSelectedTag().toString()); |
938 | // Debugger size |
939 | instance().settings().setValue("dbg.res" , |
940 | Common::Size(myDebuggerWidthSlider->getValue(), |
941 | myDebuggerHeightSlider->getValue())); |
942 | // Debugger font size |
943 | instance().settings().setValue("dbg.fontsize" , myDebuggerFontSize->getSelectedTag().toString()); |
944 | |
945 | // Ghost reads trap |
946 | instance().settings().setValue("dbg.ghostreadstrap" , myGhostReadsTrapWidget->getState()); |
947 | if(instance().hasConsole()) |
948 | instance().console().system().m6502().setGhostReadsTrap(myGhostReadsTrapWidget->getState()); |
949 | |
950 | // Read from write ports and write to read ports breaks |
951 | if (instance().hasConsole()) |
952 | { |
953 | instance().console().system().m6502().setReadFromWritePortBreak(myRWPortBreakWidget->getState()); |
954 | instance().console().system().m6502().setWriteToReadPortBreak(myWRPortBreakWidget->getState()); |
955 | } |
956 | #endif |
957 | } |
958 | |
959 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
960 | void DeveloperDialog::setDefaults() |
961 | { |
962 | bool devSettings = mySettings; |
963 | SettingsSet set = SettingsSet(mySettingsGroupEmulation->getSelected()); |
964 | |
965 | switch(myTab->getActiveTab()) |
966 | { |
967 | case 0: // Emulation |
968 | myFrameStats[set] = devSettings ? true : false; |
969 | myConsole[set] = 0; |
970 | // Randomization |
971 | myRandomBank[set] = devSettings ? true : false; |
972 | myRandomizeRAM[set] = true; |
973 | myRandomizeCPU[set] = devSettings ? "SAXYP" : "AXYP" ; |
974 | // Undriven TIA pins |
975 | myUndrivenPins[set] = devSettings ? true : false; |
976 | #ifdef DEBUGGER_SUPPORT |
977 | // Reads from write ports |
978 | myRWPortBreak[set] = devSettings ? true : false; |
979 | myWRPortBreak[set] = devSettings ? true : false; |
980 | #endif |
981 | // Thumb ARM emulation exception |
982 | myThumbException[set] = devSettings ? true : false; |
983 | // AtariVox/SaveKey EEPROM access |
984 | myEEPROMAccess[set] = devSettings ? true : false; |
985 | |
986 | setWidgetStates(set); |
987 | break; |
988 | |
989 | case 1: // TIA |
990 | myTIAType[set] = "standard" ; |
991 | // reset "custom" mode |
992 | myPlInvPhase[set] = devSettings ? true : false; |
993 | myMsInvPhase[set] = devSettings ? true : false; |
994 | myBlInvPhase[set] = devSettings ? true : false; |
995 | myPFBits[set] = devSettings ? true : false; |
996 | myPFColor[set] = devSettings ? true : false; |
997 | myPlSwap[set] = devSettings ? true : false; |
998 | myBlSwap[set] = devSettings ? true : false; |
999 | |
1000 | setWidgetStates(set); |
1001 | break; |
1002 | |
1003 | case 2: // Video |
1004 | // Jitter |
1005 | myTVJitter[set] = true; |
1006 | myTVJitterRec[set] = devSettings ? 2 : 10; |
1007 | // PAL color-loss effect |
1008 | myColorLoss[set] = devSettings ? true : false; |
1009 | // Debug colors |
1010 | myDebugColors[set] = false; |
1011 | handleDebugColours("roygpb" ); |
1012 | |
1013 | setWidgetStates(set); |
1014 | break; |
1015 | |
1016 | case 3: // States |
1017 | myTimeMachine[set] = true; |
1018 | myStateSize[set] = devSettings ? 1000 : 200; |
1019 | myUncompressed[set] = devSettings ? 600 : 60; |
1020 | myStateInterval[set] = devSettings ? "1f" : "30f" ; |
1021 | myStateHorizon[set] = devSettings ? "30s" : "10m" ; |
1022 | |
1023 | setWidgetStates(set); |
1024 | mySaveOnExitGroup->setSelected(0); |
1025 | break; |
1026 | |
1027 | case 4: // Debugger options |
1028 | { |
1029 | #ifdef DEBUGGER_SUPPORT |
1030 | uInt32 w = std::min(instance().frameBuffer().desktopSize().w, uInt32(DebuggerDialog::kMediumFontMinW)); |
1031 | uInt32 h = std::min(instance().frameBuffer().desktopSize().h, uInt32(DebuggerDialog::kMediumFontMinH)); |
1032 | myDebuggerWidthSlider->setValue(w); |
1033 | myDebuggerHeightSlider->setValue(h); |
1034 | myDebuggerFontSize->setSelected("medium" ); |
1035 | myDebuggerFontStyle->setSelected("0" ); |
1036 | |
1037 | myGhostReadsTrapWidget->setState(true); |
1038 | |
1039 | handleFontSize(); |
1040 | #endif |
1041 | break; |
1042 | } |
1043 | |
1044 | default: |
1045 | break; |
1046 | } |
1047 | } |
1048 | |
1049 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1050 | void DeveloperDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) |
1051 | { |
1052 | switch(cmd) |
1053 | { |
1054 | case kPlrSettings: |
1055 | handleSettings(false); |
1056 | break; |
1057 | |
1058 | case kDevSettings: |
1059 | handleSettings(true); |
1060 | break; |
1061 | |
1062 | case kTIAType: |
1063 | handleTia(); |
1064 | break; |
1065 | |
1066 | case kConsole: |
1067 | handleConsole(); |
1068 | break; |
1069 | |
1070 | case kTVJitter: |
1071 | handleTVJitterChange(myTVJitterWidget->getState()); |
1072 | break; |
1073 | |
1074 | case kTVJitterChanged: |
1075 | myTVJitterRecLabelWidget->setValue(myTVJitterRecWidget->getValue()); |
1076 | break; |
1077 | |
1078 | case kPPinCmd: |
1079 | instance().console().tia().driveUnusedPinsRandom(myUndrivenPinsWidget->getState()); |
1080 | break; |
1081 | |
1082 | case kTimeMachine: |
1083 | handleTimeMachine(); |
1084 | break; |
1085 | |
1086 | case kSizeChanged: |
1087 | handleSize(); |
1088 | break; |
1089 | |
1090 | case kUncompressedChanged: |
1091 | handleUncompressed(); |
1092 | break; |
1093 | |
1094 | case kIntervalChanged: |
1095 | handleInterval(); |
1096 | break; |
1097 | |
1098 | case kHorizonChanged: |
1099 | handleHorizon(); |
1100 | break; |
1101 | |
1102 | case kP0ColourChangedCmd: |
1103 | handleDebugColours(0, myDbgColour[0]->getSelected()); |
1104 | break; |
1105 | |
1106 | case kM0ColourChangedCmd: |
1107 | handleDebugColours(1, myDbgColour[1]->getSelected()); |
1108 | break; |
1109 | |
1110 | case kP1ColourChangedCmd: |
1111 | handleDebugColours(2, myDbgColour[2]->getSelected()); |
1112 | break; |
1113 | |
1114 | case kM1ColourChangedCmd: |
1115 | handleDebugColours(3, myDbgColour[3]->getSelected()); |
1116 | break; |
1117 | |
1118 | case kPFColourChangedCmd: |
1119 | handleDebugColours(4, myDbgColour[4]->getSelected()); |
1120 | break; |
1121 | |
1122 | case kBLColourChangedCmd: |
1123 | handleDebugColours(5, myDbgColour[5]->getSelected()); |
1124 | break; |
1125 | |
1126 | #ifdef DEBUGGER_SUPPORT |
1127 | case kDFontSizeChanged: |
1128 | handleFontSize(); |
1129 | break; |
1130 | #endif |
1131 | |
1132 | case GuiObject::kOKCmd: |
1133 | saveConfig(); |
1134 | close(); |
1135 | break; |
1136 | |
1137 | case GuiObject::kCloseCmd: |
1138 | // Revert changes made to event mapping |
1139 | close(); |
1140 | break; |
1141 | |
1142 | case GuiObject::kDefaultsCmd: |
1143 | setDefaults(); |
1144 | break; |
1145 | |
1146 | default: |
1147 | Dialog::handleCommand(sender, cmd, data, 0); |
1148 | } |
1149 | } |
1150 | |
1151 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1152 | void DeveloperDialog::handleSettings(bool devSettings) |
1153 | { |
1154 | myUndrivenPinsWidget->setEnabled(devSettings); |
1155 | #ifdef DEBUGGER_SUPPORT |
1156 | myRWPortBreakWidget->setEnabled(devSettings); |
1157 | myWRPortBreakWidget->setEnabled(devSettings); |
1158 | #endif |
1159 | myThumbExceptionWidget->setEnabled(devSettings); |
1160 | |
1161 | if (mySettings != devSettings) |
1162 | { |
1163 | mySettings = devSettings; // block redundant events first! |
1164 | SettingsSet set = devSettings ? SettingsSet::developer : SettingsSet::player; |
1165 | mySettingsGroupEmulation->setSelected(set); |
1166 | mySettingsGroupTia->setSelected(set); |
1167 | mySettingsGroupVideo->setSelected(set); |
1168 | mySettingsGroupTM->setSelected(set); |
1169 | getWidgetStates(devSettings ? SettingsSet::player : SettingsSet::developer); |
1170 | setWidgetStates(set); |
1171 | } |
1172 | } |
1173 | |
1174 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1175 | void DeveloperDialog::handleTVJitterChange(bool enable) |
1176 | { |
1177 | myTVJitterRecWidget->setEnabled(enable); |
1178 | myTVJitterRecLabelWidget->setEnabled(enable); |
1179 | } |
1180 | |
1181 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1182 | void DeveloperDialog::handleEnableDebugColors() |
1183 | { |
1184 | if(instance().hasConsole()) |
1185 | { |
1186 | bool fixed = instance().console().tia().usingFixedColors(); |
1187 | if(fixed != myDebugColorsWidget->getState()) |
1188 | instance().console().tia().toggleFixedColors(); |
1189 | } |
1190 | } |
1191 | |
1192 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1193 | void DeveloperDialog::handleConsole() |
1194 | { |
1195 | bool is7800 = myConsoleWidget->getSelected() == 1; |
1196 | |
1197 | myRandomizeRAMWidget->setEnabled(!is7800); |
1198 | if(is7800) |
1199 | myRandomizeRAMWidget->setState(false); |
1200 | } |
1201 | |
1202 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1203 | void DeveloperDialog::handleTia() |
1204 | { |
1205 | bool enable = BSPF::equalsIgnoreCase("custom" , myTIATypeWidget->getSelectedTag().toString()); |
1206 | |
1207 | myTIATypeWidget->setEnabled(mySettings); |
1208 | myInvPhaseLabel->setEnabled(enable); |
1209 | myPlInvPhaseWidget->setEnabled(enable); |
1210 | myMsInvPhaseWidget->setEnabled(enable); |
1211 | myBlInvPhaseWidget->setEnabled(enable); |
1212 | myPlayfieldLabel->setEnabled(enable); |
1213 | myPFBitsWidget->setEnabled(enable); |
1214 | myPFColorWidget->setEnabled(enable); |
1215 | mySwapLabel->setEnabled(enable); |
1216 | myPlSwapWidget->setEnabled(enable); |
1217 | myBlSwapWidget->setEnabled(enable); |
1218 | |
1219 | if(BSPF::equalsIgnoreCase("custom" , myTIATypeWidget->getSelectedTag().toString())) |
1220 | { |
1221 | myPlInvPhaseWidget->setState(myPlInvPhase[SettingsSet::developer]); |
1222 | myMsInvPhaseWidget->setState(myMsInvPhase[SettingsSet::developer]); |
1223 | myBlInvPhaseWidget->setState(myBlInvPhase[SettingsSet::developer]); |
1224 | myPFBitsWidget->setState(myPFBits[SettingsSet::developer]); |
1225 | myPFColorWidget->setState(myPFColor[SettingsSet::developer]); |
1226 | myPlSwapWidget->setState(myPlSwap[SettingsSet::developer]); |
1227 | myBlSwapWidget->setState(myBlSwap[SettingsSet::developer]); |
1228 | } |
1229 | else |
1230 | { |
1231 | myPlInvPhaseWidget->setState(BSPF::equalsIgnoreCase("koolaidman" , myTIATypeWidget->getSelectedTag().toString())); |
1232 | myMsInvPhaseWidget->setState(BSPF::equalsIgnoreCase("cosmicark" , myTIATypeWidget->getSelectedTag().toString())); |
1233 | myBlInvPhaseWidget->setState(false); |
1234 | myPFBitsWidget->setState(BSPF::equalsIgnoreCase("pesco" , myTIATypeWidget->getSelectedTag().toString())); |
1235 | myPFColorWidget->setState(BSPF::equalsIgnoreCase("quickstep" , myTIATypeWidget->getSelectedTag().toString())); |
1236 | myPlSwapWidget->setState(BSPF::equalsIgnoreCase("heman" , myTIATypeWidget->getSelectedTag().toString())); |
1237 | myBlSwapWidget->setState(false); |
1238 | } |
1239 | } |
1240 | |
1241 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1242 | void DeveloperDialog::handleTimeMachine() |
1243 | { |
1244 | bool enable = myTimeMachineWidget->getState(); |
1245 | |
1246 | myStateSizeWidget->setEnabled(enable); |
1247 | myUncompressedWidget->setEnabled(enable); |
1248 | myStateIntervalWidget->setEnabled(enable); |
1249 | |
1250 | uInt32 size = myStateSizeWidget->getValue(); |
1251 | uInt32 uncompressed = myUncompressedWidget->getValue(); |
1252 | |
1253 | myStateHorizonWidget->setEnabled(enable && size > uncompressed); |
1254 | } |
1255 | |
1256 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1257 | void DeveloperDialog::handleSize() |
1258 | { |
1259 | uInt32 size = myStateSizeWidget->getValue(); |
1260 | uInt32 uncompressed = myUncompressedWidget->getValue(); |
1261 | Int32 interval = myStateIntervalWidget->getSelected(); |
1262 | Int32 horizon = myStateHorizonWidget->getSelected(); |
1263 | bool found = false; |
1264 | Int32 i; |
1265 | |
1266 | // handle illegal values |
1267 | if(interval == -1) |
1268 | interval = 0; |
1269 | if(horizon == -1) |
1270 | horizon = 0; |
1271 | |
1272 | // adapt horizon and interval |
1273 | do |
1274 | { |
1275 | for(i = horizon; i < NUM_HORIZONS; ++i) |
1276 | { |
1277 | if(uInt64(size) * instance().state().rewindManager().INTERVAL_CYCLES[interval] |
1278 | <= instance().state().rewindManager().HORIZON_CYCLES[i]) |
1279 | { |
1280 | found = true; |
1281 | break; |
1282 | } |
1283 | } |
1284 | if(!found) |
1285 | --interval; |
1286 | } while(!found); |
1287 | |
1288 | if(size < uncompressed) |
1289 | myUncompressedWidget->setValue(size); |
1290 | myStateIntervalWidget->setSelectedIndex(interval); |
1291 | myStateHorizonWidget->setSelectedIndex(i); |
1292 | myStateHorizonWidget->setEnabled(myTimeMachineWidget->getState() && size > uncompressed); |
1293 | } |
1294 | |
1295 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1296 | void DeveloperDialog::handleUncompressed() |
1297 | { |
1298 | uInt32 size = myStateSizeWidget->getValue(); |
1299 | uInt32 uncompressed = myUncompressedWidget->getValue(); |
1300 | |
1301 | if(size < uncompressed) |
1302 | myStateSizeWidget->setValue(uncompressed); |
1303 | myStateHorizonWidget->setEnabled(myTimeMachineWidget->getState() && size > uncompressed); |
1304 | } |
1305 | |
1306 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1307 | void DeveloperDialog::handleInterval() |
1308 | { |
1309 | uInt32 size = myStateSizeWidget->getValue(); |
1310 | uInt32 uncompressed = myUncompressedWidget->getValue(); |
1311 | Int32 interval = myStateIntervalWidget->getSelected(); |
1312 | Int32 horizon = myStateHorizonWidget->getSelected(); |
1313 | bool found = false; |
1314 | Int32 i; |
1315 | |
1316 | // handle illegal values |
1317 | if(interval == -1) |
1318 | interval = 0; |
1319 | if(horizon == -1) |
1320 | horizon = 0; |
1321 | |
1322 | // adapt horizon and size |
1323 | do |
1324 | { |
1325 | for(i = horizon; i < NUM_HORIZONS; ++i) |
1326 | { |
1327 | if(uInt64(size) * instance().state().rewindManager().INTERVAL_CYCLES[interval] |
1328 | <= instance().state().rewindManager().HORIZON_CYCLES[i]) |
1329 | { |
1330 | found = true; |
1331 | break; |
1332 | } |
1333 | } |
1334 | if(!found) |
1335 | size -= myStateSizeWidget->getStepValue(); |
1336 | } while(!found); |
1337 | |
1338 | myStateHorizonWidget->setSelectedIndex(i); |
1339 | myStateSizeWidget->setValue(size); |
1340 | if(size < uncompressed) |
1341 | myUncompressedWidget->setValue(size); |
1342 | } |
1343 | |
1344 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1345 | void DeveloperDialog::handleHorizon() |
1346 | { |
1347 | uInt32 size = myStateSizeWidget->getValue(); |
1348 | uInt32 uncompressed = myUncompressedWidget->getValue(); |
1349 | Int32 interval = myStateIntervalWidget->getSelected(); |
1350 | Int32 horizon = myStateHorizonWidget->getSelected(); |
1351 | bool found = false; |
1352 | Int32 i; |
1353 | |
1354 | // handle illegal values |
1355 | if(interval == -1) |
1356 | interval = 0; |
1357 | if(horizon == -1) |
1358 | horizon = 0; |
1359 | |
1360 | // adapt interval and size |
1361 | do |
1362 | { |
1363 | for(i = interval; i >= 0; --i) |
1364 | { |
1365 | if(uInt64(size) * instance().state().rewindManager().INTERVAL_CYCLES[i] |
1366 | <= instance().state().rewindManager().HORIZON_CYCLES[horizon]) |
1367 | { |
1368 | found = true; |
1369 | break; |
1370 | } |
1371 | } |
1372 | if(!found) |
1373 | size -= myStateSizeWidget->getStepValue(); |
1374 | } while(!found); |
1375 | |
1376 | myStateIntervalWidget->setSelectedIndex(i); |
1377 | myStateSizeWidget->setValue(size); |
1378 | if(size < uncompressed) |
1379 | myUncompressedWidget->setValue(size); |
1380 | } |
1381 | |
1382 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1383 | void DeveloperDialog::handleDebugColours(int idx, int color) |
1384 | { |
1385 | if(idx < 0 || idx >= DEBUG_COLORS) |
1386 | return; |
1387 | |
1388 | if(!instance().hasConsole()) |
1389 | { |
1390 | myDbgColour[idx]->clearFlags(Widget::FLAG_ENABLED); |
1391 | myDbgColourSwatch[idx]->clearFlags(Widget::FLAG_ENABLED); |
1392 | return; |
1393 | } |
1394 | |
1395 | static constexpr ColorId dbg_color[3][DEBUG_COLORS] = { |
1396 | { |
1397 | TIA::FixedColor::NTSC_RED, |
1398 | TIA::FixedColor::NTSC_ORANGE, |
1399 | TIA::FixedColor::NTSC_YELLOW, |
1400 | TIA::FixedColor::NTSC_GREEN, |
1401 | TIA::FixedColor::NTSC_PURPLE, |
1402 | TIA::FixedColor::NTSC_BLUE |
1403 | }, |
1404 | { |
1405 | TIA::FixedColor::PAL_RED, |
1406 | TIA::FixedColor::PAL_ORANGE, |
1407 | TIA::FixedColor::PAL_YELLOW, |
1408 | TIA::FixedColor::PAL_GREEN, |
1409 | TIA::FixedColor::PAL_PURPLE, |
1410 | TIA::FixedColor::PAL_BLUE |
1411 | }, |
1412 | { |
1413 | TIA::FixedColor::SECAM_RED, |
1414 | TIA::FixedColor::SECAM_ORANGE, |
1415 | TIA::FixedColor::SECAM_YELLOW, |
1416 | TIA::FixedColor::SECAM_GREEN, |
1417 | TIA::FixedColor::SECAM_PURPLE, |
1418 | TIA::FixedColor::SECAM_BLUE |
1419 | } |
1420 | }; |
1421 | |
1422 | int timing = instance().console().timing() == ConsoleTiming::ntsc ? 0 |
1423 | : instance().console().timing() == ConsoleTiming::pal ? 1 : 2; |
1424 | |
1425 | myDbgColourSwatch[idx]->setColor(dbg_color[timing][color]); |
1426 | myDbgColour[idx]->setSelectedIndex(color); |
1427 | |
1428 | // make sure the selected debug colors are all different |
1429 | bool usedCol[DEBUG_COLORS]; |
1430 | |
1431 | // identify used colors |
1432 | for(int i = 0; i < DEBUG_COLORS; ++i) |
1433 | { |
1434 | usedCol[i] = false; |
1435 | for(int j = 0; j < DEBUG_COLORS; ++j) |
1436 | { |
1437 | if(myDbgColourSwatch[j]->getColor() == dbg_color[timing][i]) |
1438 | { |
1439 | usedCol[i] = true; |
1440 | break; |
1441 | } |
1442 | } |
1443 | } |
1444 | // check if currently changed color was used somewhere else |
1445 | for(int i = 0; i < DEBUG_COLORS; ++i) |
1446 | { |
1447 | if (i != idx && myDbgColourSwatch[i]->getColor() == dbg_color[timing][color]) |
1448 | { |
1449 | // if already used, change the other color to an unused one |
1450 | for(int j = 0; j < DEBUG_COLORS; ++j) |
1451 | { |
1452 | if(!usedCol[j]) |
1453 | { |
1454 | myDbgColourSwatch[i]->setColor(dbg_color[timing][j]); |
1455 | myDbgColour[i]->setSelectedIndex(j); |
1456 | break; |
1457 | } |
1458 | } |
1459 | } |
1460 | } |
1461 | } |
1462 | |
1463 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1464 | void DeveloperDialog::handleDebugColours(const string& colors) |
1465 | { |
1466 | for(int i = 0; i < DEBUG_COLORS; ++i) |
1467 | { |
1468 | switch(colors[i]) |
1469 | { |
1470 | case 'r': handleDebugColours(i, 0); break; |
1471 | case 'o': handleDebugColours(i, 1); break; |
1472 | case 'y': handleDebugColours(i, 2); break; |
1473 | case 'g': handleDebugColours(i, 3); break; |
1474 | case 'p': handleDebugColours(i, 4); break; |
1475 | case 'b': handleDebugColours(i, 5); break; |
1476 | default: break; |
1477 | } |
1478 | } |
1479 | } |
1480 | |
1481 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1482 | void DeveloperDialog::handleFontSize() |
1483 | { |
1484 | #ifdef DEBUGGER_SUPPORT |
1485 | uInt32 minW, minH; |
1486 | int fontSize = myDebuggerFontSize->getSelected(); |
1487 | |
1488 | if(fontSize == 0) |
1489 | { |
1490 | minW = DebuggerDialog::kSmallFontMinW; |
1491 | minH = DebuggerDialog::kSmallFontMinH; |
1492 | } |
1493 | else if(fontSize == 1) |
1494 | { |
1495 | minW = DebuggerDialog::kMediumFontMinW; |
1496 | minH = DebuggerDialog::kMediumFontMinH; |
1497 | } |
1498 | else // large |
1499 | { |
1500 | minW = DebuggerDialog::kLargeFontMinW; |
1501 | minH = DebuggerDialog::kLargeFontMinH; |
1502 | } |
1503 | minW = std::min(instance().frameBuffer().desktopSize().w, minW); |
1504 | minH = std::min(instance().frameBuffer().desktopSize().h, minH); |
1505 | |
1506 | myDebuggerWidthSlider->setMinValue(minW); |
1507 | if(minW > uInt32(myDebuggerWidthSlider->getValue())) |
1508 | myDebuggerWidthSlider->setValue(minW); |
1509 | |
1510 | myDebuggerHeightSlider->setMinValue(minH); |
1511 | if(minH > uInt32(myDebuggerHeightSlider->getValue())) |
1512 | myDebuggerHeightSlider->setValue(minH); |
1513 | #endif |
1514 | } |
1515 | |