bsnes-mt/bsnes/target-bsnes/settings/settings.cpp
2020-09-13 04:16:49 +03:00

296 lines
11 KiB
C++

#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"
/* MT. */
#include "bsnes-mt/translations.h"
namespace bmt = bsnesMt::translations;
/* /MT. */
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& settingsWindow = Instances::settingsWindow();
auto Settings::load() -> void {
Markup::Node::operator=(BML::unserialize(string::read(location), " "));
process(true);
save();
}
auto Settings::save() -> void {
process(false);
file::write(location ? location : locate("bsnes-mt-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/ScalingInfo", video.scalingInfo); // MT.
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(boolean, "Emulator/Hack/PPU/Mode7/Perspective", emulator.hack.ppu.mode7.perspective);
bind(boolean, "Emulator/Hack/PPU/Mode7/Supersample", emulator.hack.ppu.mode7.supersample);
bind(boolean, "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/NativeFileDialogs", general.nativeFileDialogs);
#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(bmt::get("Common.Video").data()).setIcon(Icon::Device::Display));
panelList.append(ListViewItem().setText(bmt::get("Common.Audio").data()).setIcon(Icon::Device::Speaker));
panelList.append(ListViewItem().setText(bmt::get("Settings.Input").data()).setIcon(Icon::Device::Joypad));
panelList.append(ListViewItem().setText(bmt::get("Settings.Hotkeys").data()).setIcon(Icon::Device::Keyboard));
panelList.append(ListViewItem().setText(bmt::get("Settings.Paths").data()).setIcon(Icon::Emblem::Folder));
panelList.append(ListViewItem().setText(bmt::get("Settings.Emulator").data()).setIcon(Icon::Action::Settings));
panelList.append(ListViewItem().setText(bmt::get("Settings.Enhancements").data()).setIcon(Icon::Action::Add));
panelList.append(ListViewItem().setText(bmt::get("Settings.Compatibility").data()).setIcon(Icon::Action::Remove));
panelList.append(ListViewItem().setText(bmt::get("Settings.Drivers").data()).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(bmt::get("Settings").data());
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);
}
else if (index == 0) {
videoSettings.setVisible(true);
}
else if (index == 1) {
audioSettings.setVisible(true);
}
else if (index == 2) {
inputSettings.setVisible(true);
}
else if (index == 3) {
hotkeySettings.setVisible(true);
}
else if (index == 4) {
pathSettings.setVisible(true);
}
else if (index == 5) {
emulatorSettings.setVisible(true);
}
else if (index == 6) {
enhancementSettings.setVisible(true);
}
else if (index == 7) {
compatibilitySettings.setVisible(true);
}
else if (index == 8) {
driverSettings.setVisible(true);
}
panelContainer.resize();
setVisible();
setFocused();
panelList.setFocused();
}