GlobalInputs F1-F12 + Escape, Screen sense destruir finestra, escalat al GPU, presets i fons canvas (v0.11.0)
This commit is contained in:
1 parent
837eb73398
commit
297dc85e47
23 files changed
+653
-34
No files matched your search
@@ -0,0 +1,191 @@
|
||||
#include "core/input/global_inputs.hpp"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "core/input/key_config.hpp"
|
||||
#include "core/locale/locale.hpp"
|
||||
#include "core/rendering/notifier.hpp"
|
||||
#include "core/rendering/render_info.hpp"
|
||||
#include "core/rendering/screen.hpp"
|
||||
#include "core/system/event_buffer.hpp"
|
||||
#include "game/options.hpp"
|
||||
#include "utils/defaults.hpp"
|
||||
|
||||
namespace GlobalInputs {
|
||||
|
||||
namespace {
|
||||
|
||||
// Finestra per a confirmar l'eixida amb una segona pulsació d'Escape.
|
||||
constexpr float EXIT_WINDOW_S = 1.5F;
|
||||
constexpr int MIN_ZOOM = 1;
|
||||
constexpr int MAX_ZOOM = 6;
|
||||
|
||||
float exit_window_s = 0.0F;
|
||||
bool quit_requested = false;
|
||||
|
||||
// Canvia uniforms i shader actiu sense recrear la finestra.
|
||||
void reapplyShader() {
|
||||
Screen::get().setActiveShader(Options::buildActiveShader());
|
||||
Screen::get().applyPostFXParams(Options::buildPostFXParams());
|
||||
Screen::get().applyCrtPiParams(Options::buildCrtPiParams());
|
||||
}
|
||||
|
||||
void notifyLocale(const std::string& key) {
|
||||
Notifier::get().notify(Locale::get().text(key));
|
||||
}
|
||||
|
||||
void onDecZoom() {
|
||||
if (Options::window.fullscreen) { return; }
|
||||
if (Options::window.zoom <= MIN_ZOOM) { return; }
|
||||
Options::window.zoom--;
|
||||
Screen::get().setWindowZoom(Options::window.zoom);
|
||||
Options::saveToFile();
|
||||
Notifier::get().notify(Locale::get().text("input.zoom") + " x" + std::to_string(Options::window.zoom));
|
||||
}
|
||||
|
||||
void onIncZoom() {
|
||||
if (Options::window.fullscreen) { return; }
|
||||
if (Options::window.zoom >= MAX_ZOOM) { return; }
|
||||
Options::window.zoom++;
|
||||
Screen::get().setWindowZoom(Options::window.zoom);
|
||||
Options::saveToFile();
|
||||
Notifier::get().notify(Locale::get().text("input.zoom") + " x" + std::to_string(Options::window.zoom));
|
||||
}
|
||||
|
||||
void onFullscreen() {
|
||||
Options::window.fullscreen = !Options::window.fullscreen;
|
||||
Screen::get().setFullscreen(Options::window.fullscreen);
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::window.fullscreen ? "input.fullscreen_on" : "input.fullscreen_off");
|
||||
}
|
||||
|
||||
void onToggleVSync() {
|
||||
Options::video.vsync = !Options::video.vsync;
|
||||
Screen::get().setVSync(Options::video.vsync);
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::video.vsync ? "input.vsync_on" : "input.vsync_off");
|
||||
}
|
||||
|
||||
void onToggleShader() {
|
||||
Options::video.shader.enabled = !Options::video.shader.enabled;
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::video.shader.enabled ? "input.shader_on" : "input.shader_off");
|
||||
}
|
||||
|
||||
void onNextShader() {
|
||||
Options::video.shader.current_shader = (Options::video.shader.current_shader == "crtpi") ? "postfx" : "crtpi";
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
Notifier::get().notify(Locale::get().text("input.shader") + ": " + Options::video.shader.current_shader);
|
||||
}
|
||||
|
||||
// Busca l'entrada actual al vector de presets i passa a la següent
|
||||
// (wrap-around). Si no en troba cap s'evita el canvi silenciosament.
|
||||
void onNextPreset() {
|
||||
const bool IS_CRTPI = Options::video.shader.current_shader == "crtpi";
|
||||
if (IS_CRTPI) {
|
||||
if (Options::crtpi_presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(Options::crtpi_presets,
|
||||
[](const auto& preset) { return preset.name == Options::video.shader.current_crtpi_preset; });
|
||||
std::size_t idx = (it == Options::crtpi_presets.end()) ? 0 : std::distance(Options::crtpi_presets.begin(), it);
|
||||
idx = (idx + 1) % Options::crtpi_presets.size();
|
||||
Options::video.shader.current_crtpi_preset = Options::crtpi_presets[idx].name;
|
||||
} else {
|
||||
if (Options::postfx_presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(Options::postfx_presets,
|
||||
[](const auto& preset) { return preset.name == Options::video.shader.current_postfx_preset; });
|
||||
std::size_t idx = (it == Options::postfx_presets.end()) ? 0 : std::distance(Options::postfx_presets.begin(), it);
|
||||
idx = (idx + 1) % Options::postfx_presets.size();
|
||||
Options::video.shader.current_postfx_preset = Options::postfx_presets[idx].name;
|
||||
}
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
const std::string& name = IS_CRTPI ? Options::video.shader.current_crtpi_preset : Options::video.shader.current_postfx_preset;
|
||||
Notifier::get().notify(Locale::get().text("input.preset") + ": " + name);
|
||||
}
|
||||
|
||||
void onNextScalingMode() {
|
||||
using Mode = Defaults::ScalingMode;
|
||||
Options::video.scaling_mode = static_cast<Mode>((static_cast<int>(Options::video.scaling_mode) + 1) % 5);
|
||||
Screen::get().setScalingMode(Options::video.scaling_mode);
|
||||
Options::saveToFile();
|
||||
const char* mode_key = nullptr;
|
||||
switch (Options::video.scaling_mode) {
|
||||
case Mode::DISABLED:
|
||||
mode_key = "input.scaling_disabled";
|
||||
break;
|
||||
case Mode::STRETCH:
|
||||
mode_key = "input.scaling_stretch";
|
||||
break;
|
||||
case Mode::LETTERBOX:
|
||||
mode_key = "input.scaling_letterbox";
|
||||
break;
|
||||
case Mode::OVERSCAN:
|
||||
mode_key = "input.scaling_overscan";
|
||||
break;
|
||||
case Mode::INTEGER:
|
||||
mode_key = "input.scaling_integer";
|
||||
break;
|
||||
}
|
||||
notifyLocale(mode_key);
|
||||
}
|
||||
|
||||
void onToggleRenderInfo() {
|
||||
RenderInfo::get().toggle();
|
||||
}
|
||||
|
||||
void onExit() {
|
||||
if (exit_window_s > 0.0F) {
|
||||
quit_requested = true;
|
||||
return;
|
||||
}
|
||||
exit_window_s = EXIT_WINDOW_S;
|
||||
// La notificació dura el doble de la finestra; si l'usuari no
|
||||
// prem una segona volta abans del timeout, es desarmarà sol.
|
||||
Notifier::get().notify(Locale::get().text("input.press_again_exit"),
|
||||
Notification::DEFAULT.text_color,
|
||||
Notification::DEFAULT.bg_color,
|
||||
static_cast<int>(EXIT_WINDOW_S * 1000.0F));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void update(int delta_ms) {
|
||||
exit_window_s = std::max(0.0F, exit_window_s - (static_cast<float>(delta_ms) / 1000.0F));
|
||||
|
||||
for (const auto& event : EventBuffer::events) {
|
||||
if (event.type != SDL_EVENT_KEY_DOWN) { continue; }
|
||||
const auto SC = event.key.scancode;
|
||||
if (SC == KeyConfig::get().scancode("dec_zoom")) {
|
||||
onDecZoom();
|
||||
} else if (SC == KeyConfig::get().scancode("inc_zoom")) {
|
||||
onIncZoom();
|
||||
} else if (SC == KeyConfig::get().scancode("fullscreen")) {
|
||||
onFullscreen();
|
||||
} else if (SC == KeyConfig::get().scancode("toggle_shader")) {
|
||||
onToggleShader();
|
||||
} else if (SC == KeyConfig::get().scancode("toggle_vsync")) {
|
||||
onToggleVSync();
|
||||
} else if (SC == KeyConfig::get().scancode("next_shader")) {
|
||||
onNextShader();
|
||||
} else if (SC == KeyConfig::get().scancode("next_preset")) {
|
||||
onNextPreset();
|
||||
} else if (SC == KeyConfig::get().scancode("next_scaling_mode")) {
|
||||
onNextScalingMode();
|
||||
} else if (SC == KeyConfig::get().scancode("toggle_render_info")) {
|
||||
onToggleRenderInfo();
|
||||
} else if (SC == KeyConfig::get().scancode("exit")) {
|
||||
onExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto wantsQuit() -> bool {
|
||||
return quit_requested;
|
||||
}
|
||||
|
||||
} // namespace GlobalInputs
|
||||
Reference in new issue
Block a user