#include "../bsnes.hpp" #include "video.cpp" #include "audio.cpp" #include "input.cpp" #include "hotkeys.cpp" #include "paths.cpp" #include "emulator.cpp" #include "enhancements.cpp" #include "compatibility.cpp" #include "drivers.cpp" Settings settings; VideoSettings videoSettings; AudioSettings audioSettings; InputSettings inputSettings; HotkeySettings hotkeySettings; PathSettings pathSettings; EmulatorSettings emulatorSettings; EnhancementSettings enhancementSettings; CompatibilitySettings compatibilitySettings; DriverSettings driverSettings; namespace Instances { Instance settingsWindow; } SettingsWindow& settingsWindow = Instances::settingsWindow(); auto Settings::load() -> void { Markup::Node::operator=(BML::unserialize(string::read(location), " ")); process(true); file::write(locate("settings.bml"), BML::serialize(*this, " ")); } auto Settings::save() -> void { process(false); file::write(location ? location : locate("settings.bml"), BML::serialize(*this, " ")); } auto Settings::process(bool load) -> void { if(load) { //initialize non-static default settings video.driver = ruby::Video::safestDriver(); audio.driver = ruby::Audio::safestDriver(); input.driver = ruby::Input::safestDriver(); } #define bind(type, path, name) \ if(load) { \ if(auto node = operator[](path)) name = node.type(); \ } else { \ operator()(path).setValue(name); \ } \ bind(text, "Video/Driver", video.driver); bind(boolean, "Video/Exclusive", video.exclusive); bind(boolean, "Video/Blocking", video.blocking); bind(boolean, "Video/Flush", video.flush); bind(text, "Video/Monitor", video.monitor); bind(text, "Video/Format", video.format); bind(text, "Video/Shader", video.shader); bind(natural, "Video/Luminance", video.luminance); bind(natural, "Video/Saturation", video.saturation); bind(natural, "Video/Gamma", video.gamma); bind(boolean, "Video/Dimming", video.dimming); bind(boolean, "Video/Snow", video.snow); bind(text, "Video/Output", video.output); bind(natural, "Video/Multiplier", video.multiplier); bind(boolean, "Video/AspectCorrection", video.aspectCorrection); bind(boolean, "Video/Overscan", video.overscan); bind(boolean, "Video/Blur", video.blur); bind(text, "Video/Filter", video.filter); bind(text, "Audio/Driver", audio.driver); bind(boolean, "Audio/Exclusive", audio.exclusive); bind(text, "Audio/Device", audio.device); bind(boolean, "Audio/Blocking", audio.blocking); bind(boolean, "Audio/Dynamic", audio.dynamic); bind(natural, "Audio/Frequency", audio.frequency); bind(natural, "Audio/Latency", audio.latency); bind(boolean, "Audio/Mute", audio.mute); bind(boolean, "Audio/MuteUnfocused", audio.muteUnfocused); bind(integer, "Audio/Skew", audio.skew); bind(natural, "Audio/Volume", audio.volume); bind(natural, "Audio/Balance", audio.balance); bind(text, "Input/Driver", input.driver); bind(natural, "Input/Frequency", input.frequency); bind(text, "Input/Defocus", input.defocus); bind(natural, "Input/Turbo/Frequency", input.turbo.frequency); bind(text, "Input/Hotkey/Logic", input.hotkey.logic); bind(text, "Path/Games", path.games); bind(text, "Path/Patches", path.patches); bind(text, "Path/Saves", path.saves); bind(text, "Path/Cheats", path.cheats); bind(text, "Path/States", path.states); bind(text, "Path/Screenshots", path.screenshots); bind(text, "Path/Recent/SuperFamicom", path.recent.superFamicom); bind(text, "Path/Recent/GameBoy", path.recent.gameBoy); bind(text, "Path/Recent/BSMemory", path.recent.bsMemory); bind(text, "Path/Recent/SufamiTurboA", path.recent.sufamiTurboA); bind(text, "Path/Recent/SufamiTurboB", path.recent.sufamiTurboB); bind(natural, "FastForward/FrameSkip", fastForward.frameSkip); bind(natural, "FastForward/Limiter", fastForward.limiter); bind(boolean, "FastForward/Mute", fastForward.mute); bind(natural, "Rewind/Frequency", rewind.frequency); bind(natural, "Rewind/Length", rewind.length); bind(boolean, "Rewind/Mute", rewind.mute); bind(boolean, "Emulator/WarnOnUnverifiedGames", emulator.warnOnUnverifiedGames); bind(boolean, "Emulator/AutoSaveMemory/Enable", emulator.autoSaveMemory.enable); bind(natural, "Emulator/AutoSaveMemory/Interval", emulator.autoSaveMemory.interval); bind(boolean, "Emulator/AutoSaveStateOnUnload", emulator.autoSaveStateOnUnload); bind(boolean, "Emulator/AutoLoadStateOnLoad", emulator.autoLoadStateOnLoad); bind(text, "Emulator/Serialization/Method", emulator.serialization.method); bind(natural, "Emulator/RunAhead/Frames", emulator.runAhead.frames); bind(boolean, "Emulator/Hack/Hotfixes", emulator.hack.hotfixes); bind(text, "Emulator/Hack/Entropy", emulator.hack.entropy); bind(natural, "Emulator/Hack/CPU/Overclock", emulator.hack.cpu.overclock); bind(boolean, "Emulator/Hack/CPU/FastMath", emulator.hack.cpu.fastMath); bind(boolean, "Emulator/Hack/PPU/Fast", emulator.hack.ppu.fast); bind(boolean, "Emulator/Hack/PPU/Deinterlace", emulator.hack.ppu.deinterlace); bind(boolean, "Emulator/Hack/PPU/NoSpriteLimit", emulator.hack.ppu.noSpriteLimit); bind(boolean, "Emulator/Hack/PPU/NoVRAMBlocking", emulator.hack.ppu.noVRAMBlocking); bind(natural, "Emulator/Hack/PPU/Mode7/Scale", emulator.hack.ppu.mode7.scale); bind(natural, "Emulator/Hack/PPU/Mode7/Perspective", emulator.hack.ppu.mode7.perspective); bind(natural, "Emulator/Hack/PPU/Mode7/Widescreen", emulator.hack.ppu.mode7.widescreen); bind(natural, "Emulator/Hack/PPU/Mode7/Wsbg1", emulator.hack.ppu.mode7.wsbg1); bind(natural, "Emulator/Hack/PPU/Mode7/Wsbg2", emulator.hack.ppu.mode7.wsbg2); bind(natural, "Emulator/Hack/PPU/Mode7/Wsbg3", emulator.hack.ppu.mode7.wsbg3); bind(natural, "Emulator/Hack/PPU/Mode7/Wsbg4", emulator.hack.ppu.mode7.wsbg4); bind(natural, "Emulator/Hack/PPU/Mode7/Wsobj", emulator.hack.ppu.mode7.wsobj); bind(natural, "Emulator/Hack/PPU/Mode7/Igwin", emulator.hack.ppu.mode7.igwin); bind(natural, "Emulator/Hack/PPU/Mode7/Igwinx", emulator.hack.ppu.mode7.igwinx); bind(natural, "Emulator/Hack/PPU/Mode7/BgGrad", emulator.hack.ppu.mode7.bgGrad); bind(natural, "Emulator/Hack/PPU/Mode7/WindRad", emulator.hack.ppu.mode7.windRad); bind(natural, "Emulator/Hack/PPU/Mode7/WsMode", emulator.hack.ppu.mode7.wsMode); bind(natural, "Emulator/Hack/PPU/Mode7/WsBgCol", emulator.hack.ppu.mode7.wsBgCol); bind(natural, "Emulator/Hack/PPU/Mode7/WsMarker", emulator.hack.ppu.mode7.wsMarker); bind(natural, "Emulator/Hack/PPU/Mode7/WsMarkerAlpha", emulator.hack.ppu.mode7.wsMarkerAlpha); bind(natural, "Emulator/Hack/PPU/Mode7/Supersample", emulator.hack.ppu.mode7.supersample); bind(natural, "Emulator/Hack/PPU/Mode7/Mosaic", emulator.hack.ppu.mode7.mosaic); bind(boolean, "Emulator/Hack/DSP/Fast", emulator.hack.dsp.fast); bind(boolean, "Emulator/Hack/DSP/Cubic", emulator.hack.dsp.cubic); bind(boolean, "Emulator/Hack/DSP/EchoShadow", emulator.hack.dsp.echoShadow); bind(boolean, "Emulator/Hack/Coprocessor/DelayedSync", emulator.hack.coprocessor.delayedSync); bind(boolean, "Emulator/Hack/Coprocessor/PreferHLE", emulator.hack.coprocessor.preferHLE); bind(natural, "Emulator/Hack/SA1/Overclock", emulator.hack.sa1.overclock); bind(natural, "Emulator/Hack/SuperFX/Overclock", emulator.hack.superfx.overclock); bind(boolean, "Emulator/Cheats/Enable", emulator.cheats.enable); bind(boolean, "General/StatusBar", general.statusBar); bind(boolean, "General/ScreenSaver", general.screenSaver); bind(boolean, "General/ToolTips", general.toolTips); bind(boolean, "General/Crashed", general.crashed); bind(boolean, "General/BetaWarning", general.betaWarning); #undef bind } struct SettingsHome : VerticalLayout { SettingsHome() { setCollapsible(); setVisible(false); image icon{Resource::Icon}; auto data = icon.data(); for(uint y : range(icon.height())) { for(uint x : range(icon.width())) { auto pixel = icon.read(data); auto a = pixel >> 24 & 255; auto r = pixel >> 16 & 255; auto g = pixel >> 8 & 255; auto b = pixel >> 0 & 255; a = a * 0.25; icon.write(data, a << 24 | r << 16 | g << 8 | b << 0); data += icon.stride(); } } canvas.setIcon(icon); } public: Canvas canvas{this, Size{~0, ~0}}; } settingsHome; auto SettingsWindow::create() -> void { layout.setPadding(5_sx); panelList.append(ListViewItem().setText("Video").setIcon(Icon::Device::Display)); panelList.append(ListViewItem().setText("Audio").setIcon(Icon::Device::Speaker)); panelList.append(ListViewItem().setText("Input").setIcon(Icon::Device::Joypad)); panelList.append(ListViewItem().setText("Hotkeys").setIcon(Icon::Device::Keyboard)); panelList.append(ListViewItem().setText("Paths").setIcon(Icon::Emblem::Folder)); panelList.append(ListViewItem().setText("Emulator").setIcon(Icon::Action::Settings)); panelList.append(ListViewItem().setText("Enhancements").setIcon(Icon::Action::Add)); panelList.append(ListViewItem().setText("Compatibility").setIcon(Icon::Action::Remove)); panelList.append(ListViewItem().setText("Drivers").setIcon(Icon::Place::Settings)); panelList.onChange([&] { if(auto item = panelList.selected()) { show(item.offset()); } else { show(-1); } }); panelContainer.append(settingsHome, Size{~0, ~0}); panelContainer.append(videoSettings, Size{~0, ~0}); panelContainer.append(audioSettings, Size{~0, ~0}); panelContainer.append(inputSettings, Size{~0, ~0}); panelContainer.append(hotkeySettings, Size{~0, ~0}); panelContainer.append(pathSettings, Size{~0, ~0}); panelContainer.append(emulatorSettings, Size{~0, ~0}); panelContainer.append(enhancementSettings, Size{~0, ~0}); panelContainer.append(compatibilitySettings, Size{~0, ~0}); panelContainer.append(driverSettings, Size{~0, ~0}); statusBar.setFont(Font().setBold()); setTitle("Settings"); setSize({680_sx, 400_sy}); setAlignment({0.0, 1.0}); setDismissable(); onClose([&] { if(inputSettings.activeMapping) inputSettings.cancelMapping(); if(hotkeySettings.activeMapping) hotkeySettings.cancelMapping(); setVisible(false); }); } auto SettingsWindow::setVisible(bool visible) -> SettingsWindow& { if(visible) { inputSettings.refreshMappings(); hotkeySettings.refreshMappings(); Application::processEvents(); } return Window::setVisible(visible), *this; } auto SettingsWindow::show(int index) -> void { settingsHome.setVisible(false); videoSettings.setVisible(false); audioSettings.setVisible(false); inputSettings.setVisible(false); hotkeySettings.setVisible(false); pathSettings.setVisible(false); emulatorSettings.setVisible(false); enhancementSettings.setVisible(false); compatibilitySettings.setVisible(false); driverSettings.setVisible(false); panelList.item(index).setSelected(); if(index ==-1) settingsHome.setVisible(true); if(index == 0) videoSettings.setVisible(true); if(index == 1) audioSettings.setVisible(true); if(index == 2) inputSettings.setVisible(true); if(index == 3) hotkeySettings.setVisible(true); if(index == 4) pathSettings.setVisible(true); if(index == 5) emulatorSettings.setVisible(true); if(index == 6) enhancementSettings.setVisible(true); if(index == 7) compatibilitySettings.setVisible(true); if(index == 8) driverSettings.setVisible(true); panelContainer.resize(); setVisible(); setFocused(); panelList.setFocused(); }