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 <cmath>
19
20#include "bspf.hxx"
21#include "Control.hxx"
22#include "Dialog.hxx"
23#include "Menu.hxx"
24#include "OSystem.hxx"
25#include "EditTextWidget.hxx"
26#include "PopUpWidget.hxx"
27#include "Console.hxx"
28#include "TIA.hxx"
29#include "Settings.hxx"
30#include "Widget.hxx"
31#include "Font.hxx"
32#include "TabWidget.hxx"
33#include "NTSCFilter.hxx"
34#include "TIASurface.hxx"
35
36#include "VideoDialog.hxx"
37
38namespace {
39 // Emulation speed is a positive float that multiplies the framerate. However, the UI controls
40 // adjust speed in terms of a speedup factor (1/10, 1/9 .. 1/2, 1, 2, 3, .., 10). The following
41 // mapping and formatting functions implement this conversion. The speedup factor is represented
42 // by an integer value between -900 and 900 (0 means no speedup).
43
44 constexpr int MAX_SPEED = 900;
45 constexpr int MIN_SPEED = -900;
46 constexpr int SPEED_STEP = 10;
47
48 int mapSpeed(float speed)
49 {
50 speed = std::abs(speed);
51
52 return BSPF::clamp(
53 static_cast<int>(round(100 * (speed >= 1 ? speed - 1 : -1 / speed + 1))),
54 MIN_SPEED, MAX_SPEED
55 );
56 }
57
58 float unmapSpeed(int speed)
59 {
60 float f_speed = static_cast<float>(speed) / 100;
61
62 return speed < 0 ? -1 / (f_speed - 1) : 1 + f_speed;
63 }
64
65 string formatSpeed(int speed) {
66 stringstream ss;
67
68 ss
69 << std::setw(3) << std::fixed << std::setprecision(0)
70 << (unmapSpeed(speed) * 100);
71
72 return ss.str();
73 }
74}
75
76// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
77VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
78 const GUI::Font& font, int max_w, int max_h)
79 : Dialog(osystem, parent, font, "Video settings")
80{
81 const int VGAP = 4;
82 const int VBORDER = 8;
83 const int HBORDER = 10;
84 const int INDENT = 20;
85 const int lineHeight = font.getLineHeight(),
86 fontWidth = font.getMaxCharWidth(),
87 buttonHeight = font.getLineHeight() + 4;
88 int xpos, ypos, tabID;
89 int lwidth = font.getStringWidth("TIA Palette "),
90 pwidth = font.getStringWidth("XXXXxXXXX"),
91 swidth = font.getMaxCharWidth() * 10 - 2;
92
93 WidgetArray wid;
94 VariantList items;
95
96 // Set real dimensions
97 setSize(55 * fontWidth + HBORDER * 2, 14 * (lineHeight + VGAP) + 14 + _th, max_w, max_h);
98
99 // The tab widget
100 xpos = 2; ypos = 4;
101 myTab = new TabWidget(this, font, xpos, ypos + _th, _w - 2*xpos, _h - _th - buttonHeight - 20);
102 addTabWidget(myTab);
103
104 xpos = HBORDER; ypos = VBORDER;
105 //////////////////////////////////////////////////////////
106 // 1) General options
107 tabID = myTab->addTab(" General ");
108
109 // Video renderer
110 myRenderer = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
111 instance().frameBuffer().supportedRenderers(),
112 "Renderer ", lwidth);
113 wid.push_back(myRenderer);
114 ypos += lineHeight + VGAP;
115
116 // TIA Palette
117 items.clear();
118 VarList::push_back(items, "Standard", "standard");
119 VarList::push_back(items, "Z26", "z26");
120 VarList::push_back(items, "User", "user");
121 myTIAPalette = new PopUpWidget(myTab, font, xpos, ypos, pwidth,
122 lineHeight, items, "TIA palette ", lwidth);
123 wid.push_back(myTIAPalette);
124 ypos += lineHeight + VGAP;
125
126 // TIA interpolation
127 myTIAInterpolate = new CheckboxWidget(myTab, font, xpos, ypos + 1, "TIA interpolation ");
128 wid.push_back(myTIAInterpolate);
129 ypos += lineHeight + VGAP;
130
131 // TIA zoom levels (will be dynamically filled later)
132 myTIAZoom = new SliderWidget(myTab, font, xpos, ypos - 1, swidth, lineHeight,
133 "TIA zoom", lwidth, 0, fontWidth * 4, "%");
134 myTIAZoom->setMinValue(200); myTIAZoom->setStepValue(FrameBuffer::ZOOM_STEPS * 100);
135 wid.push_back(myTIAZoom);
136 ypos += lineHeight + VGAP;
137
138 // Aspect ratio (NTSC mode)
139 myNAspectRatio =
140 new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
141 "NTSC aspect ", lwidth, 0,
142 fontWidth * 4, "%");
143 myNAspectRatio->setMinValue(80); myNAspectRatio->setMaxValue(120);
144 myNAspectRatio->setTickmarkIntervals(2);
145 wid.push_back(myNAspectRatio);
146 ypos += lineHeight + VGAP;
147
148 // Aspect ratio (PAL mode)
149 myPAspectRatio =
150 new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
151 "PAL aspect ", lwidth, 0,
152 fontWidth * 4, "%");
153 myPAspectRatio->setMinValue(80); myPAspectRatio->setMaxValue(120);
154 myPAspectRatio->setTickmarkIntervals(2);
155 wid.push_back(myPAspectRatio);
156 ypos += lineHeight + VGAP;
157
158 // Speed
159 mySpeed =
160 new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
161 "Emul. speed ", lwidth, kSpeedupChanged, fontWidth * 5, "%");
162 mySpeed->setMinValue(MIN_SPEED); mySpeed->setMaxValue(MAX_SPEED);
163 mySpeed->setStepValue(SPEED_STEP);
164 mySpeed->setTickmarkIntervals(2);
165 wid.push_back(mySpeed);
166 ypos += lineHeight + VGAP;
167
168 // Use sync to vblank
169 myUseVSync = new CheckboxWidget(myTab, font, xpos, ypos + 1, "VSync");
170 wid.push_back(myUseVSync);
171
172 // Move over to the next column
173 xpos += mySpeed->getWidth() + 28;
174 ypos = VBORDER;
175
176 // Fullscreen
177 myFullscreen = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fullscreen", kFullScreenChanged);
178 wid.push_back(myFullscreen);
179 ypos += lineHeight + VGAP;
180
181 /*pwidth = font.getStringWidth("0: 3840x2860@120Hz");
182 myFullScreenMode = new PopUpWidget(myTab, font, xpos + INDENT + 2, ypos, pwidth, lineHeight,
183 instance().frameBuffer().supportedScreenModes(), "Mode ");
184 wid.push_back(myFullScreenMode);
185 ypos += lineHeight + VGAP;*/
186
187 // FS stretch
188 myUseStretch = new CheckboxWidget(myTab, font, xpos + INDENT, ypos + 1, "Stretch");
189 wid.push_back(myUseStretch);
190 ypos += lineHeight + VGAP;
191
192 // FS overscan
193 myTVOverscan = new SliderWidget(myTab, font, xpos + INDENT, ypos - 1, swidth, lineHeight,
194 "Overscan", font.getStringWidth("Overscan "), kOverscanChanged, fontWidth * 3, "%");
195 myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10);
196 myTVOverscan->setTickmarkIntervals(2);
197 wid.push_back(myTVOverscan);
198 ypos += (lineHeight + VGAP) * 2;
199
200 // Skip progress load bars for SuperCharger ROMs
201 // Doesn't really belong here, but I couldn't find a better place for it
202 myFastSCBios = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fast SuperCharger load");
203 wid.push_back(myFastSCBios);
204 ypos += lineHeight + VGAP;
205
206 // Show UI messages onscreen
207 myUIMessages = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Show UI messages");
208 wid.push_back(myUIMessages);
209 ypos += lineHeight + VGAP;
210
211 // Center window (in windowed mode)
212 myCenter = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Center window");
213 wid.push_back(myCenter);
214 ypos += (lineHeight + VGAP) * 2;
215
216 // Use multi-threading
217 myUseThreads = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Multi-threading");
218 wid.push_back(myUseThreads);
219
220 // Add items for tab 0
221 addToFocusList(wid, myTab, tabID);
222
223 //////////////////////////////////////////////////////////
224 // 2) TV effects options
225 wid.clear();
226 tabID = myTab->addTab(" TV Effects ");
227 xpos = HBORDER;
228 ypos = VBORDER;
229 swidth = font.getMaxCharWidth() * 8 - 4;
230
231 // TV Mode
232 items.clear();
233 VarList::push_back(items, "Disabled", static_cast<uInt32>(NTSCFilter::Preset::OFF));
234 VarList::push_back(items, "RGB", static_cast<uInt32>(NTSCFilter::Preset::RGB));
235 VarList::push_back(items, "S-Video", static_cast<uInt32>(NTSCFilter::Preset::SVIDEO));
236 VarList::push_back(items, "Composite", static_cast<uInt32>(NTSCFilter::Preset::COMPOSITE));
237 VarList::push_back(items, "Bad adjust", static_cast<uInt32>(NTSCFilter::Preset::BAD));
238 VarList::push_back(items, "Custom", static_cast<uInt32>(NTSCFilter::Preset::CUSTOM));
239 lwidth = font.getStringWidth("TV Mode ");
240 pwidth = font.getStringWidth("Bad adjust");
241 myTVMode =
242 new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
243 items, "TV mode ", lwidth, kTVModeChanged);
244 wid.push_back(myTVMode);
245 ypos += lineHeight + VGAP;
246
247 // Custom adjustables (using macro voodoo)
248 xpos += INDENT - 2; ypos += 0;
249 lwidth = font.getStringWidth("Saturation ");
250
251#define CREATE_CUSTOM_SLIDERS(obj, desc, cmd) \
252 myTV ## obj = \
253 new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight, \
254 desc, lwidth, cmd, fontWidth*4, "%"); \
255 myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \
256 myTV ## obj->setTickmarkIntervals(2); \
257 wid.push_back(myTV ## obj); \
258 ypos += lineHeight + VGAP;
259
260 CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", 0)
261 CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", 0)
262 CREATE_CUSTOM_SLIDERS(Hue, "Hue ", 0)
263 CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", 0)
264 CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", 0)
265 CREATE_CUSTOM_SLIDERS(Sharp, "Sharpness ", 0)
266 CREATE_CUSTOM_SLIDERS(Res, "Resolution ", 0)
267 CREATE_CUSTOM_SLIDERS(Artifacts, "Artifacts ", 0)
268 CREATE_CUSTOM_SLIDERS(Fringe, "Fringing ", 0)
269 CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ", 0)
270
271 xpos += myTVContrast->getWidth() + 30;
272 ypos = VBORDER;
273
274 lwidth = font.getStringWidth("Intensity ");
275
276 // TV Phosphor effect
277 myTVPhosphor = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Phosphor for all ROMs", kPhosphorChanged);
278 wid.push_back(myTVPhosphor);
279 ypos += lineHeight + VGAP / 2;
280
281 // TV Phosphor blend level
282 xpos += INDENT;
283 swidth = font.getMaxCharWidth() * 10;
284 CREATE_CUSTOM_SLIDERS(PhosLevel, "Blend ", kPhosBlendChanged)
285 ypos += 8;
286
287 // Scanline intensity and interpolation
288 xpos -= INDENT;
289 myTVScanLabel = new StaticTextWidget(myTab, font, xpos, ypos, "Scanlines:");
290 ypos += lineHeight + VGAP / 2;
291
292 xpos += INDENT;
293 CREATE_CUSTOM_SLIDERS(ScanIntense, "Intensity ", kScanlinesChanged)
294 ypos += lineHeight + 2;
295
296 // Adjustable presets
297 xpos -= INDENT;
298 int cloneWidth = font.getStringWidth("Clone Bad Adjust") + 20;
299#define CREATE_CLONE_BUTTON(obj, desc) \
300 myClone ## obj = \
301 new ButtonWidget(myTab, font, xpos, ypos, cloneWidth, buttonHeight,\
302 desc, kClone ## obj ##Cmd); \
303 wid.push_back(myClone ## obj); \
304 ypos += lineHeight + 4 + VGAP;
305
306 ypos += VGAP;
307 CREATE_CLONE_BUTTON(RGB, "Clone RGB")
308 CREATE_CLONE_BUTTON(Svideo, "Clone S-Video")
309 CREATE_CLONE_BUTTON(Composite, "Clone Composite")
310 CREATE_CLONE_BUTTON(Bad, "Clone Bad adjust")
311 CREATE_CLONE_BUTTON(Custom, "Revert")
312
313 // Add items for tab 2
314 addToFocusList(wid, myTab, tabID);
315
316 // Activate the first tab
317 myTab->setActiveTab(0);
318
319 // Add Defaults, OK and Cancel buttons
320 wid.clear();
321 addDefaultsOKCancelBGroup(wid, font);
322 addBGroupToFocusList(wid);
323
324 // Disable certain functions when we know they aren't present
325#ifndef WINDOWED_SUPPORT
326 myFullscreen->clearFlags(Widget::FLAG_ENABLED);
327 myCenter->clearFlags(Widget::FLAG_ENABLED);
328#endif
329}
330
331// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
332void VideoDialog::loadConfig()
333{
334 // Renderer settings
335 myRenderer->setSelected(instance().settings().getString("video"), "default");
336
337 // TIA zoom levels
338 // These are dynamically loaded, since they depend on the size of
339 // the desktop and which renderer we're using
340 float minZoom = instance().frameBuffer().supportedTIAMinZoom(); // or 2 if we allow lower values
341 float maxZoom = instance().frameBuffer().supportedTIAMaxZoom();
342
343 myTIAZoom->setMinValue(minZoom * 100);
344 myTIAZoom->setMaxValue(maxZoom * 100);
345 myTIAZoom->setTickmarkIntervals((maxZoom - minZoom) * 2); // every ~50%
346 myTIAZoom->setValue(instance().settings().getFloat("tia.zoom") * 100);
347
348 // TIA Palette
349 myTIAPalette->setSelected(
350 instance().settings().getString("palette"), "standard");
351
352 // TIA interpolation
353 myTIAInterpolate->setState(instance().settings().getBool("tia.inter"));
354
355 // Aspect ratio setting (NTSC and PAL)
356 myNAspectRatio->setValue(instance().settings().getInt("tia.aspectn"));
357 myPAspectRatio->setValue(instance().settings().getInt("tia.aspectp"));
358
359 // Emulation speed
360 int speed = mapSpeed(instance().settings().getFloat("speed"));
361 mySpeed->setValue(speed);
362 mySpeed->setValueLabel(formatSpeed(speed));
363
364 // Fullscreen
365 myFullscreen->setState(instance().settings().getBool("fullscreen"));
366 /*string mode = instance().settings().getString("fullscreenmode");
367 myFullScreenMode->setSelected(mode);*/
368 // Fullscreen stretch setting
369 myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
370 // Fullscreen overscan setting
371 myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
372 handleFullScreenChange();
373
374 // Use sync to vertical blank
375 myUseVSync->setState(instance().settings().getBool("vsync"));
376
377 // Show UI messages
378 myUIMessages->setState(instance().settings().getBool("uimessages"));
379
380 // Center window
381 myCenter->setState(instance().settings().getBool("center"));
382
383 // Fast loading of Supercharger BIOS
384 myFastSCBios->setState(instance().settings().getBool("fastscbios"));
385
386 // Multi-threaded rendering
387 myUseThreads->setState(instance().settings().getBool("threads"));
388
389 // TV Mode
390 myTVMode->setSelected(
391 instance().settings().getString("tv.filter"), "0");
392 int preset = instance().settings().getInt("tv.filter");
393 handleTVModeChange(NTSCFilter::Preset(preset));
394
395 // TV Custom adjustables
396 loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
397
398 // TV phosphor mode
399 myTVPhosphor->setState(instance().settings().getString("tv.phosphor") == "always");
400
401 // TV phosphor blend
402 myTVPhosLevel->setValue(instance().settings().getInt("tv.phosblend"));
403 handlePhosphorChange();
404
405 // TV scanline intensity and interpolation
406 myTVScanIntense->setValue(instance().settings().getInt("tv.scanlines"));
407
408 myTab->loadConfig();
409}
410
411// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
412void VideoDialog::saveConfig()
413{
414 // Renderer setting
415 instance().settings().setValue("video",
416 myRenderer->getSelectedTag().toString());
417
418 // TIA zoom levels
419 instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0);
420
421 // TIA Palette
422 instance().settings().setValue("palette",
423 myTIAPalette->getSelectedTag().toString());
424
425 // TIA interpolation
426 instance().settings().setValue("tia.inter", myTIAInterpolate->getState());
427
428 // Aspect ratio setting (NTSC and PAL)
429 instance().settings().setValue("tia.aspectn", myNAspectRatio->getValueLabel());
430 instance().settings().setValue("tia.aspectp", myPAspectRatio->getValueLabel());
431
432 // Speed
433 int speedup = mySpeed->getValue();
434 instance().settings().setValue("speed", unmapSpeed(speedup));
435 if (instance().hasConsole()) instance().console().initializeAudio();
436
437 // Fullscreen
438 instance().settings().setValue("fullscreen", myFullscreen->getState());
439 /*instance().settings().setValue("fullscreenmode",
440 myFullScreenMode->getSelectedTag().toString());*/
441 // Fullscreen stretch setting
442 instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
443 // Fullscreen overscan
444 instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
445
446 // Use sync to vertical blank
447 instance().settings().setValue("vsync", myUseVSync->getState());
448
449 // Show UI messages
450 instance().settings().setValue("uimessages", myUIMessages->getState());
451
452 // Center window
453 instance().settings().setValue("center", myCenter->getState());
454
455 // Fast loading of Supercharger BIOS
456 instance().settings().setValue("fastscbios", myFastSCBios->getState());
457
458 // Multi-threaded rendering
459 instance().settings().setValue("threads", myUseThreads->getState());
460 if(instance().hasConsole())
461 instance().frameBuffer().tiaSurface().ntsc().enableThreading(myUseThreads->getState());
462
463 // TV Mode
464 instance().settings().setValue("tv.filter",
465 myTVMode->getSelectedTag().toString());
466
467 // TV Custom adjustables
468 NTSCFilter::Adjustable adj;
469 adj.hue = myTVHue->getValue();
470 adj.saturation = myTVSatur->getValue();
471 adj.contrast = myTVContrast->getValue();
472 adj.brightness = myTVBright->getValue();
473 adj.sharpness = myTVSharp->getValue();
474 adj.gamma = myTVGamma->getValue();
475 adj.resolution = myTVRes->getValue();
476 adj.artifacts = myTVArtifacts->getValue();
477 adj.fringing = myTVFringe->getValue();
478 adj.bleed = myTVBleed->getValue();
479 instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(adj);
480
481 // TV phosphor mode
482 instance().settings().setValue("tv.phosphor",
483 myTVPhosphor->getState() ? "always" : "byrom");
484 // TV phosphor blend
485 instance().settings().setValue("tv.phosblend", myTVPhosLevel->getValueLabel());
486
487 // TV scanline intensity
488 instance().settings().setValue("tv.scanlines", myTVScanIntense->getValueLabel());
489
490 // Finally, issue a complete framebuffer re-initialization
491 instance().createFrameBuffer();
492}
493
494// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
495void VideoDialog::setDefaults()
496{
497 switch(myTab->getActiveTab())
498 {
499 case 0: // General
500 {
501 myRenderer->setSelectedIndex(0);
502 myTIAZoom->setValue(300);
503 myTIAPalette->setSelected("standard", "");
504 myTIAInterpolate->setState(false);
505 myNAspectRatio->setValue(91);
506 myPAspectRatio->setValue(109);
507 mySpeed->setValue(0);
508
509 myFullscreen->setState(false);
510 //myFullScreenMode->setSelectedIndex(0);
511 myUseStretch->setState(true);
512 myUseVSync->setState(true);
513 myUIMessages->setState(true);
514 myCenter->setState(false);
515 myFastSCBios->setState(true);
516 myUseThreads->setState(false);
517 break;
518 }
519
520 case 1: // TV effects
521 {
522 myTVMode->setSelected("0", "0");
523
524 // TV phosphor mode
525 myTVPhosphor->setState(false);
526
527 // TV phosphor blend
528 myTVPhosLevel->setValue(50);
529
530 // TV scanline intensity and interpolation
531 myTVScanIntense->setValue(25);
532
533 // Make sure that mutually-exclusive items are not enabled at the same time
534 handleTVModeChange(NTSCFilter::Preset::OFF);
535 handlePhosphorChange();
536 loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
537 break;
538 }
539 }
540}
541
542// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
543void VideoDialog::handleTVModeChange(NTSCFilter::Preset preset)
544{
545 bool enable = preset == NTSCFilter::Preset::CUSTOM;
546
547 myTVSharp->setEnabled(enable);
548 myTVHue->setEnabled(enable);
549 myTVRes->setEnabled(enable);
550 myTVArtifacts->setEnabled(enable);
551 myTVFringe->setEnabled(enable);
552 myTVBleed->setEnabled(enable);
553 myTVBright->setEnabled(enable);
554 myTVContrast->setEnabled(enable);
555 myTVSatur->setEnabled(enable);
556 myTVGamma->setEnabled(enable);
557 myCloneComposite->setEnabled(enable);
558 myCloneSvideo->setEnabled(enable);
559 myCloneRGB->setEnabled(enable);
560 myCloneBad->setEnabled(enable);
561 myCloneCustom->setEnabled(enable);
562}
563
564// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
565void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
566{
567 NTSCFilter::Adjustable adj;
568 instance().frameBuffer().tiaSurface().ntsc().getAdjustables(
569 adj, NTSCFilter::Preset(preset));
570 myTVSharp->setValue(adj.sharpness);
571 myTVHue->setValue(adj.hue);
572 myTVRes->setValue(adj.resolution);
573 myTVArtifacts->setValue(adj.artifacts);
574 myTVFringe->setValue(adj.fringing);
575 myTVBleed->setValue(adj.bleed);
576 myTVBright->setValue(adj.brightness);
577 myTVContrast->setValue(adj.contrast);
578 myTVSatur->setValue(adj.saturation);
579 myTVGamma->setValue(adj.gamma);
580}
581
582// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
583void VideoDialog::handleFullScreenChange()
584{
585 bool enable = myFullscreen->getState();
586 myUseStretch->setEnabled(enable);
587 myTVOverscan->setEnabled(enable);
588}
589
590// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
591void VideoDialog::handleOverscanChange()
592{
593 if (myTVOverscan->getValue() == 0)
594 {
595 myTVOverscan->setValueLabel("Off");
596 myTVOverscan->setValueUnit("");
597 }
598 else
599 myTVOverscan->setValueUnit("%");
600}
601
602// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
603void VideoDialog::handlePhosphorChange()
604{
605 myTVPhosLevel->setEnabled(myTVPhosphor->getState());
606}
607
608// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
609void VideoDialog::handleCommand(CommandSender* sender, int cmd,
610 int data, int id)
611{
612 switch (cmd)
613 {
614 case GuiObject::kOKCmd:
615 saveConfig();
616 close();
617 break;
618
619 case GuiObject::kDefaultsCmd:
620 setDefaults();
621 break;
622
623 case kSpeedupChanged:
624 mySpeed->setValueLabel(formatSpeed(mySpeed->getValue()));
625 break;
626
627 case kFullScreenChanged:
628 handleFullScreenChange();
629 break;
630
631 case kOverscanChanged:
632 handleOverscanChange();
633 break;
634
635 case kTVModeChanged:
636 handleTVModeChange(NTSCFilter::Preset(myTVMode->getSelectedTag().toInt()));
637 break;
638
639 case kCloneCompositeCmd: loadTVAdjustables(NTSCFilter::Preset::COMPOSITE);
640 break;
641 case kCloneSvideoCmd: loadTVAdjustables(NTSCFilter::Preset::SVIDEO);
642 break;
643 case kCloneRGBCmd: loadTVAdjustables(NTSCFilter::Preset::RGB);
644 break;
645 case kCloneBadCmd: loadTVAdjustables(NTSCFilter::Preset::BAD);
646 break;
647 case kCloneCustomCmd: loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
648 break;
649
650 case kScanlinesChanged:
651 if (myTVScanIntense->getValue() == 0)
652 {
653 myTVScanIntense->setValueLabel("Off");
654 myTVScanIntense->setValueUnit("");
655 }
656 else
657 myTVScanIntense->setValueUnit("%");
658 break;
659
660 case kPhosphorChanged:
661 handlePhosphorChange();
662 break;
663
664 case kPhosBlendChanged:
665 if (myTVPhosLevel->getValue() == 0)
666 {
667 myTVPhosLevel->setValueLabel("Off");
668 myTVPhosLevel->setValueUnit("");
669 }
670 else
671 myTVPhosLevel->setValueUnit("%");
672 break;
673
674 default:
675 Dialog::handleCommand(sender, cmd, data, 0);
676 break;
677 }
678}
679