mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-09 20:10:37 -04:00
Add "Output Resampling" option (#1541)
Adds an Output Resampling option to the Video tab to allow choosing between the old Bilinear sampler and a new Area sampler. Area sampling produces a much cleaner, softer image when downscaling, and a significantly sharper image when upscaling. This can also serve as a halfway decent anti-aliasing substitute until we have a more proper implementation.
This commit is contained in:
Vendored
+1
-1
Submodule extern/aurora updated: f93b9e5bc2...10006618ee
@@ -15,6 +15,11 @@ enum class BloomMode : int {
|
||||
Dusk = 2,
|
||||
};
|
||||
|
||||
enum class Resampler : int {
|
||||
Bilinear = 0,
|
||||
Area = 1,
|
||||
};
|
||||
|
||||
enum class GameLanguage : u8 {
|
||||
English = OS_LANGUAGE_ENGLISH,
|
||||
German = OS_LANGUAGE_GERMAN,
|
||||
@@ -47,6 +52,12 @@ struct ConfigEnumRange<BloomMode> {
|
||||
static constexpr auto max = BloomMode::Dusk;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ConfigEnumRange<Resampler> {
|
||||
static constexpr auto min = Resampler::Bilinear;
|
||||
static constexpr auto max = Resampler::Area;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ConfigEnumRange<GameLanguage> {
|
||||
static constexpr auto min = GameLanguage::English;
|
||||
@@ -140,6 +151,7 @@ struct UserSettings {
|
||||
ConfigVar<FrameInterpMode> enableFrameInterpolation;
|
||||
ConfigVar<int> internalResolutionScale;
|
||||
ConfigVar<int> shadowResolutionMultiplier;
|
||||
ConfigVar<Resampler> resampler;
|
||||
ConfigVar<bool> enableDepthOfField;
|
||||
ConfigVar<bool> enableMapBackground;
|
||||
ConfigVar<bool> disableCutscenePillarboxing;
|
||||
|
||||
@@ -176,6 +176,7 @@ namespace dusk::config {
|
||||
template class ConfigImpl<dusk::GameLanguage>;
|
||||
template class ConfigImpl<dusk::GyroMode>;
|
||||
template class ConfigImpl<dusk::FrameInterpMode>;
|
||||
template class ConfigImpl<dusk::Resampler>;
|
||||
}
|
||||
|
||||
void dusk::config::Register(ConfigVarBase& configVar) {
|
||||
|
||||
@@ -63,6 +63,7 @@ UserSettings g_userSettings = {
|
||||
.enableFrameInterpolation {"game.enableFrameInterpolation", FrameInterpMode::Off},
|
||||
.internalResolutionScale {"game.internalResolutionScale", 0},
|
||||
.shadowResolutionMultiplier {"game.shadowResolutionMultiplier", 1},
|
||||
.resampler {"game.resampler", Resampler::Bilinear},
|
||||
.enableDepthOfField {"game.enableDepthOfField", true},
|
||||
.enableMapBackground {"game.enableMapBackground", true},
|
||||
.disableCutscenePillarboxing {"game.disableCutscenePillarboxing", false},
|
||||
@@ -223,6 +224,7 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.disableWaterRefraction);
|
||||
Register(g_userSettings.game.enableTextureReplacements);
|
||||
Register(g_userSettings.game.internalResolutionScale);
|
||||
Register(g_userSettings.game.resampler);
|
||||
Register(g_userSettings.game.shadowResolutionMultiplier);
|
||||
Register(g_userSettings.game.enableDepthOfField);
|
||||
Register(g_userSettings.game.enableMapBackground);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Z2AudioLib/Z2SeMgr.h"
|
||||
#include "m_Do/m_Do_audio.h"
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
#include <dolphin/vi.h>
|
||||
#include <fmt/format.h>
|
||||
@@ -43,6 +44,8 @@ int get_value(GraphicsOption option) {
|
||||
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:
|
||||
@@ -62,6 +65,22 @@ void set_value(GraphicsOption option, int value) {
|
||||
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;
|
||||
}
|
||||
case GraphicsOption::BloomMode:
|
||||
getSettings().game.bloomMode.setValue(static_cast<BloomMode>(std::clamp(
|
||||
value, static_cast<int>(BloomMode::Off), static_cast<int>(BloomMode::Dusk))));
|
||||
@@ -177,6 +196,14 @@ Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
|
||||
}
|
||||
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:
|
||||
|
||||
@@ -42,6 +42,7 @@ private:
|
||||
enum class GraphicsOption {
|
||||
InternalResolution,
|
||||
ShadowResolution,
|
||||
Resampler,
|
||||
BloomMode,
|
||||
BloomMultiplier,
|
||||
};
|
||||
|
||||
@@ -357,6 +357,8 @@ const Rml::String kInternalResolutionHelpText =
|
||||
const Rml::String kShadowResolutionHelpText =
|
||||
"Configure the shadow-map resolution. Higher values improve shadow quality but increase GPU "
|
||||
"and memory usage.";
|
||||
const Rml::String kResamplerHelpText =
|
||||
"Configure the sampling method used when scaling the internal resolution for final presentation.";
|
||||
const Rml::String kBloomHelpText =
|
||||
"Configure the post-processing bloom effect. Classic uses the original bloom pass; Dusklight uses "
|
||||
"a higher-quality bloom pass.";
|
||||
@@ -805,6 +807,15 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
.valueMax = 8,
|
||||
.defaultValue = 1,
|
||||
}, mPrelaunch);
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.resampler,
|
||||
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),
|
||||
}, mPrelaunch);
|
||||
|
||||
leftPane.add_section("Post-Processing");
|
||||
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.bloomMode,
|
||||
|
||||
@@ -604,6 +604,15 @@ int game_main(int argc, char* argv[]) {
|
||||
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::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