mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-02 08:43:42 -04:00
Refactor GraphicsTuner, no longer tanks performance when open (#2365)
* Sort includes, move logic into ConfigVars, add reusable helpers * Refactor GraphicsTuner, only refresh labels when actually needed
This commit is contained in:
+28
-5
@@ -1,8 +1,12 @@
|
||||
#include "dusk/settings.h"
|
||||
#include <aurora/aurora.h>
|
||||
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/ui/ui.hpp"
|
||||
#include "dusk/game_mode.hpp"
|
||||
#include "dusk/texture_replacements.hpp"
|
||||
#include "dusk/ui/ui.hpp"
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <dolphin/vi.h>
|
||||
|
||||
namespace dusk {
|
||||
|
||||
@@ -221,6 +225,22 @@ UserSettings& getSettings() {
|
||||
return g_userSettings;
|
||||
}
|
||||
|
||||
void applyInternalResolutionScale(int scale) {
|
||||
VISetFrameBufferScale(static_cast<float>(scale));
|
||||
}
|
||||
|
||||
void applyResampler(Resampler resampler) {
|
||||
switch (resampler) {
|
||||
case Resampler::Area:
|
||||
aurora_set_resampler(SAMPLER_AREA);
|
||||
break;
|
||||
case Resampler::Bilinear:
|
||||
default:
|
||||
aurora_set_resampler(SAMPLER_BILINEAR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void registerSettings() {
|
||||
// Video
|
||||
Register(g_userSettings.video.enableFullscreen);
|
||||
@@ -286,9 +306,12 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.bloomMultiplier);
|
||||
Register(g_userSettings.game.depthOfFieldMode);
|
||||
Register(g_userSettings.game.disableWaterRefraction);
|
||||
Register(g_userSettings.game.enableTextureReplacements);
|
||||
Register(g_userSettings.game.internalResolutionScale);
|
||||
Register(g_userSettings.game.resampler);
|
||||
Register(g_userSettings.game.enableTextureReplacements,
|
||||
[](const bool&, const bool&) { texture_replacements::reload(); });
|
||||
Register(g_userSettings.game.internalResolutionScale,
|
||||
[](const int& value, const int&) { applyInternalResolutionScale(value); });
|
||||
Register(g_userSettings.game.resampler,
|
||||
[](const Resampler& value, const Resampler&) { applyResampler(value); });
|
||||
Register(g_userSettings.game.shadowResolutionMultiplier);
|
||||
Register(g_userSettings.game.enableMapBackground);
|
||||
Register(g_userSettings.game.disableCutscenePillarboxing);
|
||||
|
||||
@@ -318,6 +318,9 @@ UserSettings& getSettings();
|
||||
|
||||
void registerSettings();
|
||||
|
||||
void applyInternalResolutionScale(int scale);
|
||||
void applyResampler(Resampler resampler);
|
||||
|
||||
// Transient settings
|
||||
|
||||
struct CollisionViewSettings {
|
||||
|
||||
@@ -26,11 +26,6 @@ void reload() {
|
||||
s_directoryGroup.registrations.size());
|
||||
}
|
||||
|
||||
void set_enabled(bool enabled) {
|
||||
getSettings().game.enableTextureReplacements.setValue(enabled);
|
||||
reload();
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
aurora::texture::unregister_replacements(s_directoryGroup);
|
||||
s_directoryGroup.registrations.clear();
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace dusk::texture_replacements {
|
||||
inline constexpr int32_t kUserTextureReplacementPriority = -1'000'000;
|
||||
|
||||
void reload();
|
||||
void set_enabled(bool enabled);
|
||||
void shutdown();
|
||||
|
||||
}
|
||||
|
||||
+146
-127
@@ -1,20 +1,18 @@
|
||||
#include "graphics_tuner.hpp"
|
||||
|
||||
#include "Z2AudioLib/Z2SeMgr.h"
|
||||
#include "m_Do/m_Do_audio.h"
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <aurora/gfx.h>
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
#include <dolphin/vi.h>
|
||||
#include <fmt/format.h>
|
||||
#include "button.hpp"
|
||||
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/texture_replacements.hpp"
|
||||
#include "m_Do/m_Do_audio.h"
|
||||
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace dusk::ui {
|
||||
namespace {
|
||||
@@ -40,70 +38,84 @@ const Rml::String kDocumentSource = R"RML(
|
||||
</rml>
|
||||
)RML";
|
||||
|
||||
int get_value(GraphicsOption option) {
|
||||
switch (option) {
|
||||
case GraphicsOption::InternalResolution:
|
||||
return getSettings().game.internalResolutionScale.getValue();
|
||||
case GraphicsOption::ShadowResolution:
|
||||
return getSettings().game.shadowResolutionMultiplier.getValue();
|
||||
case GraphicsOption::Resampler:
|
||||
return static_cast<int>(getSettings().game.resampler.getValue());
|
||||
case GraphicsOption::BloomMode:
|
||||
return static_cast<int>(getSettings().game.bloomMode.getValue());
|
||||
case GraphicsOption::BloomMultiplier:
|
||||
return std::clamp(
|
||||
static_cast<int>(getSettings().game.bloomMultiplier.getValue() * 100.0f + 0.5f), 0,
|
||||
100);
|
||||
case GraphicsOption::DepthOfFieldMode:
|
||||
return static_cast<int>(getSettings().game.depthOfFieldMode.getValue());
|
||||
case GraphicsOption::TextureReplacements:
|
||||
return getSettings().game.enableTextureReplacements.getValue();
|
||||
Rml::String format_internal_resolution(int value) {
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
AuroraGetRenderSize(&width, &height);
|
||||
if (value <= 0) {
|
||||
return fmt::format("Auto ({}×{})", width, height);
|
||||
}
|
||||
return 0;
|
||||
return fmt::format("{}× ({}×{})", value, width, height);
|
||||
}
|
||||
|
||||
void set_value(GraphicsOption option, int value) {
|
||||
switch (option) {
|
||||
case GraphicsOption::InternalResolution:
|
||||
getSettings().game.internalResolutionScale.setValue(value);
|
||||
VISetFrameBufferScale(static_cast<float>(value));
|
||||
break;
|
||||
case GraphicsOption::ShadowResolution:
|
||||
getSettings().game.shadowResolutionMultiplier.setValue(value);
|
||||
break;
|
||||
case GraphicsOption::Resampler: {
|
||||
const auto sampler = static_cast<Resampler>(std::clamp(value,
|
||||
static_cast<int>(Resampler::Bilinear),
|
||||
static_cast<int>(Resampler::Area)));
|
||||
getSettings().game.resampler.setValue(sampler);
|
||||
switch (sampler) {
|
||||
case Resampler::Area:
|
||||
aurora_set_resampler(SAMPLER_AREA);
|
||||
break;
|
||||
case Resampler::Bilinear:
|
||||
default:
|
||||
aurora_set_resampler(SAMPLER_BILINEAR);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
Rml::String format_resampler(int value) {
|
||||
switch (static_cast<Resampler>(value)) {
|
||||
case Resampler::Bilinear:
|
||||
return "Bilinear";
|
||||
case Resampler::Area:
|
||||
return "Area";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
case GraphicsOption::BloomMode:
|
||||
getSettings().game.bloomMode.setValue(static_cast<BloomMode>(std::clamp(
|
||||
value, static_cast<int>(BloomMode::Off), static_cast<int>(BloomMode::Dusk))));
|
||||
break;
|
||||
case GraphicsOption::DepthOfFieldMode:
|
||||
getSettings().game.depthOfFieldMode.setValue(static_cast<DepthOfFieldMode>(std::clamp(
|
||||
value, static_cast<int>(DepthOfFieldMode::Off), static_cast<int>(DepthOfFieldMode::Dusk))));
|
||||
break;
|
||||
case GraphicsOption::BloomMultiplier:
|
||||
getSettings().game.bloomMultiplier.setValue(std::clamp(value, 0, 100) / 100.0f);
|
||||
break;
|
||||
case GraphicsOption::TextureReplacements:
|
||||
texture_replacements::set_enabled(static_cast<bool>(value));
|
||||
break;
|
||||
}
|
||||
|
||||
Rml::String format_post_process_mode(int value) {
|
||||
switch (static_cast<BloomMode>(value)) {
|
||||
case BloomMode::Off:
|
||||
return "Off";
|
||||
case BloomMode::Classic:
|
||||
return "Classic";
|
||||
case BloomMode::Dusk:
|
||||
return "Dusklight";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Rml::String format_times(int value) { return fmt::format("{}×", value); }
|
||||
|
||||
Rml::String format_percent(int value) { return fmt::format("{}%", value); }
|
||||
|
||||
Rml::String format_bool(int value) { return value ? "On" : "Off"; }
|
||||
|
||||
template <typename T>
|
||||
int read_cvar(const ConfigVar<T>& var) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
return static_cast<int>(var.getValue() * 100.0f + 0.5f);
|
||||
} else {
|
||||
return static_cast<int>(var.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write_cvar(ConfigVar<T>& var, int value) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
var.setValue(static_cast<float>(value) / 100.0f);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
var.setValue(static_cast<bool>(value));
|
||||
} else {
|
||||
var.setValue(static_cast<T>(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <auto Var, typename Min, typename Max, typename Def>
|
||||
const GraphicsSetting& bind(Min min, Max max, Def def, int step, Rml::String (*label)(int),
|
||||
bool watchSize = false) {
|
||||
static const GraphicsSetting desc{
|
||||
.min = static_cast<int>(min),
|
||||
.max = static_cast<int>(max),
|
||||
.defaultValue = static_cast<int>(def),
|
||||
.step = step,
|
||||
.watchesRenderSize = watchSize,
|
||||
.read = []() -> int { return read_cvar(Var()); },
|
||||
.write = [](int value) { write_cvar(Var(), value); },
|
||||
.label = label,
|
||||
.cvarName = []() -> const char* { return Var().getName(); },
|
||||
.isModified = []() -> bool { return Var().getValue() != Var().getDefaultValue(); },
|
||||
};
|
||||
return desc;
|
||||
}
|
||||
|
||||
Rml::Element* create_stepped_carousel_root(Rml::Element* parent) {
|
||||
auto* doc = parent->GetOwnerDocument();
|
||||
auto root = doc->CreateElement("div");
|
||||
@@ -129,6 +141,35 @@ void update_carousel_arrow_color(Rml::Element* arrow, bool dim) {
|
||||
|
||||
} // namespace
|
||||
|
||||
const GraphicsSetting& GraphicsSetting::of(GraphicsOption option) {
|
||||
switch (option) {
|
||||
case GraphicsOption::InternalResolution:
|
||||
return bind<[]() -> auto& { return getSettings().game.internalResolutionScale; }>(
|
||||
0, 12, 0, 1, format_internal_resolution, true);
|
||||
case GraphicsOption::ShadowResolution:
|
||||
return bind<[]() -> auto& { return getSettings().game.shadowResolutionMultiplier; }>(
|
||||
1, 8, 1, 1, format_times);
|
||||
case GraphicsOption::Resampler:
|
||||
return bind<[]() -> auto& { return getSettings().game.resampler; }>(
|
||||
Resampler::Bilinear, Resampler::Area, Resampler::Bilinear, 1, format_resampler);
|
||||
case GraphicsOption::BloomMode:
|
||||
return bind<[]() -> auto& { return getSettings().game.bloomMode; }>(
|
||||
BloomMode::Off, BloomMode::Dusk, BloomMode::Classic, 1, format_post_process_mode);
|
||||
case GraphicsOption::BloomMultiplier:
|
||||
return bind<[]() -> auto& { return getSettings().game.bloomMultiplier; }>(
|
||||
0, 100, 100, 10, format_percent);
|
||||
case GraphicsOption::DepthOfFieldMode:
|
||||
return bind<[]() -> auto& { return getSettings().game.depthOfFieldMode; }>(
|
||||
DepthOfFieldMode::Off, DepthOfFieldMode::Dusk, DepthOfFieldMode::Classic, 1,
|
||||
format_post_process_mode);
|
||||
case GraphicsOption::TextureReplacements:
|
||||
return bind<[]() -> auto& { return getSettings().game.enableTextureReplacements; }>(
|
||||
0, 1, 0, 1, format_bool);
|
||||
}
|
||||
DuskLog.error("{} is an invalid GraphicsOption", static_cast<int>(option));
|
||||
abort();
|
||||
}
|
||||
|
||||
SteppedCarousel::SteppedCarousel(Rml::Element* parent, Props props)
|
||||
: Component(create_stepped_carousel_root(parent)), mProps(std::move(props)) {
|
||||
mPrevElem = create_stepped_carousel_arrow(mRoot, "prev", "");
|
||||
@@ -152,7 +193,9 @@ bool SteppedCarousel::focus() {
|
||||
return Component::focus();
|
||||
}
|
||||
|
||||
void SteppedCarousel::update() {
|
||||
void SteppedCarousel::update() {}
|
||||
|
||||
void SteppedCarousel::refresh() {
|
||||
if (mValueElem == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -194,59 +237,9 @@ void SteppedCarousel::apply(int value) {
|
||||
}
|
||||
}
|
||||
|
||||
Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
|
||||
switch (option) {
|
||||
case GraphicsOption::InternalResolution: {
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
AuroraGetRenderSize(&width, &height);
|
||||
if (value <= 0) {
|
||||
return fmt::format("Auto ({}×{})", width, height);
|
||||
} else {
|
||||
return fmt::format("{}× ({}×{})", value, width, height);
|
||||
}
|
||||
}
|
||||
case GraphicsOption::ShadowResolution:
|
||||
return fmt::format("{}×", value);
|
||||
case GraphicsOption::Resampler:
|
||||
switch (static_cast<Resampler>(value)) {
|
||||
case Resampler::Bilinear:
|
||||
return "Bilinear";
|
||||
case Resampler::Area:
|
||||
return "Area";
|
||||
}
|
||||
break;
|
||||
case GraphicsOption::BloomMode:
|
||||
switch (static_cast<BloomMode>(value)) {
|
||||
case BloomMode::Off:
|
||||
return "Off";
|
||||
case BloomMode::Classic:
|
||||
return "Classic";
|
||||
case BloomMode::Dusk:
|
||||
return "Dusklight";
|
||||
}
|
||||
break;
|
||||
case GraphicsOption::DepthOfFieldMode:
|
||||
switch (static_cast<DepthOfFieldMode>(value)) {
|
||||
case DepthOfFieldMode::Off:
|
||||
return "Off";
|
||||
case DepthOfFieldMode::Classic:
|
||||
return "Classic";
|
||||
case DepthOfFieldMode::Dusk:
|
||||
return "Dusklight";
|
||||
}
|
||||
break;
|
||||
case GraphicsOption::BloomMultiplier:
|
||||
return fmt::format("{}%", value);
|
||||
case GraphicsOption::TextureReplacements:
|
||||
return static_cast<bool>(value) ? "On" : "Off";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
GraphicsTuner::GraphicsTuner(GraphicsTunerProps props)
|
||||
: Document(kDocumentSource, false, DocumentScope::GraphicsTuner), mOption(props.option),
|
||||
mValueMin(props.valueMin), mValueMax(props.valueMax), mDefaultValue(props.defaultValue) {
|
||||
: Document(kDocumentSource, false, DocumentScope::GraphicsTuner),
|
||||
mSetting(GraphicsSetting::of(props.option)) {
|
||||
if (mDocument == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -260,13 +253,12 @@ GraphicsTuner::GraphicsTuner(GraphicsTunerProps props)
|
||||
if (auto* carouselParent = mDocument->GetElementById("carousel-container")) {
|
||||
mCarousel = &add_component<SteppedCarousel>(carouselParent,
|
||||
SteppedCarousel::Props{
|
||||
.min = mValueMin,
|
||||
.max = mValueMax,
|
||||
.step = props.step,
|
||||
.getValue = [this] { return get_value(mOption); },
|
||||
.onChange = [this](int value) { set_value(mOption, value); },
|
||||
.formatValue =
|
||||
[this](int value) { return format_graphics_setting_value(mOption, value); },
|
||||
.min = mSetting.min,
|
||||
.max = mSetting.max,
|
||||
.step = mSetting.step,
|
||||
.getValue = [this] { return mSetting.read(); },
|
||||
.onChange = [this](int value) { mSetting.set(value); },
|
||||
.formatValue = [this](int value) { return mSetting.label(value); },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,6 +274,17 @@ GraphicsTuner::GraphicsTuner(GraphicsTunerProps props)
|
||||
resetButton.root()->SetClass("reset", true);
|
||||
}
|
||||
|
||||
if (mCarousel != nullptr) {
|
||||
if (const char* name = mSetting.cvarName()) {
|
||||
mSubscription = config::subscribe(name,
|
||||
[this](config::ConfigVarBase&, const void*) { mCarousel->refresh(); });
|
||||
}
|
||||
mCarousel->refresh();
|
||||
if (mSetting.watchesRenderSize) {
|
||||
AuroraGetRenderSize(&mLastRenderWidth, &mLastRenderHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Hide document after transition completion
|
||||
mRoot = mDocument->GetElementById("root");
|
||||
listen(mRoot, Rml::EventId::Transitionend, [this](Rml::Event& event) {
|
||||
@@ -293,6 +296,12 @@ GraphicsTuner::GraphicsTuner(GraphicsTunerProps props)
|
||||
});
|
||||
}
|
||||
|
||||
GraphicsTuner::~GraphicsTuner() {
|
||||
if (mSubscription != 0) {
|
||||
config::unsubscribe(mSubscription);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsTuner::show() {
|
||||
Document::show();
|
||||
mRoot->SetAttribute("open", "");
|
||||
@@ -309,6 +318,16 @@ void GraphicsTuner::hide(bool close) {
|
||||
}
|
||||
|
||||
void GraphicsTuner::update() {
|
||||
if (mSetting.watchesRenderSize && mCarousel != nullptr) {
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
AuroraGetRenderSize(&width, &height);
|
||||
if (width != mLastRenderWidth || height != mLastRenderHeight) {
|
||||
mLastRenderWidth = width;
|
||||
mLastRenderHeight = height;
|
||||
mCarousel->refresh();
|
||||
}
|
||||
}
|
||||
for (const auto& component : mComponents) {
|
||||
component->update();
|
||||
}
|
||||
@@ -342,7 +361,7 @@ bool GraphicsTuner::handle_nav_command(Rml::Event& event, NavCommand cmd) {
|
||||
}
|
||||
|
||||
void GraphicsTuner::reset_default() {
|
||||
set_value(mOption, mDefaultValue);
|
||||
mSetting.set(mSetting.defaultValue);
|
||||
}
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "button.hpp"
|
||||
#include "component.hpp"
|
||||
#include "document.hpp"
|
||||
#include "ui.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
bool focus() override;
|
||||
void update() override;
|
||||
void refresh();
|
||||
bool handle_nav_command(NavCommand cmd);
|
||||
|
||||
private:
|
||||
@@ -49,21 +50,34 @@ enum class GraphicsOption {
|
||||
TextureReplacements,
|
||||
};
|
||||
|
||||
Rml::String format_graphics_setting_value(GraphicsOption option, int value);
|
||||
struct GraphicsSetting {
|
||||
int min = 0;
|
||||
int max = 0;
|
||||
int defaultValue = 0;
|
||||
int step = 1;
|
||||
bool watchesRenderSize = false;
|
||||
int (*read)() = nullptr;
|
||||
void (*write)(int) = nullptr;
|
||||
Rml::String (*label)(int) = nullptr;
|
||||
const char* (*cvarName)() = nullptr;
|
||||
bool (*isModified)() = nullptr;
|
||||
|
||||
static const GraphicsSetting& of(GraphicsOption option);
|
||||
|
||||
void set(int value) const { write(std::clamp(value, min, max)); }
|
||||
Rml::String text() const { return label(read()); }
|
||||
};
|
||||
|
||||
struct GraphicsTunerProps {
|
||||
GraphicsOption option;
|
||||
Rml::String title;
|
||||
Rml::String helpText;
|
||||
int valueMin = 0;
|
||||
int valueMax = 0;
|
||||
int defaultValue = 0;
|
||||
int step = 1;
|
||||
};
|
||||
|
||||
class GraphicsTuner : public Document {
|
||||
public:
|
||||
explicit GraphicsTuner(GraphicsTunerProps props);
|
||||
~GraphicsTuner() override;
|
||||
|
||||
void show() override;
|
||||
void hide(bool close) override;
|
||||
@@ -85,13 +99,13 @@ private:
|
||||
|
||||
void reset_default();
|
||||
|
||||
GraphicsOption mOption;
|
||||
int mValueMin = 0;
|
||||
int mValueMax = 0;
|
||||
int mDefaultValue = 0;
|
||||
GraphicsSetting mSetting;
|
||||
std::vector<std::unique_ptr<Component> > mComponents;
|
||||
SteppedCarousel* mCarousel;
|
||||
SteppedCarousel* mCarousel = nullptr;
|
||||
Rml::Element* mRoot;
|
||||
u64 mSubscription = 0;
|
||||
u32 mLastRenderWidth = 0;
|
||||
u32 mLastRenderHeight = 0;
|
||||
};
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
@@ -440,24 +440,15 @@ SelectButton& config_int_select(Pane& leftPane, Pane& rightPane, ConfigVar<int>&
|
||||
return button;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void graphics_tuner_control(Window& window, Pane& leftPane, Pane& rightPane, ConfigVar<T>& var,
|
||||
void graphics_tuner_control(Window& window, Pane& leftPane, Pane& rightPane,
|
||||
const GraphicsTunerProps& props) {
|
||||
const auto setting = GraphicsSetting::of(props.option);
|
||||
leftPane.register_control(
|
||||
leftPane
|
||||
.add_select_button({
|
||||
.key = props.title,
|
||||
.getValue =
|
||||
[&var, option = props.option] {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
return format_graphics_setting_value(
|
||||
option, float_setting_percent(var));
|
||||
} else {
|
||||
return format_graphics_setting_value(
|
||||
option, static_cast<int>(var.getValue()));
|
||||
}
|
||||
},
|
||||
.isModified = [&var] { return var.getValue() != var.getDefaultValue(); },
|
||||
.getValue = [setting] { return setting.text(); },
|
||||
.isModified = [setting] { return setting.isModified(); },
|
||||
.submit = false,
|
||||
})
|
||||
.on_nav_command([&window, props](Rml::Event&, NavCommand cmd) {
|
||||
@@ -779,75 +770,50 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
|
||||
leftPane.add_section("Resolution");
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
getSettings().game.internalResolutionScale,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::InternalResolution,
|
||||
.title = "Internal Resolution",
|
||||
.helpText = kInternalResolutionHelpText,
|
||||
.valueMin = 0,
|
||||
.valueMax = 12,
|
||||
.defaultValue = 0,
|
||||
});
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
getSettings().game.shadowResolutionMultiplier,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::ShadowResolution,
|
||||
.title = "Shadow Resolution",
|
||||
.helpText = kShadowResolutionHelpText,
|
||||
.valueMin = 1,
|
||||
.valueMax = 8,
|
||||
.defaultValue = 1,
|
||||
});
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.resampler,
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::Resampler,
|
||||
.title = "Output Resampling",
|
||||
.helpText = kResamplerHelpText,
|
||||
.valueMin = static_cast<int>(Resampler::Bilinear),
|
||||
.valueMax = static_cast<int>(Resampler::Area),
|
||||
.defaultValue = static_cast<int>(Resampler::Bilinear),
|
||||
});
|
||||
|
||||
leftPane.add_section("Post-Processing");
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.bloomMode,
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
GraphicsTunerProps{
|
||||
.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),
|
||||
});
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.bloomMultiplier,
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::BloomMultiplier,
|
||||
.title = "Bloom Brightness",
|
||||
.helpText = kBloomBrightnessHelpText,
|
||||
.valueMin = 0,
|
||||
.valueMax = 100,
|
||||
.defaultValue = 100,
|
||||
.step = 10,
|
||||
});
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.depthOfFieldMode,
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::DepthOfFieldMode,
|
||||
.title = "Depth of Field",
|
||||
.helpText = kDepthOfFieldHelpText,
|
||||
.valueMin = static_cast<int>(DepthOfFieldMode::Off),
|
||||
.valueMax = static_cast<int>(DepthOfFieldMode::Dusk),
|
||||
.defaultValue = static_cast<int>(DepthOfFieldMode::Classic),
|
||||
});
|
||||
|
||||
leftPane.add_section("Rendering");
|
||||
graphics_tuner_control(*this, leftPane, rightPane,
|
||||
getSettings().game.enableTextureReplacements,
|
||||
GraphicsTunerProps{
|
||||
.option = GraphicsOption::TextureReplacements,
|
||||
.title = "Enable Texture Replacements",
|
||||
.helpText = kTextureReplacementHelpText,
|
||||
.valueMin = static_cast<int>(false),
|
||||
.valueMax = static_cast<int>(true),
|
||||
.defaultValue = static_cast<int>(false),
|
||||
});
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
|
||||
+2
-10
@@ -747,16 +747,8 @@ int game_main(int argc, char* argv[]) {
|
||||
} else {
|
||||
AuroraSetViewportPolicy(AURORA_VIEWPORT_STRETCH);
|
||||
}
|
||||
VISetFrameBufferScale(dusk::getSettings().game.internalResolutionScale.getValue());
|
||||
switch (dusk::getSettings().game.resampler.getValue()) {
|
||||
case dusk::Resampler::Area:
|
||||
aurora_set_resampler(SAMPLER_AREA);
|
||||
break;
|
||||
case dusk::Resampler::Bilinear:
|
||||
default:
|
||||
aurora_set_resampler(SAMPLER_BILINEAR);
|
||||
break;
|
||||
}
|
||||
dusk::applyInternalResolutionScale(dusk::getSettings().game.internalResolutionScale.getValue());
|
||||
dusk::applyResampler(dusk::getSettings().game.resampler.getValue());
|
||||
|
||||
dusk::audio::SetMasterVolume(dusk::audio::MasterVolumeToLinear(dusk::getSettings().audio.masterVolume / 100.0f));
|
||||
dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb);
|
||||
|
||||
Reference in New Issue
Block a user