#include // MT. struct Settings : Markup::Node { using string = nall::string; auto load() -> void; auto save() -> void; auto process(bool load) -> void; string location; struct Video { string driver; bool exclusive = false; bool blocking = true; // Changed from `false` by MT. bool flush = false; string monitor = "Primary"; string format = "Default"; string shader = "None"; // Changed from "Blur" by MT. uint luminance = 100; uint saturation = 100; uint gamma = 150; bool dimming = true; bool snow = false; string output = "Pixel-Perfect"; // Changed from "Scale" by MT. uint multiplier = 2; bool aspectCorrection = true; bool parInsteadOfAr = false; // MT. bool overscan = false; bool scalingInfo = false; // MT. bool blur = false; string filter = "None"; } video; struct Audio { string driver; bool exclusive = false; string device; bool blocking = true; bool dynamic = false; uint frequency = 48000; uint latency = 0; bool mute = false; bool muteUnfocused = false; int skew = 0; uint volume = 100; uint balance = 50; } audio; struct Input { string driver; uint frequency = 5; string defocus = "Pause"; struct Turbo { uint frequency = 4; } turbo; struct Hotkey { string logic = "or"; } hotkey; } input; /* MT. */ struct BuiltinHotkeys { bool openGame_CtrlO = true; bool closeGame_CtrlW = true; bool closeGame_CtrlF4 = true; bool fullScreen_F11 = true; bool fullScreen_AltEnter = true; bool pseudoFullScreen_ShiftEnter = true; bool takeScreenshot_PrintScreen = true; bool takeScreenshot_F9 = true; bool resetEmulation_F5 = true; bool pauseEmulation_PauseBreak = true; } builtinHotkeys; /* /MT. */ struct Path { string games; string patches; string saves; string cheats; string states; string screenshots; struct Recent { string superFamicom; string gameBoy; string bsMemory; string sufamiTurboA; string sufamiTurboB; } recent; } path; struct FastForward { uint frameSkip = 9; uint limiter = 0; bool mute = false; } fastForward; struct Rewind { uint frequency = 0; uint length = 80; bool mute = false; } rewind; struct Emulator { bool warnOnUnverifiedGames = false; struct AutoSaveMemory { bool enable = true; uint interval = 30; } autoSaveMemory; bool autoSaveStateOnUnload = false; bool autoLoadStateOnLoad = false; struct Serialization { string method = "Fast"; } serialization; struct RunAhead { uint frames = 0; } runAhead; struct Hack { bool hotfixes = true; string entropy = "Low"; struct CPU { uint overclock = 100; bool fastMath = false; } cpu; struct PPU { bool fast = true; bool deinterlace = true; bool noSpriteLimit = false; bool noVRAMBlocking = false; struct Mode7 { uint scale = 1; bool perspective = true; bool supersample = false; bool mosaic = true; } mode7; } ppu; struct DSP { bool fast = true; bool cubic = false; bool echoShadow = false; } dsp; struct Coprocessor { bool delayedSync = true; bool preferHLE = false; } coprocessor; struct SA1 { uint overclock = 100; } sa1; struct SuperFX { uint overclock = 100; } superfx; } hack; struct Cheats { bool enable = true; } cheats; } emulator; struct General { bool statusBar = true; bool screenSaver = false; bool toolTips = true; bool crashed = false; bool nativeFileDialogs = true; // Changed from `false` by MT. } general; }; struct VideoSettings : VerticalLayout { auto create() -> void; private: Label colorAdjustmentLabel{this, Size{~0, 0}, 2}; TableLayout colorLayout{this, Size{~0, 0}}; Label luminanceLabel{&colorLayout, Size{0, 0}}; Label luminanceValue{&colorLayout, Size{50_sx, 0}}; HorizontalSlider luminanceSlider{&colorLayout, Size{~0, 0}}; // Label saturationLabel{&colorLayout, Size{0, 0}}; Label saturationValue{&colorLayout, Size{50_sx, 0}}; HorizontalSlider saturationSlider{&colorLayout, Size{~0, 0}}; // Label gammaLabel{&colorLayout, Size{0, 0}}; Label gammaValue{&colorLayout, Size{50_sx, 0}}; HorizontalSlider gammaSlider{&colorLayout, Size{~0, 0}}; // CheckLabel dimmingOption{this, Size{~0, 0}}; CheckLabel snowOption{this, Size{~0, 0}}; }; struct AudioSettings : VerticalLayout { auto create() -> void; private: Label effectsLabel{this, Size{~0, 0}, 2}; TableLayout effectsLayout{this, Size{~0, 0}}; Label skewLabel{&effectsLayout, Size{0, 0}}; Label skewValue{&effectsLayout, Size{50_sx, 0}}; HorizontalSlider skewSlider{&effectsLayout, Size{~0, 0}}; // Label volumeLabel{&effectsLayout, Size{0, 0}}; Label volumeValue{&effectsLayout, Size{50_sx, 0}}; HorizontalSlider volumeSlider{&effectsLayout, Size{~0, 0}}; // Label balanceLabel{&effectsLayout, Size{0, 0}}; Label balanceValue{&effectsLayout, Size{50_sx, 0}}; HorizontalSlider balanceSlider{&effectsLayout, Size{~0, 0}}; // CheckLabel muteUnfocused{this, Size{~0, 0}}; }; struct InputSettings : VerticalLayout { auto create() -> void; auto updateControls() -> void; auto activePort() -> InputPort&; auto activeDevice() -> InputDevice&; auto reloadPorts() -> void; auto reloadDevices() -> void; auto reloadMappings() -> void; auto refreshMappings() -> void; auto assignMapping(TableViewCell cell) -> void; auto cancelMapping() -> void; auto assignMouseInput(uint id) -> void; auto inputEvent(shared_pointer device, uint group, uint input, int16 oldValue, int16 newValue, bool allowMouseInput = false) -> void; maybe activeMapping; uint activeBinding = 0; public: Timer timer; HorizontalLayout selectionLayout{this, Size{~0, 0}}; Label portLabel{&selectionLayout, Size{0, 0}}; ComboButton portList{&selectionLayout, Size{~0, 0}}; Label deviceLabel{&selectionLayout, Size{0, 0}}; ComboButton deviceList{&selectionLayout, Size{~0, 0}}; Label turboLabel{&selectionLayout, Size{0, 0}}; ComboButton turboList{&selectionLayout, Size{0, 0}}; TableView mappingList{this, Size{~0, ~0}}; HorizontalLayout controlLayout{this, Size{~0, 0}}; Button assignMouse1{&controlLayout, Size{120_sx, 0}}; // `100_sx` => `120_sx` by MT. Button assignMouse2{&controlLayout, Size{120_sx, 0}}; // `100_sx` => `120_sx` by MT. Button assignMouse3{&controlLayout, Size{120_sx, 0}}; // `100_sx` => `120_sx` by MT. Canvas inputSink{&controlLayout, Size{~0, ~0}}; Button assignButton{&controlLayout, Size{80_sx, 0}}; Button clearButton{&controlLayout, Size{80_sx, 0}}; Canvas separator{this, Size{~0, 1}}; HorizontalLayout inputFocusLayout{this, Size{~0, 0}}; Label inputFocusLabel{&inputFocusLayout, Size{0, 0}}; HorizontalLayout inputFocusRadioLayout{this, Size{~0, 0}}; // MT. RadioLabel pauseEmulation{&inputFocusRadioLayout, Size{0, 0}}; RadioLabel blockInput{&inputFocusRadioLayout, Size{0, 0}}; RadioLabel allowInput{&inputFocusRadioLayout, Size{0, 0}}; Group inputFocusGroup{&pauseEmulation, &blockInput, &allowInput}; }; struct HotkeySettings : VerticalLayout { auto create() -> void; auto reloadMappings() -> void; auto refreshMappings() -> void; auto assignMapping(TableViewCell cell) -> void; auto cancelMapping() -> void; auto inputEvent(shared_pointer device, uint group, uint input, int16 oldValue, int16 newValue) -> void; maybe activeMapping; uint activeBinding = 0; private: Timer timer; TableView mappingList{this, Size{~0, ~0}}; HorizontalLayout controlLayout{this, Size{~0, 0}}; Label logicLabel{&controlLayout, Size{0, 0}}; RadioLabel logicAND{&controlLayout, Size{0, 0}}; RadioLabel logicOR{&controlLayout, Size{0, 0}}; Group logicGroup{&logicAND, &logicOR}; Canvas inputSink{&controlLayout, Size{~0, ~0}}; Button assignButton{&controlLayout, Size{80_sx, 0}}; Button clearButton{&controlLayout, Size{80_sx, 0}}; }; /* MT. */ struct BuiltinHotkeysSettings : VerticalLayout { auto create() -> void; public: CheckLabel openGame_CtrlO{this, Size{~0, 0}}; CheckLabel closeGame_CtrlW{this, Size{~0, 0}}; CheckLabel closeGame_CtrlF4{this, Size{~0, 0}}; CheckLabel fullScreen_F11{this, Size{~0, 0}}; CheckLabel fullScreen_AltEnter{this, Size{~0, 0}}; CheckLabel pseudoFullScreen_ShiftEnter{this, Size{~0, 0}}; CheckLabel takeScreenshot_F9{this, Size{~0, 0}}; CheckLabel takeScreenshot_PrintScreen{this, Size{~0, 0}}; CheckLabel resetEmulation_F5{this, Size{~0, 0}}; CheckLabel pauseEmulation_PauseBreak{this, Size{~0, 0}}; HorizontalLayout checkUncheckAllLayout{this, Size{~0, 0}}; Button checkAll{&checkUncheckAllLayout, Size{0, 0}}; Button uncheckAll{&checkUncheckAllLayout, Size{0, 0}}; protected: std::vector labels = { openGame_CtrlO, closeGame_CtrlW, closeGame_CtrlF4, fullScreen_F11, fullScreen_AltEnter, pseudoFullScreen_ShiftEnter, takeScreenshot_F9, takeScreenshot_PrintScreen, resetEmulation_F5, pauseEmulation_PauseBreak }; auto allChecked() -> bool; auto allUnchecked() -> bool; auto enableDisableButtons() -> void; }; /* /MT. */ struct PathSettings : VerticalLayout { auto create() -> void; auto refreshPaths() -> void; public: TableLayout layout{this, Size{~0, ~0}}; Label gamesLabel{&layout, Size{0, 0}}; LineEdit gamesPath{&layout, Size{~0, 0}}; Button gamesAssign{&layout, Size{80_sx, 0}}; Button gamesReset{&layout, Size{80_sx, 0}}; // Label patchesLabel{&layout, Size{0, 0}}; LineEdit patchesPath{&layout, Size{~0, 0}}; Button patchesAssign{&layout, Size{80_sx, 0}}; Button patchesReset{&layout, Size{80_sx, 0}}; // Label savesLabel{&layout, Size{0, 0}}; LineEdit savesPath{&layout, Size{~0, 0}}; Button savesAssign{&layout, Size{80_sx, 0}}; Button savesReset{&layout, Size{80_sx, 0}}; // Label cheatsLabel{&layout, Size{0, 0}}; LineEdit cheatsPath{&layout, Size{~0, 0}}; Button cheatsAssign{&layout, Size{80_sx, 0}}; Button cheatsReset{&layout, Size{80_sx, 0}}; // Label statesLabel{&layout, Size{0, 0}}; LineEdit statesPath{&layout, Size{~0, 0}}; Button statesAssign{&layout, Size{80_sx, 0}}; Button statesReset{&layout, Size{80_sx, 0}}; // Label screenshotsLabel{&layout, Size{0, 0}}; LineEdit screenshotsPath{&layout, Size{~0, 0}}; Button screenshotsAssign{&layout, Size{80_sx, 0}}; Button screenshotsReset{&layout, Size{80_sx, 0}}; }; struct EmulatorSettings : VerticalLayout { auto create() -> void; public: Label optionsLabel{this, Size{~0, 0}, 2}; CheckLabel warnOnUnverifiedGames{this, Size{~0, 0}, 2}; CheckLabel autoSaveMemory{this, Size{~0, 0}, 2}; HorizontalLayout autoStateLayout{this, Size{~0, 0}, 2}; CheckLabel autoSaveStateOnUnload{&autoStateLayout, Size{0, 0}}; CheckLabel autoLoadStateOnLoad{&autoStateLayout, Size{0, 0}}; CheckLabel nativeFileDialogs{this, Size{~0, 0}}; Canvas optionsSpacer{this, Size{~0, 1}}; // Label fastForwardLabel{this, Size{~0, 0}, 2}; HorizontalLayout fastForwardLayout{this, Size{~0, 0}}; Label frameSkipLabel{&fastForwardLayout, Size{0, 0}}; ComboButton frameSkipAmount{&fastForwardLayout, Size{0, 0}}; Label limiterLabel{&fastForwardLayout, Size{0, 0}}; ComboButton limiterAmount{&fastForwardLayout, Size{0, 0}}; CheckLabel fastForwardMute{this, Size{0, 0}}; Canvas fastForwardSpacer{this, Size{~0, 1}}; // Label rewindLabel{this, Size{~0, 0}, 2}; HorizontalLayout rewindLayout{this, Size{~0, 0}}; Label rewindFrequencyLabel{&rewindLayout, Size{0, 0}}; ComboButton rewindFrequencyOption{&rewindLayout, Size{0, 0}}; Label rewindLengthLabel{&rewindLayout, Size{0, 0}}; ComboButton rewindLengthOption{&rewindLayout, Size{0, 0}}; CheckLabel rewindMute{this, Size{0, 0}}; }; struct EnhancementSettings : VerticalLayout { auto create() -> void; public: Label runAheadLabel{this, Size{~0, 0}, 2}; HorizontalLayout runAheadLayout{this, Size{~0, 0}}; RadioLabel runAhead0{&runAheadLayout, Size{0, 0}}; RadioLabel runAhead1{&runAheadLayout, Size{0, 0}}; RadioLabel runAhead2{&runAheadLayout, Size{0, 0}}; RadioLabel runAhead3{&runAheadLayout, Size{0, 0}}; RadioLabel runAhead4{&runAheadLayout, Size{0, 0}}; Group runAheadGroup{&runAhead0, &runAhead1, &runAhead2, &runAhead3, &runAhead4}; Canvas runAheadSpacer{this, Size{~0, 1}}; // Label overclockingLabel{this, Size{~0, 0}, 2}; TableLayout overclockingLayout{this, Size{~0, 0}}; Label cpuLabel{&overclockingLayout, Size{0, 0}}; Label cpuValue{&overclockingLayout, Size{50_sx, 0}}; HorizontalSlider cpuClock{&overclockingLayout, Size{~0, 0}}; Canvas overclockingSpacer{this, Size{~0, 1}}; // Label sa1Label{&overclockingLayout, Size{0, 0}}; Label sa1Value{&overclockingLayout, Size{50_sx, 0}}; HorizontalSlider sa1Clock{&overclockingLayout, Size{~0, 0}}; // Label sfxLabel{&overclockingLayout, Size{0, 0}}; Label sfxValue{&overclockingLayout, Size{50_sx, 0}}; HorizontalSlider sfxClock{&overclockingLayout, Size{~0, 0}}; // Label ppuLabel{this, Size{~0, 0}, 2}; HorizontalLayout ppuLayout{this, Size{~0, 0}}; CheckLabel fastPPU{&ppuLayout, Size{0, 0}}; CheckLabel deinterlace{&ppuLayout, Size{0, 0}}; CheckLabel noSpriteLimit{&ppuLayout, Size{0, 0}}; // Label mode7Label{this, Size{~0, 0}, 2}; HorizontalLayout mode7Layout{this, Size{~0, 0}}; Label mode7ScaleLabel{&mode7Layout, Size{0, 0}}; ComboButton mode7Scale{&mode7Layout, Size{0, 0}}; CheckLabel mode7Perspective{&mode7Layout, Size{0, 0}}; CheckLabel mode7Supersample{&mode7Layout, Size{0, 0}}; CheckLabel mode7Mosaic{&mode7Layout, Size{0, 0}}; // Label dspLabel{this, Size{~0, 0}, 2}; HorizontalLayout dspLayout{this, Size{~0, 0}}; CheckLabel fastDSP{&dspLayout, Size{0, 0}}; CheckLabel cubicInterpolation{&dspLayout, Size{0, 0}}; // Label coprocessorLabel{this, Size{~0, 0}, 2}; HorizontalLayout coprocessorLayout{this, Size{~0, 0}}; CheckLabel coprocessorDelayedSyncOption{&coprocessorLayout, Size{0, 0}}; CheckLabel coprocessorPreferHLEOption{&coprocessorLayout, Size{0, 0}}; Canvas coprocessorSpacer{this, Size{~0, 1}}; // Label gameLabel{this, Size{~0, 0}, 2}; CheckLabel hotfixes{this, Size{0, 0}}; // Widget spacer{this, Size{~0, ~0}}; Label note{this, Size{~0, 0}}; }; struct CompatibilitySettings : VerticalLayout { auto create() -> void; private: Label entropyLabel{this, Size{~0, 0}, 2}; HorizontalLayout entropyLayout{this, Size{~0, 0}}; RadioLabel entropyNone{&entropyLayout, Size{0, 0}}; RadioLabel entropyLow{&entropyLayout, Size{0, 0}}; RadioLabel entropyHigh{&entropyLayout, Size{0, 0}}; Group entropyGroup{&entropyNone, &entropyLow, &entropyHigh}; // Label cpuLabel{this, Size{~0, 0}, 2}; CheckLabel fastMath{this, Size{0, 0}}; // Label ppuLabel{this, Size{~0, 0}, 2}; CheckLabel noVRAMBlocking{this, Size{0, 0}}; // Label dspLabel{this, Size{~0, 0}, 2}; CheckLabel echoShadow{this, Size{0, 0}}; // Widget spacer{this, Size{~0, ~0}}; Label note{this, Size{~0, 0}}; }; struct DriverSettings : VerticalLayout { auto create() -> void; auto videoDriverChanged() -> void; auto videoDriverChange() -> void; auto videoMonitorChanged() -> void; auto videoMonitorChange() -> void; auto videoFormatChanged() -> void; auto videoFormatChange() -> void; auto audioDriverChanged() -> void; auto audioDriverChange() -> void; auto audioDeviceChanged() -> void; auto audioDeviceChange() -> void; auto audioFrequencyChanged() -> void; auto audioFrequencyChange() -> void; auto audioLatencyChanged() -> void; auto audioLatencyChange() -> void; auto inputDriverChanged() -> void; auto inputDriverChange() -> void; public: Label videoLabel{this, Size{~0, 0}, 2}; VerticalLayout videoLayout{this, Size{~0, 0}}; HorizontalLayout videoDriverLayout{&videoLayout, Size{~0, 0}}; Label videoDriverLabel{&videoDriverLayout, Size{0, 0}}; ComboButton videoDriverOption{&videoDriverLayout, Size{0, 0}}; Button videoDriverUpdate{&videoDriverLayout, Size{0, 0}}; Label videoDriverActive{&videoDriverLayout, Size{0, 0}}; HorizontalLayout videoPropertyLayout{&videoLayout, Size{~0, 0}}; Label videoMonitorLabel{&videoPropertyLayout, Size{0, 0}}; ComboButton videoMonitorOption{&videoPropertyLayout, Size{0, 0}}; Label videoFormatLabel{&videoPropertyLayout, Size{0, 0}}; ComboButton videoFormatOption{&videoPropertyLayout, Size{0, 0}}; HorizontalLayout videoToggleLayout{this, Size{~0, 0}}; CheckLabel videoExclusiveToggle{&videoToggleLayout, Size{0, 0}}; CheckLabel videoBlockingToggle{&videoToggleLayout, Size{0, 0}}; CheckLabel videoFlushToggle{&videoToggleLayout, Size{0, 0}}; Canvas videoSpacer{this, Size{~0, 1}}; // Label audioLabel{this, Size{~0, 0}, 2}; VerticalLayout audioLayout{this, Size{~0, 0}}; HorizontalLayout audioDriverLayout{&audioLayout, Size{~0, 0}}; Label audioDriverLabel{&audioDriverLayout, Size{0, 0}}; ComboButton audioDriverOption{&audioDriverLayout, Size{0, 0}}; Button audioDriverUpdate{&audioDriverLayout, Size{0, 0}}; Label audioDriverActive{&audioDriverLayout, Size{0, 0}}; HorizontalLayout audioPropertyLayout{&audioLayout, Size{~0, 0}}; Label audioDeviceLabel{&audioPropertyLayout, Size{0, 0}}; ComboButton audioDeviceOption{&audioPropertyLayout, Size{0, 0}}; HorizontalLayout audioSampleRateAndLatencyLayout{&audioLayout, Size{~0, 0}}; // MT. Label audioSampleRateLabel{&audioSampleRateAndLatencyLayout, Size{0, 0}}; ComboButton audioSampleRateOption{&audioSampleRateAndLatencyLayout, Size{0, 0}}; Label audioLatencyLabel{&audioSampleRateAndLatencyLayout, Size{0, 0}}; ComboButton audioLatencyOption{&audioSampleRateAndLatencyLayout, Size{0, 0}}; HorizontalLayout audioToggleLayout{this, Size{~0, 0}}; CheckLabel audioExclusiveToggle{&audioToggleLayout, Size{0, 0}}; CheckLabel audioBlockingToggle{&audioToggleLayout, Size{0, 0}}; CheckLabel audioDynamicToggle{&audioToggleLayout, Size{0, 0}}; Canvas audioSpacer{this, Size{~0, 1}}; // Label inputLabel{this, Size{~0, 0}, 2}; VerticalLayout inputLayout{this, Size{~0, 0}}; HorizontalLayout inputDriverLayout{&inputLayout, Size{~0, 0}}; Label inputDriverLabel{&inputDriverLayout, Size{0, 0}}; ComboButton inputDriverOption{&inputDriverLayout, Size{0, 0}}; Button inputDriverUpdate{&inputDriverLayout, Size{0, 0}}; Label inputDriverActive{&inputDriverLayout, Size{0, 0}}; Canvas inputSpacer{this, Size{~0, 1}}; // Widget spacer{this, Size{~0, ~0}, 0}; Label syncModeLabel{this, Size{~0, 0}, 0}; Label syncModeRequirements{this, Size{~0, 0}}; HorizontalLayout modeLayout{this, Size{~0, 0}}; Button adaptiveSyncMode{&modeLayout, Size{0, 0}}; Button dynamicRateControlMode{&modeLayout, Size{0, 0}}; }; struct SettingsWindow : Window, Lock { auto create() -> void; auto setVisible(bool visible = true) -> SettingsWindow&; auto show(int index) -> void; public: VerticalLayout layout{this}; HorizontalLayout panelLayout{&layout, Size{~0, ~0}}; ListView panelList{&panelLayout, Size{190_sx, ~0}}; // `125_sx` => `190_sx` by MT. VerticalLayout panelContainer{&panelLayout, Size{~0, ~0}}; StatusBar statusBar{this}; }; extern Settings settings; extern VideoSettings videoSettings; extern AudioSettings audioSettings; extern InputSettings inputSettings; extern HotkeySettings hotkeySettings; extern BuiltinHotkeysSettings builtinHotkeysSettings; // MT. extern PathSettings pathSettings; extern EmulatorSettings emulatorSettings; extern EnhancementSettings enhancementSettings; extern CompatibilitySettings compatibilitySettings; extern DriverSettings driverSettings; namespace Instances { extern Instance settingsWindow; } extern SettingsWindow& settingsWindow;