mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-10 15:14:33 -04:00
Modern Menu (#183)
* Add modern menu. Add and include LUS cvars .cmake file for macro usage in modern menu. * Un-ignore new .cmake * Copy new Resolution Editor stuff from 2ship (incomplete). Fix fullscreen checkbox. Finish changes for new UIWidgets. Cleanup ShipUtils. * Remove duplicate asm-differ entry from .gitmodules. * Re-implement Freecam options. * Cleanup freecam character follow buttons. Partially re-implement Multiplayer window as enhancement sidebar (needs text input widget to finish). Cleanup disables. --------- Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
This commit is contained in:
+475
-355
@@ -1,422 +1,542 @@
|
||||
#include "ResolutionEditor.h"
|
||||
#include "UIWidgets.h"
|
||||
#include "libultraship/src/Context.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#include "UIWidgets.h"
|
||||
#include <graphic/Fast3D/gfx_pc.h>
|
||||
#include "port/Engine.h"
|
||||
#include "PortMenu.h"
|
||||
|
||||
/* Console Variables are grouped under gAdvancedResolution. (e.g. "gAdvancedResolution.Enabled")
|
||||
/* Console Variables are grouped under gAdvancedResolution. (e.g. CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled")
|
||||
|
||||
The following CVars are used in Libultraship and can be edited here:
|
||||
The following cvars are used in Libultraship and can be edited here:
|
||||
- Enabled - Turns Advanced Resolution Mode on.
|
||||
- AspectRatioX, AspectRatioY - Aspect ratio controls. To toggle off, set either to zero.
|
||||
- VerticalPixelCount, VerticalResolutionToggle - Resolution controls.
|
||||
- PixelPerfectMode, IntegerScale.Factor - Pixel Perfect Mode a.k.a. integer scaling controls.
|
||||
(Waiting on a second PR merge on LUS for this to fully function.):
|
||||
- IntegerScale.FitAutomatically - Automatic resizing for Pixel Perfect Mode.
|
||||
- IntegerScale.NeverExceedBounds - Prevents manual resizing from exceeding screen bounds.
|
||||
|
||||
The following CVars are also implemented in LUS for niche use cases:
|
||||
The following cvars are also implemented in LUS for niche use cases:
|
||||
- IgnoreAspectCorrection - Stretch framebuffer to fill screen.
|
||||
This is something of a power-user setting for niche setups that most people won't need or care about,
|
||||
but may be useful if playing the Switch/Wii U ports on a 4:3 television.
|
||||
- IntegerScale.ExceedBoundsBy - Offset the max screen bounds, usually by +1.
|
||||
This isn't that useful at the moment.
|
||||
This isn't that useful at the moment, so it's unused here.
|
||||
*/
|
||||
|
||||
namespace AdvancedResolutionSettings {
|
||||
namespace GameUI {
|
||||
extern std::shared_ptr<PortMenu> mPortMenu;
|
||||
enum setting { UPDATE_aspectRatioX, UPDATE_aspectRatioY, UPDATE_verticalPixelCount };
|
||||
|
||||
const char* aspectRatioPresetLabels[] = {
|
||||
"Off", "Custom", "Original (4:3)", "Widescreen (16:9)", "Nintendo 3DS (5:3)", "16:10 (8:5)", "Ultrawide (21:9)"
|
||||
};
|
||||
const float aspectRatioPresetsX[] = { 0.0f, 12.0f, 4.0f, 16.0f, 5.0f, 16.0f, 21.0f };
|
||||
std::unordered_map<int32_t, const char*> aspectRatioPresetLabels = { { 0, "Off" },
|
||||
{ 1, "Custom" },
|
||||
{ 2, "Original (4:3)" },
|
||||
{ 3, "Widescreen (16:9)" },
|
||||
{ 4, "Nintendo 3DS (5:3)" },
|
||||
{ 5, "16:10 (8:5)" },
|
||||
{ 6, "Ultrawide (21:9)" } };
|
||||
const float aspectRatioPresetsX[] = { 0.0f, 16.0f, 4.0f, 16.0f, 5.0f, 16.0f, 21.0f };
|
||||
const float aspectRatioPresetsY[] = { 0.0f, 9.0f, 3.0f, 9.0f, 3.0f, 10.0f, 9.0f };
|
||||
const int default_aspectRatio = 1; // Default combo list option
|
||||
|
||||
const char* pixelCountPresetLabels[] = { "Custom", "Native N64 (240p)", "2x (480p)", "3x (720p)", "4x (960p)",
|
||||
"5x (1200p)", "6x (1440p)", "Full HD (1080p)", "4K (2160p)" };
|
||||
const int pixelCountPresets[] = { 480, 240, 480, 720, 960, 1200, 1440, 1080, 2160, 480 };
|
||||
const int pixelCountPresets[] = { 480, 240, 480, 720, 960, 1200, 1440, 1080, 2160 };
|
||||
const int default_pixelCount = 0; // Default combo list option
|
||||
|
||||
const uint32_t minVerticalPixelCount = 240; // see: Ship::AdvancedResolution()
|
||||
const uint32_t maxVerticalPixelCount = 4320;
|
||||
// Resolution clamp values as hardcoded in LUS::Gui::ApplyResolutionChanges()
|
||||
const uint32_t minVerticalPixelCount = SCREEN_HEIGHT;
|
||||
const uint32_t maxVerticalPixelCount = 4320; // 18x native, or 8K TV resolution
|
||||
|
||||
const unsigned short default_maxIntegerScaleFactor = 6; // Default size of Integer scale factor slider.
|
||||
|
||||
const float enhancementSpacerHeight = 19.0f;
|
||||
// This will need to be determined more intelligently when Hi-DPI UI support is added.
|
||||
enum messageType { MESSAGE_ERROR, MESSAGE_WARNING, MESSAGE_QUESTION, MESSAGE_INFO, MESSAGE_GRAY_75 };
|
||||
const ImVec4 messageColor[]{
|
||||
{ 0.85f, 0.0f, 0.0f, 1.0f }, // MESSAGE_ERROR
|
||||
{ 0.85f, 0.85f, 0.0f, 1.0f }, // MESSAGE_WARNING
|
||||
{ 0.0f, 0.85f, 0.85f, 1.0f }, // MESSAGE_QUESTION
|
||||
{ 0.0f, 0.85f, 0.55f, 1.0f }, // MESSAGE_INFO
|
||||
{ 0.75f, 0.75f, 0.75f, 1.0f } // MESSAGE_GRAY_75
|
||||
};
|
||||
static const float enhancementSpacerHeight = 19.0f;
|
||||
// Initialise update flags.
|
||||
static bool update[3];
|
||||
|
||||
void AdvancedResolutionSettingsWindow::InitElement() {
|
||||
}
|
||||
// Initialise integer scale bounds.
|
||||
static short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get
|
||||
// overridden depending on viewport res
|
||||
|
||||
void AdvancedResolutionSettingsWindow::DrawElement() {
|
||||
ImGui::SetNextWindowSize(ImVec2(497, 532), ImGuiCond_FirstUseEver);
|
||||
if (ImGui::Begin("Advanced Resolution Settings", &mIsVisible)) {
|
||||
// Initialise update flags.
|
||||
bool update[sizeof(setting)];
|
||||
for (unsigned short i = 0; i < sizeof(setting); i++)
|
||||
update[i] = false;
|
||||
static short updateCountdown = 0;
|
||||
short countdownStartingValue = CVarGetInteger("gInterpolationFPS", 30) / 2; // half of a second, in frames.
|
||||
static short integerScale_maximumBounds = 1; // can change when window is resized
|
||||
|
||||
// Initialise integer scale bounds.
|
||||
short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get
|
||||
// overridden depending on viewport res
|
||||
// Combo List defaults
|
||||
static int32_t item_aspectRatio;
|
||||
static int32_t item_pixelCount;
|
||||
// Stored Values for non-UIWidgets elements
|
||||
static float aspectRatioX;
|
||||
static float aspectRatioY;
|
||||
static int32_t verticalPixelCount;
|
||||
// Additional settings
|
||||
static bool showHorizontalResField;
|
||||
static int32_t horizontalPixelCount;
|
||||
// Disabling flags
|
||||
static bool disabled_everything;
|
||||
static bool disabled_pixelCount;
|
||||
|
||||
short integerScale_maximumBounds = 1; // can change when window is resized
|
||||
// This is mostly just for UX purposes, as Fit Automatically logic is part of LUS.
|
||||
if (((float) gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) >
|
||||
((float) gfx_current_dimensions.width / gfx_current_dimensions.height)) {
|
||||
// Scale to window height
|
||||
integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_dimensions.height;
|
||||
} else {
|
||||
// Scale to window width
|
||||
integerScale_maximumBounds = gfx_current_game_window_viewport.width / gfx_current_dimensions.width;
|
||||
}
|
||||
// Lower-clamping maximum bounds value to 1 is no-longer necessary as that's accounted for in LUS.
|
||||
// Letting it go below 1 in this Editor will even allow for checking if screen bounds are being exceeded.
|
||||
if (default_maxIntegerScaleFactor < integerScale_maximumBounds) {
|
||||
max_integerScaleFactor =
|
||||
integerScale_maximumBounds + CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0);
|
||||
}
|
||||
|
||||
// Stored Values for non-UIWidgets elements
|
||||
static float aspectRatioX = CVarGetFloat("gAdvancedResolution.AspectRatioX", 16.0f);
|
||||
static float aspectRatioY = CVarGetFloat("gAdvancedResolution.AspectRatioY", 9.0f);
|
||||
static int verticalPixelCount = CVarGetInteger("gAdvancedResolution.VerticalPixelCount", 480);
|
||||
// Combo List defaults
|
||||
static int item_aspectRatio = default_aspectRatio;
|
||||
static int item_pixelCount = default_pixelCount;
|
||||
// Additional settings
|
||||
static bool showHorizontalResField = false;
|
||||
static int horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
using namespace UIWidgets;
|
||||
|
||||
void RegisterResolutionWidgets() {
|
||||
WidgetPath path = { "Settings", "Graphics", SECTION_COLUMN_2 };
|
||||
#ifdef __APPLE__
|
||||
ImGui::Text("Note: these settings may behave incorrectly on Apple Retina Displays.");
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
mPortMenu
|
||||
->AddWidget(path, ICON_FA_INFO_CIRCLE " These settings may behave incorrectly on Retina displays.", WIDGET_TEXT)
|
||||
.Options(WidgetOptions().Color(Colors::Green));
|
||||
#endif
|
||||
|
||||
// The original resolution slider (for convenience)
|
||||
if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f,
|
||||
"", 1.0f, true, true,
|
||||
(CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0) &&
|
||||
CVarGetInteger("gAdvancedResolution.Enabled", 0)) ||
|
||||
CVarGetInteger("gLowResMode", 0))) {
|
||||
Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
|
||||
}
|
||||
UIWidgets::Tooltip("Multiplies your output resolution by the value entered, as a more intensive but effective "
|
||||
"form of anti-aliasing"); // Description pulled from SohMenuBar.cpp
|
||||
// Resolution visualiser
|
||||
mPortMenu->AddWidget(path, "Viewport dimensions: {} x {}", WIDGET_TEXT).PreFunc([](WidgetInfo& info) {
|
||||
info.name = fmt::format("Viewport dimensions: {} x {}", gfx_current_game_window_viewport.width,
|
||||
gfx_current_game_window_viewport.height);
|
||||
});
|
||||
mPortMenu->AddWidget(path, "Internal resolution: {} x {}", WIDGET_TEXT).PreFunc([](WidgetInfo& info) {
|
||||
info.name =
|
||||
fmt::format("Internal resolution: {} x {}", gfx_current_dimensions.width, gfx_current_dimensions.height);
|
||||
});
|
||||
|
||||
// N64 Mode toggle (again for convenience)
|
||||
// UIWidgets::PaddedEnhancementCheckbox("(Enhancements>Graphics) N64 Mode", "gLowResMode", false, false, false,
|
||||
// "", UIWidgets::CheckboxGraphics::Cross, false);
|
||||
// UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
// Activator
|
||||
mPortMenu->AddWidget(path, "Enable advanced settings.", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled");
|
||||
/*UIWidgets::PaddedEnhancementCheckbox(, , false, false,
|
||||
false, "", UIWidgets::CheckboxGraphics::Cross, false);*/
|
||||
// Error/Warning display
|
||||
mPortMenu
|
||||
->AddWidget(path, ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring.",
|
||||
WIDGET_TEXT)
|
||||
.PreFunc(
|
||||
[](WidgetInfo& info) { info.isHidden = !(!CVarGetInteger(CVAR_LOW_RES_MODE, 0) && IsDroppingFrames()); })
|
||||
.Options(WidgetOptions().Color(Colors::Orange));
|
||||
mPortMenu->AddWidget(path, ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.", WIDGET_TEXT)
|
||||
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
|
||||
.Options(WidgetOptions().Color(Colors::LightBlue));
|
||||
mPortMenu->AddWidget(path, "Click to disable N64 mode", WIDGET_BUTTON)
|
||||
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
|
||||
.Callback([](WidgetInfo& info) {
|
||||
CVarSetInteger(CVAR_LOW_RES_MODE, 0);
|
||||
CVarSave();
|
||||
});
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
// Activator
|
||||
UIWidgets::PaddedEnhancementCheckbox("Enable advanced settings.", "gAdvancedResolution.Enabled", false, false,
|
||||
false, "", UIWidgets::CheckboxGraphics::Cross, false);
|
||||
// Error/Warning display
|
||||
if (!CVarGetInteger("gLowResMode", 0)) {
|
||||
if (IsDroppingFrames()) { // Significant frame drop warning
|
||||
ImGui::TextColored({ 0.85f, 0.85f, 0.0f, 1.0f },
|
||||
ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring.");
|
||||
UIWidgets::Spacer(2);
|
||||
} else { // No warnings
|
||||
UIWidgets::Spacer(enhancementSpacerHeight);
|
||||
// if (disabled_everything) { // Hide aspect ratio controls.
|
||||
// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
// }
|
||||
|
||||
// Aspect Ratio
|
||||
mPortMenu->AddWidget(path, "AspectSep", WIDGET_SEPARATOR);
|
||||
mPortMenu->AddWidget(path, "Force aspect ratio:", WIDGET_TEXT);
|
||||
mPortMenu->AddWidget(path, "(Select \"Off\" to disable.)", WIDGET_TEXT)
|
||||
.SameLine(true)
|
||||
.Options(WidgetOptions().Color(Colors::Gray));
|
||||
// Presets
|
||||
mPortMenu->AddWidget(path, "Aspect Ratio", WIDGET_COMBOBOX)
|
||||
.ValuePointer(&item_aspectRatio)
|
||||
.PreFunc([](WidgetInfo& info) {
|
||||
info.isHidden = !mPortMenu->GetDisabledMap().at(DISABLE_FOR_ADVANCED_RESOLUTION_ON).active;
|
||||
})
|
||||
.Callback([](WidgetInfo& info) {
|
||||
if (item_aspectRatio != default_aspectRatio) { // don't change anything if "Custom" is selected.
|
||||
aspectRatioX = aspectRatioPresetsX[item_aspectRatio];
|
||||
aspectRatioY = aspectRatioPresetsY[item_aspectRatio];
|
||||
|
||||
if (showHorizontalResField) {
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
}
|
||||
|
||||
CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX);
|
||||
CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY);
|
||||
}
|
||||
} else { // N64 Mode warning
|
||||
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
|
||||
ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Click to disable")) {
|
||||
CVarSetInteger("gLowResMode", (int) false);
|
||||
CVarSave();
|
||||
}
|
||||
}
|
||||
// Resolution visualiser
|
||||
ImGui::Text("Viewport dimensions: %d x %d", gfx_current_game_window_viewport.width,
|
||||
gfx_current_game_window_viewport.height);
|
||||
ImGui::Text("Internal resolution: %d x %d", gfx_current_dimensions.width, gfx_current_dimensions.height);
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
// Aspect Ratio
|
||||
ImGui::Text("Force aspect ratio:");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored({ 0.75f, 0.75f, 0.75f, 1.0f }, "(Select \"Off\" to disable.)");
|
||||
if (ImGui::Combo(" ", &item_aspectRatio, aspectRatioPresetLabels,
|
||||
IM_ARRAYSIZE(aspectRatioPresetLabels)) &&
|
||||
item_aspectRatio != default_aspectRatio) { // don't change anything if "Custom" is selected.
|
||||
aspectRatioX = aspectRatioPresetsX[item_aspectRatio];
|
||||
aspectRatioY = aspectRatioPresetsY[item_aspectRatio];
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
update[UPDATE_aspectRatioY] = true;
|
||||
|
||||
if (showHorizontalResField) {
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
}
|
||||
}
|
||||
CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio);
|
||||
CVarSave();
|
||||
})
|
||||
.Options(ComboboxOptions().ComboMap(aspectRatioPresetLabels));
|
||||
mPortMenu->AddWidget(path, "AspectRationCustom", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) {
|
||||
// Hide aspect ratio input fields if using one of the presets.
|
||||
if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) {
|
||||
// Declaring the Y input interaction in particular as a variable beforehand
|
||||
// will prevent a bug where the Y field would disappear when modifying X.
|
||||
bool inputX = ImGui::InputFloat("X", &aspectRatioX, 0.1f, 1.0f, "%.3f");
|
||||
bool inputY = ImGui::InputFloat("Y", &aspectRatioY, 0.1f, 1.0f, "%.3f");
|
||||
if (inputX || inputY) {
|
||||
// Declare input interaction bools outside of IF statement to prevent Y field from disappearing.
|
||||
const bool input_X = ImGui::InputFloat("X", &aspectRatioX, 0.1f, 1.0f, "%.3f");
|
||||
const bool input_Y = ImGui::InputFloat("Y", &aspectRatioY, 0.1f, 1.0f, "%.3f");
|
||||
if (input_X || input_Y) {
|
||||
item_aspectRatio = default_aspectRatio;
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
update[UPDATE_aspectRatioY] = true;
|
||||
}
|
||||
} else if (showHorizontalResField) { // Show calculated aspect ratio
|
||||
if (item_aspectRatio) {
|
||||
UIWidgets::Spacer(2);
|
||||
float resolvedAspectRatio = (float) gfx_current_dimensions.height / gfx_current_dimensions.width;
|
||||
ImGui::Text("Aspect ratio: %.4f", resolvedAspectRatio);
|
||||
} else {
|
||||
UIWidgets::Spacer(enhancementSpacerHeight);
|
||||
ImGui::Dummy({ 0, 2 });
|
||||
const float resolvedAspectRatio = (float)gfx_current_dimensions.width / gfx_current_dimensions.height;
|
||||
ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio);
|
||||
}
|
||||
}
|
||||
});
|
||||
//
|
||||
// if (disabled_everything) { // Hide aspect ratio controls.
|
||||
// UIWidgets::ReEnableComponent("disabledTooltipText");
|
||||
// }
|
||||
// UIWidgets::Spacer(0);
|
||||
//
|
||||
// // Vertical Resolution
|
||||
// UIWidgets::PaddedEnhancementCheckbox("Set fixed vertical resolution (disables Resolution slider)",
|
||||
// CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", true,
|
||||
// false, disabled_everything, "", UIWidgets::CheckboxGraphics::Cross,
|
||||
// false);
|
||||
// UIWidgets::Tooltip(
|
||||
// "Override the resolution scale slider and use the settings below, irrespective of window size.");
|
||||
// if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls.
|
||||
// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
// }
|
||||
// if (ImGui::Combo("Pixel Count Presets", &item_pixelCount, pixelCountPresetLabels,
|
||||
// IM_ARRAYSIZE(pixelCountPresetLabels)) &&
|
||||
// item_pixelCount != default_pixelCount) { // don't change anything if "Custom" is selected.
|
||||
// verticalPixelCount = pixelCountPresets[item_pixelCount];
|
||||
//
|
||||
// if (showHorizontalResField) {
|
||||
// horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// }
|
||||
//
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount);
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount);
|
||||
// CVarSave();
|
||||
// }
|
||||
// // Horizontal Resolution, if visibility is enabled for it.
|
||||
// if (showHorizontalResField) {
|
||||
// // Only show the field if Aspect Ratio is being enforced.
|
||||
// if ((aspectRatioX > 0.0f) && (aspectRatioY > 0.0f)) {
|
||||
// // So basically we're "faking" this one by setting aspectRatioX instead.
|
||||
// if (ImGui::InputInt("Horiz. Pixel Count", &horizontalPixelCount, 8, 320)) {
|
||||
// item_aspectRatio = default_aspectRatio;
|
||||
// if (horizontalPixelCount < SCREEN_WIDTH) {
|
||||
// horizontalPixelCount = SCREEN_WIDTH;
|
||||
// }
|
||||
// aspectRatioX = horizontalPixelCount;
|
||||
// aspectRatioY = verticalPixelCount;
|
||||
// update[UPDATE_aspectRatioX] = true;
|
||||
// update[UPDATE_aspectRatioY] = true;
|
||||
// }
|
||||
// } else { // Display a notice instead.
|
||||
// ImGui::TextColored(messageColor[MESSAGE_QUESTION],
|
||||
// ICON_FA_QUESTION_CIRCLE " \"Force aspect ratio\" required.");
|
||||
// // ImGui::Text(" ");
|
||||
// ImGui::SameLine();
|
||||
// if (ImGui::Button("Click to resolve")) {
|
||||
// item_aspectRatio = default_aspectRatio; // Set it to Custom
|
||||
// aspectRatioX = aspectRatioPresetsX[2]; // but use the 4:3 defaults
|
||||
// aspectRatioY = aspectRatioPresetsY[2];
|
||||
// update[UPDATE_aspectRatioX] = true;
|
||||
// update[UPDATE_aspectRatioY] = true;
|
||||
// horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // Vertical Resolution part 2
|
||||
// if (ImGui::InputInt("Vertical Pixel Count", &verticalPixelCount, 8, 240)) {
|
||||
// item_pixelCount = default_pixelCount;
|
||||
// update[UPDATE_verticalPixelCount] = true;
|
||||
//
|
||||
// // Account for the natural instinct to enter horizontal first.
|
||||
// // Ignore vertical resolutions that are below the lower clamp constant.
|
||||
// if (showHorizontalResField && !(verticalPixelCount < minVerticalPixelCount)) {
|
||||
// item_aspectRatio = default_aspectRatio;
|
||||
// aspectRatioX = horizontalPixelCount;
|
||||
// aspectRatioY = verticalPixelCount;
|
||||
// update[UPDATE_aspectRatioX] = true;
|
||||
// update[UPDATE_aspectRatioY] = true;
|
||||
// }
|
||||
// }
|
||||
// if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls.
|
||||
// UIWidgets::ReEnableComponent("disabledTooltipText");
|
||||
// }
|
||||
//
|
||||
// UIWidgets::Spacer(0);
|
||||
//
|
||||
// // Integer scaling settings group (Pixel-perfect Mode)
|
||||
// static const ImGuiTreeNodeFlags IntegerScalingResolvedImGuiFlag =
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) ? ImGuiTreeNodeFlags_DefaultOpen
|
||||
// : ImGuiTreeNodeFlags_None;
|
||||
// if (ImGui::CollapsingHeader("Integer Scaling Settings", IntegerScalingResolvedImGuiFlag)) {
|
||||
// const bool disabled_pixelPerfectMode =
|
||||
// !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything;
|
||||
// // Pixel-perfect Mode
|
||||
// UIWidgets::PaddedEnhancementCheckbox("Pixel-perfect Mode", CVAR_PREFIX_ADVANCED_RESOLUTION
|
||||
// ".PixelPerfectMode", true,
|
||||
// true, disabled_pixelCount || disabled_everything, "",
|
||||
// UIWidgets::CheckboxGraphics::Cross, false);
|
||||
// UIWidgets::Tooltip("Don't scale image to fill window.");
|
||||
// if (disabled_pixelCount && CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0)) {
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0);
|
||||
// CVarSave();
|
||||
// }
|
||||
//
|
||||
// // Integer Scaling
|
||||
// UIWidgets::EnhancementSliderInt(
|
||||
// "Integer scale factor: %d", "##ARSIntScale", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor",
|
||||
// 1, max_integerScaleFactor, "%d", 1, true, disabled_pixelPerfectMode ||
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0));
|
||||
// UIWidgets::Tooltip("Integer scales the image. Only available in pixel-perfect mode.");
|
||||
// // Display warning if size is being clamped or if framebuffer is larger than viewport.
|
||||
// if (!disabled_pixelPerfectMode &&
|
||||
// (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) &&
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", 1) >
|
||||
// integerScale_maximumBounds)) {
|
||||
// ImGui::SameLine();
|
||||
// ImGui::TextColored(messageColor[MESSAGE_WARNING], ICON_FA_EXCLAMATION_TRIANGLE " Window exceeded.");
|
||||
// }
|
||||
//
|
||||
// UIWidgets::PaddedEnhancementCheckbox(
|
||||
// "Automatically scale image to fit viewport", CVAR_PREFIX_ADVANCED_RESOLUTION
|
||||
// ".IntegerScale.FitAutomatically", true, true, disabled_pixelPerfectMode, "",
|
||||
// UIWidgets::CheckboxGraphics::Cross, false);
|
||||
// UIWidgets::Tooltip("Automatically sets scale factor to fit window. Only available in pixel-perfect
|
||||
// mode."); if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0)) {
|
||||
// // This is just here to update the value shown on the slider.
|
||||
// // The function in LUS to handle this setting will ignore IntegerScaleFactor while active.
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", integerScale_maximumBounds);
|
||||
// // CVarSave();
|
||||
// }
|
||||
// } // End of integer scaling settings
|
||||
//
|
||||
// UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
//
|
||||
// // Collapsible panel for additional settings
|
||||
// if (ImGui::CollapsingHeader("Additional Settings")) {
|
||||
// UIWidgets::Spacer(0);
|
||||
//
|
||||
//#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
// // Disable aspect correction, stretching the framebuffer to fill the viewport.
|
||||
// // This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles.
|
||||
// // The associated cvar is still functional on PC platforms if you want to use it though.
|
||||
// UIWidgets::PaddedEnhancementCheckbox("Disable aspect correction and stretch the output image.\n"
|
||||
// "(Might be useful for 4:3 televisions!)\n"
|
||||
// "Not available in Pixel Perfect Mode.",
|
||||
// CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", false,
|
||||
// true, CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION
|
||||
// ".PixelPerfectMode", 0) ||
|
||||
// disabled_everything,
|
||||
// "", UIWidgets::CheckboxGraphics::Cross, false);
|
||||
//#else
|
||||
// if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0)) {
|
||||
// // This setting is intentionally not exposed on PC platforms,
|
||||
// // but may be accidentally activated for varying reasons.
|
||||
// // Having this button should hopefully prevent support headaches.
|
||||
// ImGui::TextColored(messageColor[MESSAGE_QUESTION], ICON_FA_QUESTION_CIRCLE
|
||||
// " If the image is stretched and you don't know why, click this.");
|
||||
// if (ImGui::Button("Click to reenable aspect correction.")) {
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0);
|
||||
// CVarSave();
|
||||
// }
|
||||
// UIWidgets::Spacer(2);
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
// // A requested addition; an alternative way of displaying the resolution field.
|
||||
// if (ImGui::Checkbox("Show a horizontal resolution field, instead of aspect ratio.",
|
||||
// &showHorizontalResField)) {
|
||||
// if (!showHorizontalResField && (aspectRatioX > 0.0f)) { // when turning this setting off
|
||||
// // Refresh relevant values
|
||||
// aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
// horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// } else { // when turning this setting on
|
||||
// item_aspectRatio = default_aspectRatio;
|
||||
// if (aspectRatioX > 0.0f) {
|
||||
// // Refresh relevant values in the opposite order
|
||||
// horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
// }
|
||||
// }
|
||||
// update[UPDATE_aspectRatioX] = true;
|
||||
// }
|
||||
//
|
||||
// // Beginning of Integer Scaling additional settings.
|
||||
// {
|
||||
// // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
//
|
||||
// // Integer Scaling - Never Exceed Bounds.
|
||||
// const bool disabled_neverExceedBounds =
|
||||
// !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) ||
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0) ||
|
||||
// disabled_everything;
|
||||
// const bool checkbox_neverExceedBounds =
|
||||
// UIWidgets::PaddedEnhancementCheckbox("Prevent integer scaling from exceeding screen bounds.\n"
|
||||
// "(Makes screen bounds take priority over specified
|
||||
// factor.)", CVAR_PREFIX_ADVANCED_RESOLUTION
|
||||
// ".IntegerScale.NeverExceedBounds", true, false,
|
||||
// disabled_neverExceedBounds, "",
|
||||
// UIWidgets::CheckboxGraphics::Cross, true);
|
||||
// UIWidgets::Tooltip(
|
||||
// "Prevents integer scaling factor from exceeding screen bounds.\n\n"
|
||||
// "Enabled: Will clamp the scaling factor and display a gentle warning in the resolution editor.\n"
|
||||
// "Disabled: Will allow scaling to exceed screen bounds, for users who want to crop overscan.\n\n"
|
||||
// " " ICON_FA_INFO_CIRCLE
|
||||
// " Please note that exceeding screen bounds may show a scroll bar on-screen.");
|
||||
//
|
||||
// // Initialise the (currently unused) "Exceed Bounds By" cvar if it's been changed.
|
||||
// if (checkbox_neverExceedBounds &&
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) {
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0);
|
||||
// CVarSave();
|
||||
// }
|
||||
//
|
||||
// // Integer Scaling - Exceed Bounds By 1x/Offset.
|
||||
// // A popular feature in some retro frontends/upscalers, sometimes called "crop overscan" or "1080p
|
||||
// 5x".
|
||||
// /*
|
||||
// UIWidgets::PaddedEnhancementCheckbox("Allow integer scale factor to go +1 above maximum screen
|
||||
// bounds.", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", false, false,
|
||||
// !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything, "",
|
||||
// UIWidgets::CheckboxGraphics::Cross, false);
|
||||
// */
|
||||
// // It does actually function as expected, but exceeding the bottom of the screen shows a scroll bar.
|
||||
// // I've ended up commenting this one out because of the scroll bar, and for simplicity.
|
||||
//
|
||||
// // Display an info message about the scroll bar.
|
||||
// if (!CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) ||
|
||||
// CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) {
|
||||
// if (disabled_neverExceedBounds) { // Dim this help text accordingly
|
||||
// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
// }
|
||||
// ImGui::TextColored(messageColor[MESSAGE_INFO],
|
||||
// " " ICON_FA_INFO_CIRCLE
|
||||
// " A scroll bar may become visible if screen bounds are exceeded.");
|
||||
// if (disabled_neverExceedBounds) { // Dim this help text accordingly
|
||||
// UIWidgets::ReEnableComponent("disabledTooltipText");
|
||||
// }
|
||||
//
|
||||
// // Another support helper button, to disable the unused "Exceed Bounds By" cvar.
|
||||
// // (Remove this button if uncommenting the checkbox.)
|
||||
// if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) {
|
||||
// if (ImGui::Button("Click to reset a console variable that may be causing this.")) {
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0);
|
||||
// CVarSave();
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// ImGui::Text(" ");
|
||||
// }
|
||||
// // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
// } // End of Integer Scaling additional settings.
|
||||
//
|
||||
// } // End of additional settings
|
||||
//
|
||||
// // Clamp and update the cvars that don't use UIWidgets
|
||||
// if (update[UPDATE_aspectRatioX] || update[UPDATE_aspectRatioY] || update[UPDATE_verticalPixelCount]) {
|
||||
// if (update[UPDATE_aspectRatioX]) {
|
||||
// if (aspectRatioX < 0.0f) {
|
||||
// aspectRatioX = 0.0f;
|
||||
// }
|
||||
// CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX);
|
||||
// }
|
||||
// if (update[UPDATE_aspectRatioY]) {
|
||||
// if (aspectRatioY < 0.0f) {
|
||||
// aspectRatioY = 0.0f;
|
||||
// }
|
||||
// CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY);
|
||||
// }
|
||||
// if (update[UPDATE_verticalPixelCount]) {
|
||||
// // There's a upper and lower clamp on the Libultraship side too,
|
||||
// // so clamping it here is entirely visual, so the vertical resolution field reflects it.
|
||||
// if (verticalPixelCount < minVerticalPixelCount) {
|
||||
// verticalPixelCount = minVerticalPixelCount;
|
||||
// }
|
||||
// if (verticalPixelCount > maxVerticalPixelCount) {
|
||||
// verticalPixelCount = maxVerticalPixelCount;
|
||||
// }
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount);
|
||||
// }
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio);
|
||||
// CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount);
|
||||
// CVarSave();
|
||||
// }
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
// Vertical Resolution
|
||||
UIWidgets::PaddedEnhancementCheckbox("Set fixed vertical resolution (disables Resolution slider)",
|
||||
"gAdvancedResolution.VerticalResolutionToggle", true, false, false, "",
|
||||
UIWidgets::CheckboxGraphics::Cross, false);
|
||||
UIWidgets::Tooltip(
|
||||
"Override the resolution scale slider and use the settings below, irrespective of window size.");
|
||||
if (ImGui::Combo("Pixel Count Presets", &item_pixelCount, pixelCountPresetLabels,
|
||||
IM_ARRAYSIZE(pixelCountPresetLabels)) &&
|
||||
item_pixelCount != default_pixelCount) { // don't change anything if "Custom" is selected.
|
||||
verticalPixelCount = pixelCountPresets[item_pixelCount];
|
||||
update[UPDATE_verticalPixelCount] = true;
|
||||
|
||||
if (showHorizontalResField) {
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
void UpdateResolutionVars() {
|
||||
// Clamp and update the cvars that don't use UIWidgets
|
||||
if (update[UPDATE_aspectRatioX] || update[UPDATE_aspectRatioY] || update[UPDATE_verticalPixelCount]) {
|
||||
if (update[UPDATE_aspectRatioX]) {
|
||||
if (aspectRatioX < 0.0f) {
|
||||
aspectRatioX = 0.0f;
|
||||
}
|
||||
CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX);
|
||||
}
|
||||
// Horizontal Resolution, if visibility is enabled for it.
|
||||
if (showHorizontalResField) {
|
||||
// Only show the field if Aspect Ratio is being enforced.
|
||||
if ((aspectRatioX > 0.0f) && (aspectRatioY > 0.0f)) {
|
||||
// So basically we're "faking" this one by setting aspectRatioX instead.
|
||||
if (ImGui::InputInt("Horiz. Pixel Count", &horizontalPixelCount, 8, 320)) {
|
||||
item_aspectRatio = default_aspectRatio;
|
||||
if (horizontalPixelCount < (minVerticalPixelCount / 3.0f) * 4.0f) {
|
||||
horizontalPixelCount = (minVerticalPixelCount / 3.0f) * 4.0f;
|
||||
}
|
||||
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
}
|
||||
} else { // Display a notice instead.
|
||||
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
|
||||
ICON_FA_QUESTION_CIRCLE " \"Force aspect ratio\" required.");
|
||||
// ImGui::Text(" ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Click to resolve")) {
|
||||
item_aspectRatio = default_aspectRatio; // Set it to Custom
|
||||
aspectRatioX = aspectRatioPresetsX[2]; // but use the 4:3 defaults
|
||||
aspectRatioY = aspectRatioPresetsY[2];
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
update[UPDATE_aspectRatioY] = true;
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
}
|
||||
if (update[UPDATE_aspectRatioY]) {
|
||||
if (aspectRatioY < 0.0f) {
|
||||
aspectRatioY = 0.0f;
|
||||
}
|
||||
CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY);
|
||||
}
|
||||
// Vertical Resolution part 2
|
||||
if (ImGui::InputInt("Vertical Pixel Count", &verticalPixelCount, 8, 240)) {
|
||||
item_pixelCount = default_pixelCount;
|
||||
update[UPDATE_verticalPixelCount] = true;
|
||||
|
||||
// Account for the natural instinct to enter horizontal first.
|
||||
// Ignore vertical resolutions that are below the lower clamp constant.
|
||||
if (showHorizontalResField && !(verticalPixelCount < minVerticalPixelCount)) {
|
||||
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
if (update[UPDATE_verticalPixelCount]) {
|
||||
// There's a upper and lower clamp on the Libultraship side too,
|
||||
// so clamping it here is entirely visual, so the vertical resolution field reflects it.
|
||||
if (verticalPixelCount < minVerticalPixelCount) {
|
||||
verticalPixelCount = minVerticalPixelCount;
|
||||
}
|
||||
if (verticalPixelCount > maxVerticalPixelCount) {
|
||||
verticalPixelCount = maxVerticalPixelCount;
|
||||
}
|
||||
CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount);
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
// UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
// Integer scaling settings group
|
||||
if (ImGui::CollapsingHeader("Integer Scaling Settings")) {
|
||||
// Pixel-perfect Mode
|
||||
UIWidgets::PaddedEnhancementCheckbox("Pixel-perfect Mode", "gAdvancedResolution.PixelPerfectMode", true,
|
||||
true,
|
||||
!CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0), "",
|
||||
UIWidgets::CheckboxGraphics::Cross, false);
|
||||
UIWidgets::Tooltip("Don't scale image to fill window.");
|
||||
if (!CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0)) {
|
||||
CVarSetInteger("gAdvancedResolution.PixelPerfectMode", (int) false);
|
||||
CVarSave();
|
||||
}
|
||||
|
||||
// Integer Scaling
|
||||
UIWidgets::EnhancementSliderInt("Integer scale factor: %d", "##ARSIntScale",
|
||||
"gAdvancedResolution.IntegerScale.Factor", 1, max_integerScaleFactor, "%d",
|
||||
1, true,
|
||||
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) ||
|
||||
CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0));
|
||||
UIWidgets::Tooltip("Integer scales the image. Only available in pixel-perfect mode.");
|
||||
// Display warning if size is being clamped or if framebuffer is larger than viewport.
|
||||
if (CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) &&
|
||||
(CVarGetInteger("gAdvancedResolution.IntegerScale.NeverExceedBounds", 1) &&
|
||||
CVarGetInteger("gAdvancedResolution.IntegerScale.Factor", 1) > integerScale_maximumBounds)) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored({ 0.85f, 0.85f, 0.0f, 1.0f }, ICON_FA_EXCLAMATION_TRIANGLE " Window exceeded.");
|
||||
}
|
||||
|
||||
UIWidgets::PaddedEnhancementCheckbox("Automatically scale image to fit viewport",
|
||||
"gAdvancedResolution.IntegerScale.FitAutomatically", true, true,
|
||||
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
|
||||
UIWidgets::CheckboxGraphics::Cross, false);
|
||||
UIWidgets::Tooltip("Automatically sets scale factor to fit window. Only available in pixel-perfect mode.");
|
||||
if (CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0)) {
|
||||
// This is just here to update the value shown on the slider.
|
||||
// The function in LUS to handle this setting will ignore IntegerScaleFactor while active.
|
||||
CVarSetInteger("gAdvancedResolution.IntegerScale.Factor", integerScale_maximumBounds);
|
||||
// CVarSave();
|
||||
}
|
||||
}
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
// Collapsible panel for additional settings
|
||||
if (ImGui::CollapsingHeader("Additional Settings")) {
|
||||
UIWidgets::Spacer(0);
|
||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
// Disable aspect correction, stretching the framebuffer to fill the viewport.
|
||||
// This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles.
|
||||
// The associated CVar is still functional on PC platforms if you want to use it though.
|
||||
UIWidgets::PaddedEnhancementCheckbox("Disable aspect correction and stretch the output image.\n"
|
||||
"(Might be useful for 4:3 televisions!)\n"
|
||||
"Not available in Pixel Perfect Mode.",
|
||||
"gAdvancedResolution.IgnoreAspectCorrection", false, true,
|
||||
CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
|
||||
UIWidgets::CheckboxGraphics::Cross, false);
|
||||
#else
|
||||
if (CVarGetInteger("gAdvancedResolution.IgnoreAspectCorrection", 0)) {
|
||||
// This setting is intentionally not exposed on PC platforms,
|
||||
// but may be accidentally activated for varying reasons.
|
||||
// Having this button should hopefully prevent support headaches.
|
||||
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f }, ICON_FA_QUESTION_CIRCLE
|
||||
" If the image is stretched and you don't know why, click this.");
|
||||
if (ImGui::Button("Click to reenable aspect correction.")) {
|
||||
CVarSetInteger("gAdvancedResolution.IgnoreAspectCorrection", (int) false);
|
||||
CVarSave();
|
||||
}
|
||||
UIWidgets::Spacer(2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ImGui::Checkbox("Show a horizontal resolution field.", &showHorizontalResField)) {
|
||||
if (!showHorizontalResField && (aspectRatioX > 0.0f)) { // when turning this setting off
|
||||
// Refresh relevant values
|
||||
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
} else { // when turning this setting on
|
||||
item_aspectRatio = default_aspectRatio;
|
||||
if (aspectRatioX > 0.0f) {
|
||||
// Refresh relevant values in the opposite order
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
|
||||
}
|
||||
}
|
||||
update[UPDATE_aspectRatioX] = true;
|
||||
}
|
||||
|
||||
UIWidgets::PaddedEnhancementCheckbox(
|
||||
"Don't allow integer scaling to exceed screen bounds.\n"
|
||||
"(Makes screen bounds take priority over specified factor.)",
|
||||
"gAdvancedResolution.IntegerScale.NeverExceedBounds", true, false,
|
||||
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) ||
|
||||
CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0),
|
||||
"", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
|
||||
if (!CVarGetInteger("gAdvancedResolution.IntegerScale.NeverExceedBounds", 1) ||
|
||||
CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
|
||||
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
|
||||
" " ICON_FA_QUESTION_CIRCLE
|
||||
" A scroll bar may become visible if screen bounds are exceeded.");
|
||||
// Another helpful button for an unused CVar.
|
||||
if (CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
|
||||
if (ImGui::Button("Click to reset an unused CVar that may be causing this.")) {
|
||||
CVarSetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0);
|
||||
CVarSave();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UIWidgets::Spacer(enhancementSpacerHeight);
|
||||
}
|
||||
|
||||
// I've ended up dummying this one out because it doesn't function in a satisfactory way.
|
||||
// Consider this idea on the table, but I don't deem it an important enough feature to push for.
|
||||
/*
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow integer scale factor to go 1x above maximum screen bounds.",
|
||||
"gAdvancedResolution.IntegerScale.ExceedBoundsBy", false, false,
|
||||
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
|
||||
UIWidgets::CheckboxGraphics::Cross, false);
|
||||
if (CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
|
||||
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
|
||||
" " ICON_FA_QUESTION_CIRCLE
|
||||
" A scroll bar may become visible if screen bounds are exceeded.");
|
||||
}*/
|
||||
|
||||
} // end of Additional Settings
|
||||
|
||||
// Clamp and update the CVars that don't use UIWidgets
|
||||
if (IsBoolArrayTrue(update)) {
|
||||
if (update[UPDATE_aspectRatioX]) {
|
||||
if (aspectRatioX < 0.0f) {
|
||||
aspectRatioX = 0.0f;
|
||||
}
|
||||
CVarSetFloat("gAdvancedResolution.AspectRatioX", aspectRatioX);
|
||||
}
|
||||
if (update[UPDATE_aspectRatioY]) {
|
||||
if (aspectRatioY < 0.0f) {
|
||||
aspectRatioY = 0.0f;
|
||||
}
|
||||
CVarSetFloat("gAdvancedResolution.AspectRatioY", aspectRatioY);
|
||||
}
|
||||
if (update[UPDATE_verticalPixelCount]) {
|
||||
// There's a upper and lower clamp on the Libultraship side too,
|
||||
// so clamping it here is purely visual, so the vertical resolution field reflects it.
|
||||
if (verticalPixelCount < minVerticalPixelCount) {
|
||||
verticalPixelCount = minVerticalPixelCount;
|
||||
}
|
||||
if (verticalPixelCount > maxVerticalPixelCount) {
|
||||
verticalPixelCount = maxVerticalPixelCount;
|
||||
}
|
||||
CVarSetInteger("gAdvancedResolution.VerticalPixelCount", verticalPixelCount);
|
||||
}
|
||||
// Delay saving this set of CVars by a predetermined length of time, in frames.
|
||||
updateCountdown = countdownStartingValue;
|
||||
}
|
||||
if (updateCountdown > 0) {
|
||||
updateCountdown--;
|
||||
} else {
|
||||
CVarSave();
|
||||
}
|
||||
CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio);
|
||||
CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount);
|
||||
CVarSave();
|
||||
}
|
||||
ImGui::End();
|
||||
// Initialise update flags.
|
||||
for (uint8_t i = 0; i < sizeof(update); i++) {
|
||||
update[i] = false;
|
||||
}
|
||||
|
||||
// Initialise integer scale bounds.
|
||||
short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get
|
||||
// overridden depending on viewport res
|
||||
|
||||
short integerScale_maximumBounds = 1; // can change when window is resized
|
||||
// This is mostly just for UX purposes, as Fit Automatically logic is part of LUS.
|
||||
if (((float)gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) >
|
||||
((float)gfx_current_dimensions.width / gfx_current_dimensions.height)) {
|
||||
// Scale to window height
|
||||
integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_dimensions.height;
|
||||
} else {
|
||||
// Scale to window width
|
||||
integerScale_maximumBounds = gfx_current_game_window_viewport.width / gfx_current_dimensions.width;
|
||||
}
|
||||
// Lower-clamping maximum bounds value to 1 is no-longer necessary as that's accounted for in LUS.
|
||||
// Letting it go below 1 in this Editor will even allow for checking if screen bounds are being exceeded.
|
||||
if (default_maxIntegerScaleFactor < integerScale_maximumBounds) {
|
||||
max_integerScaleFactor = integerScale_maximumBounds +
|
||||
CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0);
|
||||
}
|
||||
|
||||
// Combo List defaults
|
||||
item_aspectRatio = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", 3);
|
||||
item_pixelCount = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", default_pixelCount);
|
||||
// Stored Values for non-UIWidgets elements
|
||||
aspectRatioX = CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioPresetsX[item_aspectRatio]);
|
||||
aspectRatioY = CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioPresetsY[item_aspectRatio]);
|
||||
verticalPixelCount =
|
||||
CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", pixelCountPresets[item_pixelCount]);
|
||||
// Additional settings
|
||||
showHorizontalResField = false;
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// Disabling flags
|
||||
disabled_everything = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0);
|
||||
disabled_pixelCount = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0);
|
||||
}
|
||||
|
||||
void AdvancedResolutionSettingsWindow::UpdateElement() {
|
||||
}
|
||||
|
||||
bool AdvancedResolutionSettingsWindow::IsDroppingFrames() {
|
||||
bool IsDroppingFrames() {
|
||||
// a rather imprecise way of checking for frame drops.
|
||||
// but it's mostly there to inform the player of large drops.
|
||||
const short targetFPS = CVarGetInteger("gInterpolationFPS", 30);
|
||||
const short targetFPS = CVarGetInteger("gInterpolationFPS", 20);
|
||||
const float threshold = targetFPS / 20.0f + 4.1f;
|
||||
return ImGui::GetIO().Framerate < targetFPS - threshold;
|
||||
}
|
||||
|
||||
bool AdvancedResolutionSettingsWindow::IsBoolArrayTrue(bool* foo) {
|
||||
for (unsigned short i = 0; i < sizeof(&foo); i++)
|
||||
if (&foo[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
} // namespace AdvancedResolutionSettings
|
||||
static RegisterMenuUpdateFunc updateFunc(UpdateResolutionVars, "Settings", "Graphics");
|
||||
static RegisterMenuInitFunc initFunc(RegisterResolutionWidgets);
|
||||
|
||||
} // namespace BenGui
|
||||
|
||||
Reference in New Issue
Block a user