- Es pot posar shader preset directament per nom desde la consola

- shader preset i palette ja autocompleten amb la llista de noms
This commit is contained in:
2026-04-01 20:08:55 +02:00
parent ec9a9aff81
commit fe520dd341
8 changed files with 119 additions and 57 deletions

View File

@@ -19,6 +19,7 @@
#include "game/options.hpp" // Para Options
#include "game/scene_manager.hpp" // Para SceneManager
#include "game/ui/notifier.hpp" // Para Notifier
#include "utils/utils.hpp" // Para toUpper, prettyName
#ifdef _DEBUG
#include "core/system/debug.hpp" // Para Debug
@@ -110,7 +111,59 @@ static auto cmd_ss(const std::vector<std::string>& args) -> std::string {
return "usage: ss [on|off|size|upscale [nearest|linear]|downscale [bilinear|lanczos2|lanczos3]]";
}
// SHADER [ON|OFF|NEXT [PRESET]|POSTFX|CRTPI]
// Helper: aplica un preset por dirección (NEXT/PREV) o nombre; devuelve mensaje
static auto applyPreset(const std::vector<std::string>& args) -> std::string {
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
const auto& presets_postfx = Options::postfx_presets;
const auto& presets_crtpi = Options::crtpi_presets;
const std::string shader_label = IS_CRTPI ? "CrtPi" : "PostFX";
auto& current_idx = IS_CRTPI ? Options::video.shader.current_crtpi_preset
: Options::video.shader.current_postfx_preset;
const int count = static_cast<int>(IS_CRTPI ? presets_crtpi.size() : presets_postfx.size());
if (count == 0) { return "No " + shader_label + " presets available"; }
const auto presetName = [&]() -> std::string {
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(current_idx)].name
: presets_postfx[static_cast<size_t>(current_idx)].name;
return prettyName(name);
};
if (args.empty()) {
return shader_label + " preset: " + presetName();
}
if (args[0] == "NEXT") {
current_idx = (current_idx + 1) % count;
} else if (args[0] == "PREV") {
current_idx = (current_idx - 1 + count) % count;
} else {
// Buscar por nombre (case-insensitive, con guiones)
std::string search = args[0];
std::ranges::transform(search, search.begin(), ::toupper);
bool found = false;
for (int i = 0; i < count; ++i) {
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(i)].name
: presets_postfx[static_cast<size_t>(i)].name;
if (toUpper(name) == search) {
current_idx = i;
found = true;
break;
}
}
if (!found) {
std::string name_lower = args[0];
std::ranges::transform(name_lower, name_lower.begin(), ::tolower);
return "Unknown preset: " + name_lower;
}
}
if (IS_CRTPI) { Screen::get()->reloadCrtPi(); } else { Screen::get()->reloadPostFX(); }
return shader_label + " preset: " + presetName();
}
// SHADER [ON|OFF|NEXT|POSTFX|CRTPI|PRESET [NEXT|PREV|<name>]]
static auto cmd_shader(const std::vector<std::string>& args) -> std::string {
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
if (args.empty()) {
@@ -136,29 +189,15 @@ static auto cmd_shader(const std::vector<std::string>& args) -> std::string {
return "Shader: CrtPi";
}
if (args[0] == "NEXT") {
if (args.size() >= 2 && args[1] == "PRESET") {
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
if (Options::crtpi_presets.empty()) { return "No CrtPi presets available"; }
Options::video.shader.current_crtpi_preset =
(Options::video.shader.current_crtpi_preset + 1) %
static_cast<int>(Options::crtpi_presets.size());
Screen::get()->reloadCrtPi();
return "CrtPi preset: " +
Options::crtpi_presets[static_cast<size_t>(Options::video.shader.current_crtpi_preset)].name;
}
if (Options::postfx_presets.empty()) { return "No PostFX presets available"; }
Options::video.shader.current_postfx_preset =
(Options::video.shader.current_postfx_preset + 1) %
static_cast<int>(Options::postfx_presets.size());
Screen::get()->reloadPostFX();
return "PostFX preset: " +
Options::postfx_presets[static_cast<size_t>(Options::video.shader.current_postfx_preset)].name;
}
Screen::get()->nextShader();
return std::string("Shader: ") +
(Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX");
}
return "usage: shader [on|off|next [preset]|postfx|crtpi]";
if (args[0] == "PRESET") {
const std::vector<std::string> rest(args.begin() + 1, args.end());
return applyPreset(rest);
}
return "usage: shader [on|off|next|postfx|crtpi|preset [next|prev|<name>]]";
}
// BORDER [ON|OFF]
@@ -744,6 +783,30 @@ void CommandRegistry::registerHandlers() {
handlers_["cmd_scene"] = cmd_scene;
#endif
// HELP se registra en load() como lambda que captura this
// Proveedores de completions dinámicas
// PALETTE: NEXT, PREV + nombres de paletas disponibles (UPPERCASE)
dynamic_providers_["PALETTE"] = []() -> std::vector<std::string> {
std::vector<std::string> result = {"NEXT", "PREV"};
if (Screen::get() != nullptr) {
for (const auto& name : Screen::get()->getPaletteNames()) {
result.push_back(toUpper(name));
}
}
return result;
};
// SHADER PRESET: NEXT, PREV + nombres de presets del shader activo (UPPERCASE)
dynamic_providers_["SHADER PRESET"] = []() -> std::vector<std::string> {
std::vector<std::string> result = {"NEXT", "PREV"};
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
if (IS_CRTPI) {
for (const auto& p : Options::crtpi_presets) { result.push_back(toUpper(p.name)); }
} else {
for (const auto& p : Options::postfx_presets) { result.push_back(toUpper(p.name)); }
}
return result;
};
}
void CommandRegistry::load(const std::string& yaml_path) {
@@ -914,10 +977,16 @@ auto CommandRegistry::generateConsoleHelp() const -> std::string {
return result;
}
auto CommandRegistry::getCompletions(const std::string& path) const -> const std::vector<std::string>* {
auto CommandRegistry::getCompletions(const std::string& path) const -> std::vector<std::string> {
// Primero: buscar proveedor dinámico (tiene prioridad si existe)
const auto dyn_it = dynamic_providers_.find(path);
if (dyn_it != dynamic_providers_.end()) {
return dyn_it->second();
}
// Fallback: completions estáticas del YAML
const auto it = completions_map_.find(path);
if (it != completions_map_.end()) { return &it->second; }
return nullptr;
if (it != completions_map_.end()) { return it->second; }
return {};
}
auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {
@@ -929,8 +998,3 @@ auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {
}
return result;
}
auto CommandRegistry::hasDynamicCompletions(const std::string& keyword) const -> bool {
const auto* def = findCommand(keyword);
return def != nullptr && def->dynamic_completions;
}