mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-12 04:57:06 -04:00
582 lines
26 KiB
C++
582 lines
26 KiB
C++
#include "settings.hpp"
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include "aurora/gfx.h"
|
|
#include "bool_button.hpp"
|
|
#include "dusk/audio/DuskAudioSystem.h"
|
|
#include "dusk/config.hpp"
|
|
#include "dusk/livesplit.h"
|
|
#include "m_Do/m_Do_main.h"
|
|
#include "number_button.hpp"
|
|
#include "overlay.hpp"
|
|
#include "pane.hpp"
|
|
#include "ui.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace dusk::ui {
|
|
namespace {
|
|
|
|
void reset_for_speedrun_mode() {
|
|
mDoMain::developmentMode = -1;
|
|
|
|
getSettings().game.damageMultiplier.setValue(1);
|
|
getSettings().game.instantDeath.setValue(false);
|
|
getSettings().game.noHeartDrops.setValue(false);
|
|
|
|
getSettings().game.infiniteHearts.setValue(false);
|
|
getSettings().game.infiniteArrows.setValue(false);
|
|
getSettings().game.infiniteBombs.setValue(false);
|
|
getSettings().game.infiniteOil.setValue(false);
|
|
getSettings().game.infiniteOxygen.setValue(false);
|
|
getSettings().game.infiniteRupees.setValue(false);
|
|
getSettings().game.enableIndefiniteItemDrops.setValue(false);
|
|
|
|
getSettings().game.moonJump.setValue(false);
|
|
getSettings().game.superClawshot.setValue(false);
|
|
getSettings().game.alwaysGreatspin.setValue(false);
|
|
getSettings().game.enableFastIronBoots.setValue(false);
|
|
getSettings().game.canTransformAnywhere.setValue(false);
|
|
getSettings().game.fastSpinner.setValue(false);
|
|
getSettings().game.freeMagicArmor.setValue(false);
|
|
|
|
getSettings().game.enableTurboKeybind.setValue(false);
|
|
}
|
|
|
|
const Rml::String kInternalResolutionHelpText =
|
|
"Configure the resolution used for rendering the game. Higher values are more demanding on "
|
|
"your graphics hardware.";
|
|
const Rml::String kShadowResolutionHelpText =
|
|
"Configure the shadow-map resolution. Higher values improve shadow quality but increase GPU "
|
|
"and memory usage.";
|
|
const Rml::String kBloomHelpText =
|
|
"Configure the post-processing bloom effect. Classic uses the original bloom pass; Dusk uses "
|
|
"a higher-quality bloom pass.";
|
|
const Rml::String kBloomBrightnessHelpText =
|
|
"Configure bloom intensity. Higher values make bright areas glow more strongly.";
|
|
|
|
int bloom_multiplier_percent() {
|
|
return std::clamp(
|
|
static_cast<int>(getSettings().game.bloomMultiplier.getValue() * 100.0f + 0.5f), 0, 100);
|
|
}
|
|
|
|
int float_setting_percent(ConfigVar<float>& var) {
|
|
return static_cast<int>(var.getValue() * 100.0f + 0.5f);
|
|
}
|
|
|
|
bool gyro_enabled() {
|
|
return getSettings().game.enableGyroAim || getSettings().game.enableGyroRollgoal;
|
|
}
|
|
|
|
struct ConfigBoolProps {
|
|
Rml::String key;
|
|
Rml::String helpText;
|
|
std::function<void(bool)> onChange;
|
|
std::function<bool()> isDisabled;
|
|
};
|
|
|
|
SelectButton& config_bool_select(
|
|
Pane& leftPane, Pane& rightPane, ConfigVar<bool>& var, ConfigBoolProps props) {
|
|
return leftPane
|
|
.add_child<BoolButton>(BoolButton::Props{
|
|
.key = std::move(props.key),
|
|
.getValue = [&var] { return var.getValue(); },
|
|
.setValue =
|
|
[&var, callback = std::move(props.onChange)](bool value) {
|
|
if (value == var.getValue()) {
|
|
return;
|
|
}
|
|
var.setValue(value);
|
|
config::Save();
|
|
if (callback) {
|
|
callback(value);
|
|
}
|
|
},
|
|
.isDisabled = std::move(props.isDisabled),
|
|
})
|
|
.on_focus([&rightPane, helpText = std::move(props.helpText)](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_rml(helpText);
|
|
});
|
|
}
|
|
|
|
SelectButton& config_percent_select(Pane& leftPane, Pane& rightPane, ConfigVar<float>& var,
|
|
Rml::String key, Rml::String helpText, int min, int max, int step = 5,
|
|
std::function<bool()> isDisabled = {}) {
|
|
return leftPane
|
|
.add_child<NumberButton>(NumberButton::Props{
|
|
.key = std::move(key),
|
|
.getValue = [&var] { return float_setting_percent(var); },
|
|
.setValue =
|
|
[&var, min, max](int value) {
|
|
var.setValue(std::clamp(value, min, max) / 100.0f);
|
|
config::Save();
|
|
},
|
|
.isDisabled = std::move(isDisabled),
|
|
.min = min,
|
|
.max = max,
|
|
.step = step,
|
|
.suffix = "%",
|
|
})
|
|
.on_focus([&rightPane, helpText = std::move(helpText)](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text(helpText);
|
|
});
|
|
}
|
|
|
|
class ControllerConfigWindow : public Window {
|
|
public:
|
|
ControllerConfigWindow() {
|
|
for (int i = 0; i < 4; ++i) {
|
|
add_tab(fmt::format("Port {}", i + 1), [this](Rml::Element* content) {
|
|
auto& pane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
pane.add_section("Coming soon");
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
SettingsWindow::SettingsWindow() {
|
|
add_tab("Audio", [this](Rml::Element* content) {
|
|
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
|
|
|
leftPane.add_section("Volume");
|
|
leftPane
|
|
.add_child<NumberButton>(NumberButton::Props{
|
|
.key = "Master Volume",
|
|
.getValue = [] { return getSettings().audio.masterVolume.getValue(); },
|
|
.setValue =
|
|
[](int value) {
|
|
getSettings().audio.masterVolume.setValue(value);
|
|
config::Save();
|
|
audio::SetMasterVolume(value / 100.f);
|
|
},
|
|
.max = 100,
|
|
.suffix = "%",
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text("Adjusts the volume of all sounds in the game.");
|
|
});
|
|
|
|
leftPane.add_section("Effects");
|
|
config_bool_select(leftPane, rightPane, getSettings().audio.enableReverb,
|
|
{
|
|
.key = "Enable Reverb",
|
|
.helpText = "Enables the reverb effect in game audio.",
|
|
.onChange = [](bool value) { audio::SetEnableReverb(value); },
|
|
});
|
|
|
|
leftPane.add_section("Tweaks");
|
|
config_bool_select(leftPane, rightPane, getSettings().game.noLowHpSound,
|
|
{
|
|
.key = "No Low HP Sound",
|
|
.helpText = "Disable the beeping sound when having low health.",
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().game.midnasLamentNonStop,
|
|
{
|
|
.key = "Non-Stop Midna's Lament",
|
|
.helpText = "Prevents enemy music while Midna's Lament is playing.",
|
|
});
|
|
});
|
|
|
|
add_tab("Cheats", [this](Rml::Element* content) {
|
|
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
|
|
|
auto addCheat = [&](const Rml::String& key, ConfigVar<bool>& value,
|
|
const Rml::String& helpText) {
|
|
config_bool_select(leftPane, rightPane, value,
|
|
{
|
|
.key = key,
|
|
.helpText = helpText,
|
|
.isDisabled = [] { return getSettings().game.speedrunMode; },
|
|
});
|
|
};
|
|
|
|
leftPane.add_section("Resources");
|
|
addCheat("Infinite Hearts", getSettings().game.infiniteHearts, "Keeps your health full.");
|
|
addCheat(
|
|
"Infinite Arrows", getSettings().game.infiniteArrows, "Keeps your arrow count full.");
|
|
addCheat("Infinite Bombs", getSettings().game.infiniteBombs, "Keeps all bomb bags full.");
|
|
addCheat("Infinite Oil", getSettings().game.infiniteOil, "Keeps your lantern oil full.");
|
|
addCheat("Infinite Oxygen", getSettings().game.infiniteOxygen,
|
|
"Keeps your underwater oxygen meter full.");
|
|
addCheat(
|
|
"Infinite Rupees", getSettings().game.infiniteRupees, "Keeps your rupee count full.");
|
|
addCheat("No Item Timer", getSettings().game.enableIndefiniteItemDrops,
|
|
"Item drops such as rupees and hearts will never disappear after they drop.");
|
|
|
|
leftPane.add_section("Abilities");
|
|
addCheat(
|
|
"Moon Jump (R+A)", getSettings().game.moonJump, "Hold R and A to rise into the air.");
|
|
addCheat("Super Clawshot", getSettings().game.superClawshot,
|
|
"Extends clawshot behavior beyond the normal game rules.");
|
|
addCheat("Always Greatspin", getSettings().game.alwaysGreatspin,
|
|
"Allows the Great Spin attack without requiring full health.");
|
|
addCheat("Fast Iron Boots", getSettings().game.enableFastIronBoots,
|
|
"Speeds up movement while wearing the Iron Boots.");
|
|
addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere,
|
|
"Allows transforming even if NPCs are looking.");
|
|
addCheat("Fast Spinner", getSettings().game.fastSpinner,
|
|
"Speeds up Spinner movement while holding R.");
|
|
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,
|
|
"Lets the magic armor work without consuming rupees.");
|
|
});
|
|
|
|
add_tab("Gameplay", [this](Rml::Element* content) {
|
|
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
|
|
|
auto addOption = [&](const Rml::String& key, ConfigVar<bool>& value,
|
|
const Rml::String& helpText) {
|
|
config_bool_select(leftPane, rightPane, value,
|
|
{
|
|
.key = key,
|
|
.helpText = helpText,
|
|
});
|
|
};
|
|
auto addSpeedrunDisabledOption = [&](const Rml::String& key, ConfigVar<bool>& value,
|
|
const Rml::String& helpText) {
|
|
config_bool_select(leftPane, rightPane, value,
|
|
{
|
|
.key = key,
|
|
.helpText = helpText,
|
|
.isDisabled = [] { return getSettings().game.speedrunMode; },
|
|
});
|
|
};
|
|
|
|
leftPane.add_section("General");
|
|
addOption("Mirror Mode", getSettings().game.enableMirrorMode,
|
|
"Mirrors the world horizontally, matching the Wii version of the game.");
|
|
addOption("Disable Main HUD", getSettings().game.disableMainHUD,
|
|
"Disables the main HUD of the game.<br/>Useful for recording or a more immersive "
|
|
"experience.");
|
|
addOption("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches,
|
|
"Restores patched glitches from Wii USA 1.0, the first released version.");
|
|
addOption("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation,
|
|
"Enables rotating Link in the collection menu with the C-Stick.");
|
|
|
|
leftPane.add_section("Difficulty");
|
|
leftPane
|
|
.add_child<NumberButton>(NumberButton::Props{
|
|
.key = "Damage Multiplier",
|
|
.getValue = [] { return getSettings().game.damageMultiplier.getValue(); },
|
|
.setValue =
|
|
[](int value) {
|
|
getSettings().game.damageMultiplier.setValue(value);
|
|
config::Save();
|
|
},
|
|
.isDisabled = [] { return getSettings().game.speedrunMode; },
|
|
.min = 1,
|
|
.max = 8,
|
|
.prefix = "x",
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text("Multiplies incoming damage.");
|
|
});
|
|
addSpeedrunDisabledOption(
|
|
"Instant Death", getSettings().game.instantDeath, "Any hit will instantly kill you.");
|
|
addSpeedrunDisabledOption("No Heart Drops", getSettings().game.noHeartDrops,
|
|
"Hearts will never drop from enemies, pots, and various other places.");
|
|
|
|
leftPane.add_section("Quality of Life");
|
|
addOption("Bigger Wallets", getSettings().game.biggerWallets,
|
|
"Wallet sizes are like in the HD version. (500, 1000, 2000)");
|
|
addOption("Disable Rupee Cutscenes", getSettings().game.disableRupeeCutscenes,
|
|
"Rupees will not play cutscenes after you have collected them the first time.");
|
|
addOption("Faster Climbing", getSettings().game.fastClimbing,
|
|
"Quicker climbing on ladders and vines like the HD version.");
|
|
addOption("Faster Tears of Light", getSettings().game.fastTears,
|
|
"Tears of Light dropped by Shadow Insects pop out faster like the HD version.");
|
|
addOption("Instant Saves", getSettings().game.instantSaves,
|
|
"Skips the delay when writing to the Memory Card.");
|
|
addOption("Hold B for Instant Text", getSettings().game.instantText,
|
|
"Makes text scroll immediately by holding B.");
|
|
addOption("No Climbing Miss Animation", getSettings().game.noMissClimbing,
|
|
"Prevents Link from playing a struggle animation when grabbing ledges or climbing on "
|
|
"vines.");
|
|
addOption("No Rupee Returns", getSettings().game.noReturnRupees,
|
|
"Always collect Rupees even if your Wallet is too full.");
|
|
addOption("No Sword Recoil", getSettings().game.noSwordRecoil,
|
|
"Link will not recoil when his sword hits walls.");
|
|
addOption("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat,
|
|
"Skip needing to catch a second fish for Sera's cat.");
|
|
addOption("Skip TV Settings Screen", getSettings().game.hideTvSettingsScreen,
|
|
"Skips the TV calibration screen shown when loading a save.");
|
|
addOption("Skip Warning Screen", getSettings().game.skipWarningScreen,
|
|
"Skips the warning screen shown when starting the game.");
|
|
addOption("Sun's Song (R+X)", getSettings().game.sunsSong,
|
|
"Allows Wolf Link to howl and change the time of day.");
|
|
addOption("Quick Transform (R+Y)", getSettings().game.enableQuickTransform,
|
|
"Transform instantly by pressing R and Y simultaneously.");
|
|
|
|
leftPane.add_section("Speedrunning");
|
|
config_bool_select(leftPane, rightPane, getSettings().game.speedrunMode,
|
|
{
|
|
.key = "Speedrun Mode",
|
|
.helpText =
|
|
"Enables speedrunning options while restricting certain gameplay modifiers.",
|
|
.onChange = [](bool) { reset_for_speedrun_mode(); },
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().game.liveSplitEnabled,
|
|
{
|
|
.key = "LiveSplit Connection",
|
|
.helpText = "Connect to LiveSplit server on localhost:16834.",
|
|
.onChange =
|
|
[](bool enabled) {
|
|
if (enabled) {
|
|
speedrun::connectLiveSplit();
|
|
} else {
|
|
speedrun::disconnectLiveSplit();
|
|
}
|
|
},
|
|
.isDisabled = [] { return !getSettings().game.speedrunMode; },
|
|
});
|
|
});
|
|
|
|
add_tab("Input", [this](Rml::Element* content) {
|
|
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
|
|
|
auto addOption = [&](const Rml::String& key, ConfigVar<bool>& value,
|
|
const Rml::String& helpText, std::function<bool()> isDisabled = {}) {
|
|
config_bool_select(leftPane, rightPane, value,
|
|
{
|
|
.key = key,
|
|
.helpText = helpText,
|
|
.isDisabled = std::move(isDisabled),
|
|
});
|
|
};
|
|
|
|
leftPane.add_section("Controller");
|
|
leftPane.add_button("Configure Controller")
|
|
.on_pressed([] { push_document(std::make_unique<ControllerConfigWindow>()); })
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text("Open controller binding configuration.");
|
|
});
|
|
|
|
leftPane.add_section("Camera");
|
|
addOption("Free Camera", getSettings().game.freeCamera,
|
|
"Enables twin-stick camera control, letting the C-Stick move the camera vertically as "
|
|
"well as horizontally.");
|
|
addOption("Invert Camera X Axis", getSettings().game.invertCameraXAxis,
|
|
"Invert horizontal camera movement.");
|
|
addOption("Invert Camera Y Axis", getSettings().game.invertCameraYAxis,
|
|
"Invert vertical camera movement when Free Camera is enabled.",
|
|
[] { return !getSettings().game.freeCamera; });
|
|
config_percent_select(leftPane, rightPane, getSettings().game.freeCameraSensitivity,
|
|
"Free Camera Sensitivity", "Adjusts twin-stick camera sensitivity.", 50, 200, 5,
|
|
[] { return !getSettings().game.freeCamera; });
|
|
|
|
leftPane.add_section("Gyro");
|
|
addOption("Gyro Aim", getSettings().game.enableGyroAim,
|
|
"Enables gyro aiming on supported controllers while in look mode and while aiming "
|
|
"items.");
|
|
addOption("Gyro Rollgoal", getSettings().game.enableGyroRollgoal,
|
|
"Enables gyro controls for Rollgoal in Hena's Cabin.");
|
|
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityY,
|
|
"Gyro Pitch Sensitivity", "Controls vertical gyro aiming sensitivity.", 25, 400, 5,
|
|
[] { return !gyro_enabled(); });
|
|
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityX,
|
|
"Gyro Yaw Sensitivity", "Controls horizontal gyro aiming sensitivity.", 25, 400, 5,
|
|
[] { return !gyro_enabled(); });
|
|
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityRollgoal,
|
|
"Rollgoal Sensitivity", "Controls how strongly gyro input tilts the Rollgoal table.",
|
|
25, 400, 5, [] { return !getSettings().game.enableGyroRollgoal; });
|
|
config_percent_select(leftPane, rightPane, getSettings().game.gyroDeadband, "Gyro Deadband",
|
|
"Ignores small gyro movement to reduce drift and jitter.", 0, 50, 1,
|
|
[] { return !gyro_enabled(); });
|
|
config_percent_select(leftPane, rightPane, getSettings().game.gyroSmoothing,
|
|
"Gyro Smoothing", "Higher values smooth gyro input over time.", 0, 100, 1,
|
|
[] { return !gyro_enabled(); });
|
|
addOption("Invert Gyro Pitch", getSettings().game.gyroInvertPitch,
|
|
"Invert vertical gyro aiming.", [] { return !gyro_enabled(); });
|
|
addOption("Invert Gyro Yaw", getSettings().game.gyroInvertYaw,
|
|
"Invert horizontal gyro aiming.", [] { return !gyro_enabled(); });
|
|
|
|
leftPane.add_section("Tools");
|
|
addOption("Turbo Key", getSettings().game.enableTurboKeybind,
|
|
"Hold Tab to increase game speed by up to 4x.",
|
|
[] { return getSettings().game.speedrunMode; });
|
|
});
|
|
|
|
add_tab("Graphics", [this](Rml::Element* content) {
|
|
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
|
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
|
|
|
leftPane.add_section("Display");
|
|
|
|
leftPane.add_button("Toggle Fullscreen").on_pressed([] {
|
|
getSettings().video.enableFullscreen.setValue(!getSettings().video.enableFullscreen);
|
|
VISetWindowFullscreen(getSettings().video.enableFullscreen);
|
|
config::Save();
|
|
});
|
|
leftPane.add_button("Restore Default Window Size").on_pressed([] {
|
|
getSettings().video.enableFullscreen.setValue(false);
|
|
VISetWindowFullscreen(false);
|
|
VISetWindowSize(FB_WIDTH * 2, FB_HEIGHT * 2);
|
|
VICenterWindow();
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().video.enableVsync,
|
|
{
|
|
.key = "Enable VSync",
|
|
.helpText = "Synchronizes the frame rate to your monitor's refresh rate.",
|
|
.onChange = [](bool value) { aurora_enable_vsync(value); },
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().video.lockAspectRatio,
|
|
{
|
|
.key = "Lock 4:3 Aspect Ratio",
|
|
.helpText = "Lock the game's aspect ratio to the original.",
|
|
.onChange =
|
|
[](bool value) {
|
|
AuroraSetViewportPolicy(
|
|
value ? AURORA_VIEWPORT_FIT : AURORA_VIEWPORT_STRETCH);
|
|
},
|
|
});
|
|
|
|
leftPane.add_section("Resolution");
|
|
leftPane
|
|
.add_select_button({
|
|
.key = "Internal Resolution",
|
|
.getValue =
|
|
[] {
|
|
return format_graphics_setting_value(GraphicsOption::InternalResolution,
|
|
getSettings().game.internalResolutionScale.getValue());
|
|
},
|
|
})
|
|
.on_nav_command([](Rml::Event&, NavCommand cmd) {
|
|
if (cmd == NavCommand::Confirm || cmd == NavCommand::Left ||
|
|
cmd == NavCommand::Right) {
|
|
push_document(std::make_unique<Overlay>(OverlayProps{
|
|
.option = GraphicsOption::InternalResolution,
|
|
.title = "Internal Resolution",
|
|
.helpText = kInternalResolutionHelpText,
|
|
.valueMin = 0,
|
|
.valueMax = 12,
|
|
.defaultValue = 0,
|
|
}));
|
|
return true;
|
|
}
|
|
return false;
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text(kInternalResolutionHelpText);
|
|
});
|
|
leftPane
|
|
.add_select_button({
|
|
.key = "Shadow Resolution",
|
|
.getValue =
|
|
[] {
|
|
return format_graphics_setting_value(GraphicsOption::ShadowResolution,
|
|
getSettings().game.shadowResolutionMultiplier.getValue());
|
|
},
|
|
})
|
|
.on_nav_command([](Rml::Event&, NavCommand cmd) {
|
|
if (cmd == NavCommand::Confirm || cmd == NavCommand::Left ||
|
|
cmd == NavCommand::Right) {
|
|
push_document(std::make_unique<Overlay>(OverlayProps{
|
|
.option = GraphicsOption::ShadowResolution,
|
|
.title = "Shadow Resolution",
|
|
.helpText = kShadowResolutionHelpText,
|
|
.valueMin = 1,
|
|
.valueMax = 8,
|
|
.defaultValue = 1,
|
|
}));
|
|
return true;
|
|
}
|
|
return false;
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text(kShadowResolutionHelpText);
|
|
});
|
|
|
|
leftPane.add_section("Post-Processing");
|
|
leftPane
|
|
.add_select_button({
|
|
.key = "Bloom",
|
|
.getValue =
|
|
[] {
|
|
return format_graphics_setting_value(GraphicsOption::BloomMode,
|
|
static_cast<int>(getSettings().game.bloomMode.getValue()));
|
|
},
|
|
})
|
|
.on_nav_command([](Rml::Event&, NavCommand cmd) {
|
|
if (cmd == NavCommand::Confirm || cmd == NavCommand::Left ||
|
|
cmd == NavCommand::Right) {
|
|
push_document(std::make_unique<Overlay>(OverlayProps{
|
|
.option = GraphicsOption::BloomMode,
|
|
.title = "Bloom",
|
|
.helpText = kBloomHelpText,
|
|
.valueMin = static_cast<int>(BloomMode::Off),
|
|
.valueMax = static_cast<int>(BloomMode::Dusk),
|
|
.defaultValue = static_cast<int>(BloomMode::Classic),
|
|
}));
|
|
return true;
|
|
}
|
|
return false;
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text(kBloomHelpText);
|
|
});
|
|
leftPane
|
|
.add_select_button({
|
|
.key = "Bloom Brightness",
|
|
.getValue =
|
|
[] {
|
|
return format_graphics_setting_value(
|
|
GraphicsOption::BloomMultiplier, bloom_multiplier_percent());
|
|
},
|
|
.isDisabled =
|
|
[] { return getSettings().game.bloomMode.getValue() == BloomMode::Off; },
|
|
})
|
|
.on_nav_command([](Rml::Event&, NavCommand cmd) {
|
|
if (cmd == NavCommand::Confirm || cmd == NavCommand::Left ||
|
|
cmd == NavCommand::Right) {
|
|
push_document(std::make_unique<Overlay>(OverlayProps{
|
|
.option = GraphicsOption::BloomMultiplier,
|
|
.title = "Bloom Brightness",
|
|
.helpText = kBloomBrightnessHelpText,
|
|
.valueMin = 0,
|
|
.valueMax = 100,
|
|
.defaultValue = 100,
|
|
}));
|
|
return true;
|
|
}
|
|
return false;
|
|
})
|
|
.on_focus([&rightPane](Rml::Event&) {
|
|
rightPane.clear();
|
|
rightPane.add_text(kBloomBrightnessHelpText);
|
|
});
|
|
|
|
leftPane.add_section("Rendering");
|
|
config_bool_select(leftPane, rightPane, getSettings().game.enableFrameInterpolation,
|
|
{
|
|
.key = "Unlock Framerate",
|
|
.helpText =
|
|
"Uses inter-frame interpolation to enable higher frame rates.<br/><br/>Visual "
|
|
"artifacts, animation glitches, or instability may occur.",
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().game.enableDepthOfField,
|
|
{
|
|
.key = "Enable Depth of Field",
|
|
});
|
|
config_bool_select(leftPane, rightPane, getSettings().game.enableMapBackground,
|
|
{
|
|
.key = "Enable Mini-Map Shadows",
|
|
});
|
|
});
|
|
}
|
|
|
|
} // namespace dusk::ui
|