presets en yaml
This commit is contained in:
42
source/core/input/global_inputs.cpp
Normal file
42
source/core/input/global_inputs.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "core/input/global_inputs.hpp"
|
||||
|
||||
#include "core/input/input.h"
|
||||
#include "core/rendering/screen.h"
|
||||
|
||||
namespace GlobalInputs {
|
||||
|
||||
auto handle(Screen *screen, Input *input) -> bool {
|
||||
if (screen == nullptr || input == nullptr) { return false; }
|
||||
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_prev_preset, REPEAT_FALSE)) {
|
||||
screen->prevPreset();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_next_preset, REPEAT_FALSE)) {
|
||||
screen->nextPreset();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
return true;
|
||||
}
|
||||
if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace GlobalInputs
|
||||
13
source/core/input/global_inputs.hpp
Normal file
13
source/core/input/global_inputs.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
class Input;
|
||||
class Screen;
|
||||
|
||||
namespace GlobalInputs {
|
||||
// Gestiona els atalls globals disponibles en qualsevol escena: zoom de
|
||||
// finestra (F1/F2), fullscreen (F3), presets de shader (F8/F9), toggle
|
||||
// shader (F10) i tipus de shader POSTFX↔CRTPI (F11). Retorna true si ha
|
||||
// consumit alguna tecla (per si la capa cridant vol suprimir-la del
|
||||
// processament específic de l'escena).
|
||||
auto handle(Screen *screen, Input *input) -> bool;
|
||||
} // namespace GlobalInputs
|
||||
@@ -35,7 +35,8 @@ enum inputs_e {
|
||||
input_window_dec_size,
|
||||
|
||||
// GPU / shaders (hotkeys provisionales hasta que haya menú de opciones)
|
||||
input_toggle_gpu,
|
||||
input_prev_preset,
|
||||
input_next_preset,
|
||||
input_toggle_shader,
|
||||
input_toggle_shader_type,
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ void Screen::registerEmscriptenEventCallbacks() {
|
||||
// ============================================================================
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
// Aplica al backend el preset del shader actiu segons options.
|
||||
// Aplica al backend el shader actiu + els seus presets PostFX i CrtPi.
|
||||
// Només s'ha de cridar quan `videoShaderEnabled=true` (en cas contrari el
|
||||
// blit() ja força POSTFX+zero params per a desactivar els efectes sense
|
||||
// tocar els paràmetres emmagatzemats).
|
||||
@@ -461,16 +461,8 @@ void Screen::applyShaderParams() {
|
||||
return;
|
||||
}
|
||||
shader_backend_->setActiveShader(Options::video.shader.current_shader);
|
||||
|
||||
// Preset per defecte (carregador YAML pendent). Valors estil "CRT" de CCAE.
|
||||
Rendering::PostFXParams POSTFX;
|
||||
POSTFX.vignette = 0.15F;
|
||||
POSTFX.scanlines = 0.7F;
|
||||
POSTFX.chroma = 0.2F;
|
||||
shader_backend_->setPostFXParams(POSTFX);
|
||||
|
||||
// CrtPi: defaults del struct ja raonables (scanline_weight=6.0, bloom=3.5…).
|
||||
shader_backend_->setCrtPiParams(Rendering::CrtPiParams{});
|
||||
applyCurrentPostFXPreset();
|
||||
applyCurrentCrtPiPreset();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -491,6 +483,22 @@ void Screen::initShaders() {
|
||||
if (shader_backend_->isHardwareAccelerated()) {
|
||||
shader_backend_->setScaleMode(Options::video.integer_scale);
|
||||
shader_backend_->setVSync(Options::video.vsync);
|
||||
|
||||
// Resol els índexs de preset a partir del nom emmagatzemat al config.
|
||||
// Si el nom no existeix (preset esborrat del YAML), es queda en 0.
|
||||
for (int i = 0; i < static_cast<int>(Options::postfx_presets.size()); ++i) {
|
||||
if (Options::postfx_presets[i].name == Options::video.shader.current_postfx_preset_name) {
|
||||
Options::current_postfx_preset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < static_cast<int>(Options::crtpi_presets.size()); ++i) {
|
||||
if (Options::crtpi_presets[i].name == Options::video.shader.current_crtpi_preset_name) {
|
||||
Options::current_crtpi_preset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
applyShaderParams(); // aplica preset del shader actiu
|
||||
}
|
||||
#endif
|
||||
@@ -508,22 +516,6 @@ void Screen::shutdownShaders() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::setGpuAcceleration(bool enabled) {
|
||||
if (Options::video.gpu.acceleration == enabled) { return; }
|
||||
Options::video.gpu.acceleration = enabled;
|
||||
// Soft toggle: el backend es manté viu (vegeu shutdownShaders). El canvi
|
||||
// s'aplica al proper arrencada. S'emet una notificació perquè l'usuari
|
||||
// sap que ha tocat la tecla però el canvi no és immediat.
|
||||
const color_t YELLOW = {0xFF, 0xFF, 0x00};
|
||||
const color_t BLACK = {0x00, 0x00, 0x00};
|
||||
const Uint32 DUR_MS = 2500;
|
||||
notify(enabled ? "GPU: ON (restart)" : "GPU: OFF (restart)", YELLOW, BLACK, DUR_MS);
|
||||
}
|
||||
|
||||
void Screen::toggleGpuAcceleration() {
|
||||
setGpuAcceleration(!Options::video.gpu.acceleration);
|
||||
}
|
||||
|
||||
auto Screen::isGpuAccelerated() const -> bool {
|
||||
#ifndef NO_SHADERS
|
||||
return shader_backend_ && shader_backend_->isHardwareAccelerated();
|
||||
@@ -585,3 +577,137 @@ void Screen::toggleActiveShader() {
|
||||
: Rendering::ShaderType::POSTFX;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Presets de shaders
|
||||
// ============================================================================
|
||||
|
||||
void Screen::applyCurrentPostFXPreset() {
|
||||
#ifndef NO_SHADERS
|
||||
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) { return; }
|
||||
if (Options::postfx_presets.empty()) { return; }
|
||||
if (Options::current_postfx_preset < 0
|
||||
|| Options::current_postfx_preset >= static_cast<int>(Options::postfx_presets.size())) {
|
||||
Options::current_postfx_preset = 0;
|
||||
}
|
||||
const auto &PRESET = Options::postfx_presets[Options::current_postfx_preset];
|
||||
Rendering::PostFXParams p;
|
||||
p.vignette = PRESET.vignette;
|
||||
p.scanlines = PRESET.scanlines;
|
||||
p.chroma = PRESET.chroma;
|
||||
p.mask = PRESET.mask;
|
||||
p.gamma = PRESET.gamma;
|
||||
p.curvature = PRESET.curvature;
|
||||
p.bleeding = PRESET.bleeding;
|
||||
p.flicker = PRESET.flicker;
|
||||
shader_backend_->setPostFXParams(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::applyCurrentCrtPiPreset() {
|
||||
#ifndef NO_SHADERS
|
||||
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) { return; }
|
||||
if (Options::crtpi_presets.empty()) { return; }
|
||||
if (Options::current_crtpi_preset < 0
|
||||
|| Options::current_crtpi_preset >= static_cast<int>(Options::crtpi_presets.size())) {
|
||||
Options::current_crtpi_preset = 0;
|
||||
}
|
||||
const auto &PRESET = Options::crtpi_presets[Options::current_crtpi_preset];
|
||||
Rendering::CrtPiParams p;
|
||||
p.scanline_weight = PRESET.scanline_weight;
|
||||
p.scanline_gap_brightness = PRESET.scanline_gap_brightness;
|
||||
p.bloom_factor = PRESET.bloom_factor;
|
||||
p.input_gamma = PRESET.input_gamma;
|
||||
p.output_gamma = PRESET.output_gamma;
|
||||
p.mask_brightness = PRESET.mask_brightness;
|
||||
p.curvature_x = PRESET.curvature_x;
|
||||
p.curvature_y = PRESET.curvature_y;
|
||||
p.mask_type = PRESET.mask_type;
|
||||
p.enable_scanlines = PRESET.enable_scanlines;
|
||||
p.enable_multisample = PRESET.enable_multisample;
|
||||
p.enable_gamma = PRESET.enable_gamma;
|
||||
p.enable_curvature = PRESET.enable_curvature;
|
||||
p.enable_sharper = PRESET.enable_sharper;
|
||||
shader_backend_->setCrtPiParams(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
auto Screen::getCurrentPresetName() const -> const char* {
|
||||
#ifndef NO_SHADERS
|
||||
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) { return "---"; }
|
||||
if (Options::video.shader.current_shader == Rendering::ShaderType::POSTFX) {
|
||||
if (Options::current_postfx_preset >= 0
|
||||
&& Options::current_postfx_preset < static_cast<int>(Options::postfx_presets.size())) {
|
||||
return Options::postfx_presets[Options::current_postfx_preset].name.c_str();
|
||||
}
|
||||
} else {
|
||||
if (Options::current_crtpi_preset >= 0
|
||||
&& Options::current_crtpi_preset < static_cast<int>(Options::crtpi_presets.size())) {
|
||||
return Options::crtpi_presets[Options::current_crtpi_preset].name.c_str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return "---";
|
||||
}
|
||||
|
||||
auto Screen::nextPreset() -> bool {
|
||||
#ifndef NO_SHADERS
|
||||
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) { return false; }
|
||||
if (!Options::video.shader.enabled) { return false; }
|
||||
|
||||
if (Options::video.shader.current_shader == Rendering::ShaderType::POSTFX) {
|
||||
if (Options::postfx_presets.empty()) { return false; }
|
||||
const int N = static_cast<int>(Options::postfx_presets.size());
|
||||
Options::current_postfx_preset = (Options::current_postfx_preset + 1) % N;
|
||||
Options::video.shader.current_postfx_preset_name =
|
||||
Options::postfx_presets[Options::current_postfx_preset].name;
|
||||
applyCurrentPostFXPreset();
|
||||
} else {
|
||||
if (Options::crtpi_presets.empty()) { return false; }
|
||||
const int N = static_cast<int>(Options::crtpi_presets.size());
|
||||
Options::current_crtpi_preset = (Options::current_crtpi_preset + 1) % N;
|
||||
Options::video.shader.current_crtpi_preset_name =
|
||||
Options::crtpi_presets[Options::current_crtpi_preset].name;
|
||||
applyCurrentCrtPiPreset();
|
||||
}
|
||||
|
||||
const color_t GREEN = {0x00, 0xFF, 0x80};
|
||||
const color_t BLACK = {0x00, 0x00, 0x00};
|
||||
const Uint32 DUR_MS = 1500;
|
||||
notify(std::string("Preset: ") + getCurrentPresetName(), GREEN, BLACK, DUR_MS);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
auto Screen::prevPreset() -> bool {
|
||||
#ifndef NO_SHADERS
|
||||
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) { return false; }
|
||||
if (!Options::video.shader.enabled) { return false; }
|
||||
|
||||
if (Options::video.shader.current_shader == Rendering::ShaderType::POSTFX) {
|
||||
if (Options::postfx_presets.empty()) { return false; }
|
||||
const int N = static_cast<int>(Options::postfx_presets.size());
|
||||
Options::current_postfx_preset = (Options::current_postfx_preset - 1 + N) % N;
|
||||
Options::video.shader.current_postfx_preset_name =
|
||||
Options::postfx_presets[Options::current_postfx_preset].name;
|
||||
applyCurrentPostFXPreset();
|
||||
} else {
|
||||
if (Options::crtpi_presets.empty()) { return false; }
|
||||
const int N = static_cast<int>(Options::crtpi_presets.size());
|
||||
Options::current_crtpi_preset = (Options::current_crtpi_preset - 1 + N) % N;
|
||||
Options::video.shader.current_crtpi_preset_name =
|
||||
Options::crtpi_presets[Options::current_crtpi_preset].name;
|
||||
applyCurrentCrtPiPreset();
|
||||
}
|
||||
|
||||
const color_t GREEN = {0x00, 0xFF, 0x80};
|
||||
const color_t BLACK = {0x00, 0x00, 0x00};
|
||||
const Uint32 DUR_MS = 1500;
|
||||
notify(std::string("Preset: ") + getCurrentPresetName(), GREEN, BLACK, DUR_MS);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -63,8 +63,6 @@ class Screen {
|
||||
// GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op.
|
||||
void initShaders(); // Crea el backend GPU si no existe y lo inicializa
|
||||
void shutdownShaders(); // Libera el backend GPU
|
||||
void setGpuAcceleration(bool enabled); // Crea/destruye el backend según valor, persiste options
|
||||
void toggleGpuAcceleration(); // Alterna aceleración GPU
|
||||
auto isGpuAccelerated() const -> bool; // true si el backend existe y reporta hardware OK
|
||||
void setShaderEnabled(bool enabled); // Activa o desactiva el post-procesado (persiste)
|
||||
void toggleShaderEnabled(); // Alterna post-procesado
|
||||
@@ -75,6 +73,14 @@ class Screen {
|
||||
#endif
|
||||
void toggleActiveShader(); // Alterna POSTFX ↔ CRTPI
|
||||
|
||||
// Presets de shaders (PostFX/CrtPi). Operen sobre el shader actiu.
|
||||
// Retornen false si GPU off / shaders off / llista buida (igual que a aee_plus).
|
||||
auto nextPreset() -> bool;
|
||||
auto prevPreset() -> bool;
|
||||
auto getCurrentPresetName() const -> const char*;
|
||||
void applyCurrentPostFXPreset(); // Escriu el preset PostFX actiu al backend
|
||||
void applyCurrentCrtPiPreset(); // Escriu el preset CrtPi actiu al backend
|
||||
|
||||
private:
|
||||
// Helpers internos de setVideoMode
|
||||
void applyFullscreen(bool fullscreen); // SDL_SetWindowFullscreen + visibilidad del cursor
|
||||
|
||||
@@ -64,6 +64,12 @@ Director::Director(int argc, const char *argv[]) {
|
||||
Options::setConfigFile(systemFolder + "/config.yaml");
|
||||
Options::loadFromFile();
|
||||
|
||||
// Presets de shaders (creats amb defaults si no existeixen).
|
||||
Options::setPostFXFile(systemFolder + "/postfx.yaml");
|
||||
Options::loadPostFXFromFile();
|
||||
Options::setCrtPiFile(systemFolder + "/crtpi.yaml");
|
||||
Options::loadCrtPiFromFile();
|
||||
|
||||
// Inicializa el sistema de recursos (pack + fallback).
|
||||
// En wasm siempre se usa filesystem (MEMFS) porque el propio --preload-file
|
||||
// de emscripten ya empaqueta data/ — no hay resources.pack.
|
||||
@@ -202,7 +208,8 @@ void Director::initInput() {
|
||||
input->bindKey(input_window_dec_size, SDL_SCANCODE_F1);
|
||||
input->bindKey(input_window_inc_size, SDL_SCANCODE_F2);
|
||||
input->bindKey(input_window_fullscreen, SDL_SCANCODE_F3);
|
||||
input->bindKey(input_toggle_gpu, SDL_SCANCODE_F9);
|
||||
input->bindKey(input_prev_preset, SDL_SCANCODE_F8);
|
||||
input->bindKey(input_next_preset, SDL_SCANCODE_F9);
|
||||
input->bindKey(input_toggle_shader, SDL_SCANCODE_F10);
|
||||
input->bindKey(input_toggle_shader_type, SDL_SCANCODE_F11);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <iostream> // for basic_ostream, char_traits, operator<<
|
||||
|
||||
#include "core/audio/jail_audio.hpp" // for JA_PlaySound, JA_DeleteSound, JA_LoadSound
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
#include "core/input/input.h" // for inputs_e, Input, REPEAT_TRUE, REPEAT_FALSE
|
||||
#include "core/locale/lang.h" // for Lang
|
||||
#include "core/rendering/fade.h" // for Fade, FADE_CENTER
|
||||
@@ -2517,30 +2518,8 @@ void Game::checkGameInput() {
|
||||
demo.keys.fireLeft = 0;
|
||||
demo.keys.fireRight = 0;
|
||||
|
||||
// Comprueba las teclas de cambiar el tamaño de la centana y el modo de video
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_gpu, REPEAT_FALSE)) {
|
||||
screen->toggleGpuAcceleration();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
}
|
||||
// Atalls globals (zoom finestra, fullscreen, shaders, presets, ...)
|
||||
GlobalInputs::handle(screen, input);
|
||||
|
||||
// Modo Demo activo
|
||||
if (demo.enabled) {
|
||||
|
||||
@@ -22,6 +22,14 @@ namespace Options {
|
||||
Settings settings;
|
||||
std::vector<input_t> inputs;
|
||||
|
||||
std::vector<PostFXPreset> postfx_presets;
|
||||
std::string postfx_file_path;
|
||||
int current_postfx_preset = 0;
|
||||
|
||||
std::vector<CrtPiPreset> crtpi_presets;
|
||||
std::string crtpi_file_path;
|
||||
int current_crtpi_preset = 0;
|
||||
|
||||
// --- Helpers locals ---
|
||||
namespace {
|
||||
void parseBoolField(const fkyaml::node &node, const std::string &key, bool &target) {
|
||||
@@ -339,4 +347,212 @@ namespace Options {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Presets de shaders (postfx.yaml / crtpi.yaml)
|
||||
//
|
||||
// Els defaults viuen en una única font (defaultPostFXPresets / defaultCrtPiPresets).
|
||||
// Generem el YAML a partir d'ells el primer cop i els usem també com a
|
||||
// fallback si el YAML és absent o corrupte. Si algú toca els valors, ho fa
|
||||
// en un sol lloc.
|
||||
// ========================================================================
|
||||
|
||||
namespace {
|
||||
void parseFloatField(const fkyaml::node &node, const std::string &key, float &target) {
|
||||
if (node.contains(key)) {
|
||||
try {
|
||||
target = node[key].get_value<float>();
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
auto defaultPostFXPresets() -> const std::vector<PostFXPreset> & {
|
||||
static const std::vector<PostFXPreset> DEFAULTS = {
|
||||
{"CRT", 0.6F, 0.7F, 0.15F, 0.6F, 0.8F},
|
||||
{"NTSC", 0.4F, 0.5F, 0.2F, 0.4F, 0.5F, 0.0F, 0.6F},
|
||||
{"CURVED", 0.5F, 0.6F, 0.1F, 0.5F, 0.7F, 0.8F},
|
||||
{"SCANLINES", 0.0F, 0.8F},
|
||||
{"SUBTLE", 0.3F, 0.4F, 0.05F, 0.0F, 0.3F},
|
||||
{"CRT LIVE", 0.5F, 0.6F, 0.3F, 0.3F, 0.4F, 0.3F, 0.4F, 0.8F},
|
||||
};
|
||||
return DEFAULTS;
|
||||
}
|
||||
|
||||
auto defaultCrtPiPresets() -> const std::vector<CrtPiPreset> & {
|
||||
static const std::vector<CrtPiPreset> DEFAULTS = {
|
||||
{"Default", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false},
|
||||
{"Curved", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false},
|
||||
{"Sharp", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true},
|
||||
{"Minimal", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false},
|
||||
};
|
||||
return DEFAULTS;
|
||||
}
|
||||
|
||||
void writePostFXDefaults(std::ostream &out) {
|
||||
out << "# Coffee Crisis - PostFX Shader Presets\n\n";
|
||||
out << "presets:\n";
|
||||
for (const auto &p : defaultPostFXPresets()) {
|
||||
out << " - name: \"" << p.name << "\"\n";
|
||||
out << " vignette: " << p.vignette << "\n";
|
||||
out << " scanlines: " << p.scanlines << "\n";
|
||||
out << " chroma: " << p.chroma << "\n";
|
||||
out << " mask: " << p.mask << "\n";
|
||||
out << " gamma: " << p.gamma << "\n";
|
||||
out << " curvature: " << p.curvature << "\n";
|
||||
out << " bleeding: " << p.bleeding << "\n";
|
||||
out << " flicker: " << p.flicker << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void writeCrtPiDefaults(std::ostream &out) {
|
||||
out << "# Coffee Crisis - CrtPi Shader Presets\n\n";
|
||||
out << "presets:\n";
|
||||
for (const auto &p : defaultCrtPiPresets()) {
|
||||
out << " - name: \"" << p.name << "\"\n";
|
||||
out << " scanline_weight: " << p.scanline_weight << "\n";
|
||||
out << " scanline_gap_brightness: " << p.scanline_gap_brightness << "\n";
|
||||
out << " bloom_factor: " << p.bloom_factor << "\n";
|
||||
out << " input_gamma: " << p.input_gamma << "\n";
|
||||
out << " output_gamma: " << p.output_gamma << "\n";
|
||||
out << " mask_brightness: " << p.mask_brightness << "\n";
|
||||
out << " curvature_x: " << p.curvature_x << "\n";
|
||||
out << " curvature_y: " << p.curvature_y << "\n";
|
||||
out << " mask_type: " << p.mask_type << "\n";
|
||||
out << " enable_scanlines: " << boolToString(p.enable_scanlines) << "\n";
|
||||
out << " enable_multisample: " << boolToString(p.enable_multisample) << "\n";
|
||||
out << " enable_gamma: " << boolToString(p.enable_gamma) << "\n";
|
||||
out << " enable_curvature: " << boolToString(p.enable_curvature) << "\n";
|
||||
out << " enable_sharper: " << boolToString(p.enable_sharper) << "\n";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void setPostFXFile(const std::string &path) {
|
||||
postfx_file_path = path;
|
||||
}
|
||||
|
||||
auto loadPostFXFromFile() -> bool {
|
||||
postfx_presets.clear();
|
||||
current_postfx_preset = 0;
|
||||
|
||||
std::ifstream file(postfx_file_path);
|
||||
if (!file.is_open()) {
|
||||
// No existeix: escriu el YAML a partir dels defaults i copia'ls a memòria.
|
||||
std::ofstream out(postfx_file_path);
|
||||
if (out.is_open()) {
|
||||
writePostFXDefaults(out);
|
||||
out.close();
|
||||
}
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string CONTENT((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||
if (yaml.contains("presets")) {
|
||||
for (const auto &p : yaml["presets"]) {
|
||||
PostFXPreset preset;
|
||||
if (p.contains("name")) {
|
||||
try { preset.name = p["name"].get_value<std::string>(); } catch (...) {}
|
||||
}
|
||||
parseFloatField(p, "vignette", preset.vignette);
|
||||
parseFloatField(p, "scanlines", preset.scanlines);
|
||||
parseFloatField(p, "chroma", preset.chroma);
|
||||
parseFloatField(p, "mask", preset.mask);
|
||||
parseFloatField(p, "gamma", preset.gamma);
|
||||
parseFloatField(p, "curvature", preset.curvature);
|
||||
parseFloatField(p, "bleeding", preset.bleeding);
|
||||
parseFloatField(p, "flicker", preset.flicker);
|
||||
postfx_presets.push_back(preset);
|
||||
}
|
||||
}
|
||||
std::cout << "PostFX loaded: " << postfx_presets.size() << " preset(s)\n";
|
||||
} catch (const fkyaml::exception &e) {
|
||||
std::cout << "Error parsing PostFX YAML: " << e.what() << ". Using defaults.\n";
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (postfx_presets.empty()) {
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void setCrtPiFile(const std::string &path) {
|
||||
crtpi_file_path = path;
|
||||
}
|
||||
|
||||
auto loadCrtPiFromFile() -> bool {
|
||||
crtpi_presets.clear();
|
||||
current_crtpi_preset = 0;
|
||||
|
||||
std::ifstream file(crtpi_file_path);
|
||||
if (!file.is_open()) {
|
||||
std::ofstream out(crtpi_file_path);
|
||||
if (out.is_open()) {
|
||||
writeCrtPiDefaults(out);
|
||||
out.close();
|
||||
}
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string CONTENT((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||
if (yaml.contains("presets")) {
|
||||
for (const auto &p : yaml["presets"]) {
|
||||
CrtPiPreset preset;
|
||||
if (p.contains("name")) {
|
||||
try { preset.name = p["name"].get_value<std::string>(); } catch (...) {}
|
||||
}
|
||||
parseFloatField(p, "scanline_weight", preset.scanline_weight);
|
||||
parseFloatField(p, "scanline_gap_brightness", preset.scanline_gap_brightness);
|
||||
parseFloatField(p, "bloom_factor", preset.bloom_factor);
|
||||
parseFloatField(p, "input_gamma", preset.input_gamma);
|
||||
parseFloatField(p, "output_gamma", preset.output_gamma);
|
||||
parseFloatField(p, "mask_brightness", preset.mask_brightness);
|
||||
parseFloatField(p, "curvature_x", preset.curvature_x);
|
||||
parseFloatField(p, "curvature_y", preset.curvature_y);
|
||||
if (p.contains("mask_type")) {
|
||||
try { preset.mask_type = p["mask_type"].get_value<int>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_scanlines")) {
|
||||
try { preset.enable_scanlines = p["enable_scanlines"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_multisample")) {
|
||||
try { preset.enable_multisample = p["enable_multisample"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_gamma")) {
|
||||
try { preset.enable_gamma = p["enable_gamma"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_curvature")) {
|
||||
try { preset.enable_curvature = p["enable_curvature"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_sharper")) {
|
||||
try { preset.enable_sharper = p["enable_sharper"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
crtpi_presets.push_back(preset);
|
||||
}
|
||||
}
|
||||
std::cout << "CrtPi loaded: " << crtpi_presets.size() << " preset(s)\n";
|
||||
} catch (const fkyaml::exception &e) {
|
||||
std::cout << "Error parsing CrtPi YAML: " << e.what() << ". Using defaults.\n";
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crtpi_presets.empty()) {
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Options
|
||||
|
||||
@@ -88,6 +88,38 @@ namespace Options {
|
||||
std::string config_file;
|
||||
};
|
||||
|
||||
// Preset PostFX
|
||||
struct PostFXPreset {
|
||||
std::string name;
|
||||
float vignette{0.0F};
|
||||
float scanlines{0.0F};
|
||||
float chroma{0.0F};
|
||||
float mask{0.0F};
|
||||
float gamma{0.0F};
|
||||
float curvature{0.0F};
|
||||
float bleeding{0.0F};
|
||||
float flicker{0.0F};
|
||||
};
|
||||
|
||||
// Preset CrtPi
|
||||
struct CrtPiPreset {
|
||||
std::string name;
|
||||
float scanline_weight{6.0F};
|
||||
float scanline_gap_brightness{0.12F};
|
||||
float bloom_factor{3.5F};
|
||||
float input_gamma{2.4F};
|
||||
float output_gamma{2.2F};
|
||||
float mask_brightness{0.80F};
|
||||
float curvature_x{0.05F};
|
||||
float curvature_y{0.10F};
|
||||
int mask_type{2};
|
||||
bool enable_scanlines{true};
|
||||
bool enable_multisample{true};
|
||||
bool enable_gamma{true};
|
||||
bool enable_curvature{false};
|
||||
bool enable_sharper{false};
|
||||
};
|
||||
|
||||
// --- Variables globales ---
|
||||
extern Window window;
|
||||
extern Video video;
|
||||
@@ -96,10 +128,26 @@ namespace Options {
|
||||
extern Settings settings;
|
||||
extern std::vector<input_t> inputs; // [0]=KEYBOARD, [1]=GAMECONTROLLER per defecte
|
||||
|
||||
// Presets de shaders (carregats de postfx.yaml / crtpi.yaml al config folder)
|
||||
extern std::vector<PostFXPreset> postfx_presets;
|
||||
extern std::string postfx_file_path;
|
||||
extern int current_postfx_preset; // Índex dins `postfx_presets`
|
||||
|
||||
extern std::vector<CrtPiPreset> crtpi_presets;
|
||||
extern std::string crtpi_file_path;
|
||||
extern int current_crtpi_preset; // Índex dins `crtpi_presets`
|
||||
|
||||
// --- Funciones ---
|
||||
void init(); // Reinicia a defaults i omple `inputs`
|
||||
void setConfigFile(const std::string &file_path); // Ruta del config.yaml
|
||||
auto loadFromFile() -> bool; // Carrega el YAML; si no existeix, crea'l amb defaults
|
||||
auto saveToFile() -> bool; // Guarda el YAML
|
||||
|
||||
// Presets de shaders. Si el fitxer no existeix, l'escriu amb els defaults
|
||||
// i deixa els presets carregats en memòria.
|
||||
void setPostFXFile(const std::string &path);
|
||||
auto loadPostFXFromFile() -> bool;
|
||||
void setCrtPiFile(const std::string &path);
|
||||
auto loadCrtPiFromFile() -> bool;
|
||||
|
||||
} // namespace Options
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
#include <iostream> // for char_traits, basic_ostream, operator<<
|
||||
#include <string> // for basic_string
|
||||
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/locale/lang.h" // for Lang
|
||||
#include "core/rendering/screen.h" // for Screen
|
||||
#include "core/rendering/sprite.h" // for Sprite
|
||||
@@ -218,33 +219,12 @@ void Instructions::checkInput() {
|
||||
if (input->checkInput(input_exit, REPEAT_FALSE)) {
|
||||
quitRequested = true;
|
||||
finished = true;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
}
|
||||
if (GlobalInputs::handle(screen, input)) { return; }
|
||||
|
||||
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_gpu, REPEAT_FALSE)) {
|
||||
screen->toggleGpuAcceleration();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
if (mode == m_auto) {
|
||||
finished = true;
|
||||
} else {
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
#include <string> // for basic_string
|
||||
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic, JA_DeleteMusic, JA_LoadMusic
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic, JA_DeleteMusic, JA_LoadMusic
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/locale/lang.h" // for Lang
|
||||
#include "core/rendering/screen.h" // for Screen
|
||||
#include "core/rendering/smartsprite.h" // for SmartSprite
|
||||
@@ -194,33 +195,12 @@ void Intro::checkInput() {
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (input->checkInput(input_exit, REPEAT_FALSE)) {
|
||||
section->name = SECTION_PROG_QUIT;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
}
|
||||
if (GlobalInputs::handle(screen, input)) { return; }
|
||||
|
||||
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_gpu, REPEAT_FALSE)) {
|
||||
screen->toggleGpuAcceleration();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
JA_StopMusic();
|
||||
section->name = SECTION_PROG_TITLE;
|
||||
section->subsection = SUBSECTION_TITLE_1;
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#include <algorithm> // for min
|
||||
#include <string> // for basic_string
|
||||
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/rendering/screen.h" // for Screen
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
#include "core/input/input.h" // for Input, REPEAT_FALSE, inputs_e
|
||||
#include "core/rendering/screen.h" // for Screen
|
||||
#include "core/rendering/sprite.h" // for Sprite
|
||||
#include "core/rendering/texture.h" // for Texture
|
||||
#include "core/resources/asset.h" // for Asset
|
||||
@@ -77,33 +78,12 @@ void Logo::checkInput() {
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (input->checkInput(input_exit, REPEAT_FALSE)) {
|
||||
section->name = SECTION_PROG_QUIT;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
}
|
||||
if (GlobalInputs::handle(screen, input)) { return; }
|
||||
|
||||
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_gpu, REPEAT_FALSE)) {
|
||||
screen->toggleGpuAcceleration();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
|
||||
section->name = SECTION_PROG_TITLE;
|
||||
section->subsection = SUBSECTION_TITLE_1;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string> // for basic_string, operator+, char_traits
|
||||
|
||||
#include "core/audio/jail_audio.hpp" // for JA_StopMusic, JA_GetMusicState, JA_Play...
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
#include "core/input/input.h" // for Input, INPUT_USE_GAMECONTROLLER, INPUT_...
|
||||
#include "core/locale/lang.h" // for Lang, ba_BA, en_UK, es_ES
|
||||
#include "core/rendering/animatedsprite.h" // for AnimatedSprite
|
||||
@@ -643,31 +644,10 @@ void Title::checkInput() {
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (input->checkInput(input_exit, REPEAT_FALSE)) {
|
||||
section->name = SECTION_PROG_QUIT;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
||||
screen->toggleVideoMode();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
||||
screen->decWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
||||
screen->incWindowZoom();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_gpu, REPEAT_FALSE)) {
|
||||
screen->toggleGpuAcceleration();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
||||
screen->toggleShaderEnabled();
|
||||
}
|
||||
|
||||
else if (input->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
||||
screen->toggleActiveShader();
|
||||
}
|
||||
GlobalInputs::handle(screen, input);
|
||||
}
|
||||
|
||||
// Actualiza el tileado de fondo
|
||||
|
||||
Reference in New Issue
Block a user