mil arreglos cosmetics a console 2.0

This commit is contained in:
2026-03-30 19:56:31 +02:00
parent cd14ae22c5
commit 32f22c99db
6 changed files with 18111 additions and 1572 deletions

View File

@@ -31,6 +31,7 @@
struct ConsoleCommand {
std::string_view keyword;
std::function<std::string(const std::vector<std::string>& args)> execute;
bool instant{false}; // Si true, muestra la respuesta sin efecto typewriter
};
// Convierte la entrada a uppercase y la divide en tokens por espacios
@@ -70,7 +71,7 @@ static auto parseTokens(const std::string& input) -> std::vector<std::string> {
(toggle_fn); \
return label " OFF"; \
} \
return "Usage: " label " [ON|OFF]"; \
return "usage: " label " [on|off]"; \
}
// Texto de ayuda común para HELP y ?
@@ -155,7 +156,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Screen::get()->setLinearUpscale(true);
return "Upscale: Linear";
}
return "Usage: SS UPSCALE [NEAREST|LINEAR]";
return "usage: ss upscale [nearest|linear]";
}
if (!args.empty() && args[0] == "DOWNSCALE") {
if (args.size() == 1) {
@@ -165,7 +166,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (args[1] == "BILINEAR") { algo = 0; }
if (args[1] == "LANCZOS2") { algo = 1; }
if (args[1] == "LANCZOS3") { algo = 2; }
if (algo == -1) { return "Usage: SS DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]"; }
if (algo == -1) { return "usage: ss downscale [bilinear|lanczos2|lanczos3]"; }
if (Options::video.downscale_algo == algo) {
return std::string("Downscale already ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(algo)]);
}
@@ -186,7 +187,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Screen::get()->toggleSupersampling();
return "PostFX Supersampling OFF";
}
return "Usage: SS [ON|OFF|SIZE|UPSCALE [NEAREST|LINEAR]|DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]]";
return "usage: ss [on|off|size|upscale [nearest|linear]|downscale [bilinear|lanczos2|lanczos3]]";
}},
// SHADER [ON|OFF|NEXT [PRESET]|POSTFX|CRTPI] — Toggle/cicla/selecciona shader (F4 / Shift+F4)
@@ -238,7 +239,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
return std::string("Shader: ") +
(Options::current_shader == Rendering::ShaderType::CRTPI ? "CRTPI" : "POSTFX");
}
return "Usage: SHADER [ON|OFF|NEXT [PRESET]|POSTFX|CRTPI]";
return "usage: shader [on|off|next [preset]|postfx|crtpi]";
}},
// BORDER [ON|OFF] — Borde decorativo (B)
@@ -269,12 +270,12 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Screen::get()->toggleVideoMode();
return std::string("Fullscreen ") + (Options::video.fullscreen ? "ON" : "OFF");
}
return "Usage: FULLSCREEN [ON|OFF]";
return "usage: fullscreen [on|off]";
}},
// ZOOM UP/DOWN — Zoom de ventana (F1/F2)
{.keyword = "ZOOM", .execute = [](const std::vector<std::string>& args) -> std::string {
if (args.empty()) { return "Usage: ZOOM [UP|DOWN]"; }
if (args.empty()) { return "usage: zoom [up|down]"; }
if (args[0] == "UP") {
if (!Screen::get()->incWindowZoom()) { return "Max zoom reached"; }
return "Zoom " + std::to_string(Options::window.zoom);
@@ -283,7 +284,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (!Screen::get()->decWindowZoom()) { return "Min zoom reached"; }
return "Zoom " + std::to_string(Options::window.zoom);
}
return "Usage: ZOOM [UP|DOWN]";
return "usage: zoom [up|down]";
}},
// INTSCALE [ON|OFF] — Escalado entero (F7)
@@ -291,7 +292,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
const bool ON = args.empty() ? !Options::video.integer_scale
: (args[0] == "ON");
if (!args.empty() && args[0] != "ON" && args[0] != "OFF") {
return "Usage: INTSCALE [ON|OFF]";
return "usage: intscale [on|off]";
}
if (ON == Options::video.integer_scale) {
return std::string("IntScale already ") + (ON ? "ON" : "OFF");
@@ -362,7 +363,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// PALETTE NEXT/PREV — Paleta de colores (F5/F6)
{.keyword = "PALETTE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (args.empty()) { return "Usage: PALETTE [NEXT|PREV]"; }
if (args.empty()) { return "usage: palette [next|prev]"; }
if (args[0] == "NEXT") {
Screen::get()->nextPalette();
return "Palette: " + Options::video.palette;
@@ -371,7 +372,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Screen::get()->previousPalette();
return "Palette: " + Options::video.palette;
}
return "Usage: PALETTE [NEXT|PREV]";
return "usage: palette [next|prev]";
}},
#ifdef _DEBUG
@@ -390,7 +391,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
GameControl::toggle_debug_mode();
return "Debug mode OFF";
}
if (!args.empty()) { return "Usage: DEBUG [ON|OFF]"; }
if (!args.empty()) { return "usage: debug [on|off]"; }
GameControl::toggle_debug_mode();
return std::string("Debug mode ") + (Debug::get()->isEnabled() ? "ON" : "OFF");
}},
@@ -398,7 +399,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// ROOM <num>|NEXT|PREV — Cambia a la habitación indicada (1-60); solo en escena GAME
{.keyword = "ROOM", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "Usage: ROOM <1-60>|NEXT|PREV"; }
if (args.empty()) { return "usage: room <1-60>|next|prev"; }
int num = 0;
if (args[0] == "NEXT" || args[0] == "PREV") {
if (!GameControl::get_current_room) { return "Game not initialized"; }
@@ -410,7 +411,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
} else {
try {
num = std::stoi(args[0]);
} catch (...) { return "Usage: ROOM <1-60>|NEXT|PREV"; }
} catch (...) { return "usage: room <1-60>|next|prev"; }
}
if (num < 1 || num > 60) { return "Room must be between 1 and 60"; }
char buf[16];
@@ -434,9 +435,9 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Notifier::get()->show({Locale::get()->get("achievements.header"), Locale::get()->get("achievements.c1")}, Notifier::Style::CHEEVO, -1, false); // NOLINT(readability-static-accessed-through-instance)
return "Cheevo notification shown";
}
if (args.empty() || args[0] != "INFO") { return "Usage: SHOW [INFO|NOTIFICATION|CHEEVO]"; }
if (args.empty() || args[0] != "INFO") { return "usage: show [info|notification|cheevo]"; }
#else
if (args.empty() || args[0] != "INFO") { return "Usage: SHOW [INFO]"; }
if (args.empty() || args[0] != "INFO") { return "usage: show [info]"; }
#endif
if (RenderInfo::get()->isActive()) { return "Info overlay already ON"; }
RenderInfo::get()->toggle();
@@ -445,7 +446,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// HIDE INFO — disponible en Release
{.keyword = "HIDE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (args.empty() || args[0] != "INFO") { return "Usage: HIDE [INFO]"; }
if (args.empty() || args[0] != "INFO") { return "usage: hide [info]"; }
if (!RenderInfo::get()->isActive()) { return "Info overlay already OFF"; }
RenderInfo::get()->toggle();
return "Info overlay OFF";
@@ -454,11 +455,11 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// CHEAT <subcomando> — Trucos de juego; solo en escena GAME; no aparece en ayuda en builds Release
{.keyword = "CHEAT", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "Usage: CHEAT [INFINITE LIVES|INVINCIBILITY|OPEN THE JAIL|CLOSE THE JAIL]"; }
if (args.empty()) { return "usage: cheat [infinite lives|invincibility|open the jail|close the jail]"; }
// CHEAT INFINITE LIVES [ON|OFF]
if (args[0] == "INFINITE") {
if (args.size() < 2 || args[1] != "LIVES") { return "Usage: CHEAT INFINITE LIVES [ON|OFF]"; }
if (args.size() < 2 || args[1] != "LIVES") { return "usage: cheat infinite lives [on|off]"; }
auto& cheat = Options::cheats.infinite_lives;
using State = Options::Cheat::State;
const std::vector<std::string> REST(args.begin() + 2, args.end());
@@ -471,7 +472,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (cheat == State::DISABLED) { return "Infinite lives already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: CHEAT INFINITE LIVES [ON|OFF]";
return "usage: cheat infinite lives [on|off]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Infinite lives ") + (cheat == State::ENABLED ? "ON" : "OFF");
@@ -490,7 +491,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (cheat == State::DISABLED) { return "Invincibility already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: CHEAT INVINCIBILITY [ON|OFF]";
return "usage: cheat invincibility [on|off]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Invincibility ") + (cheat == State::ENABLED ? "ON" : "OFF");
@@ -498,7 +499,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// CHEAT OPEN THE JAIL
if (args[0] == "OPEN") {
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "Usage: CHEAT OPEN THE JAIL"; }
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "usage: cheat open the jail"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::ENABLED) { return "Jail already open"; }
Options::cheats.jail_is_open = Options::Cheat::State::ENABLED;
return "Jail opened";
@@ -506,13 +507,13 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// CHEAT CLOSE THE JAIL
if (args[0] == "CLOSE") {
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "Usage: CHEAT CLOSE THE JAIL"; }
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "usage: cheat close the jail"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::DISABLED) { return "Jail already closed"; }
Options::cheats.jail_is_open = Options::Cheat::State::DISABLED;
return "Jail closed";
}
return "Usage: CHEAT [INFINITE LIVES|INVINCIBILITY|OPEN THE JAIL|CLOSE THE JAIL]";
return "usage: cheat [infinite lives|invincibility|open the jail|close the jail]";
}},
// SET PLAYER SKIN <1|2> — Cambia la skin del jugador (disponible en todos los builds, GAME)
@@ -526,7 +527,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
try {
num = std::stoi(args[2]);
} catch (...) {}
if (num < 1 || num > 2) { return "Usage: SET PLAYER SKIN <1|2>"; }
if (num < 1 || num > 2) { return "usage: set player skin <1|2>"; }
if (!GameControl::change_player_skin) { return "Game not initialized"; }
GameControl::change_player_skin(num);
return "Player skin: " + std::to_string(num);
@@ -571,23 +572,23 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// SET ITEMS <0-200> — Fija el contador de items recogidos
if (args[0] == "ITEMS") {
if (args.size() < 2) { return "Usage: SET ITEMS <0-200>"; }
if (args.size() < 2) { return "usage: set items <0-200>"; }
int count = 0;
try {
count = std::stoi(args[1]);
} catch (...) { return "Usage: SET ITEMS <0-200>"; }
} catch (...) { return "usage: set items <0-200>"; }
if (count < 0 || count > 200) { return "Items must be between 0 and 200"; }
if (!GameControl::set_items) { return "Game not initialized"; }
GameControl::set_items(count);
return "Items: " + std::to_string(count);
}
if (args.empty() || args[0] != "INITIAL") { return "Usage: SET INITIAL [ROOM|POS|SCENE] | SET ITEMS <0-200> | SET PLAYER SKIN <1|2>"; }
if (args.empty() || args[0] != "INITIAL") { return "usage: set initial [room|pos|scene] | set items <0-200> | set player skin <1|2>"; }
const bool DO_ROOM = args.size() == 1 || (args.size() >= 2 && args[1] == "ROOM");
const bool DO_POS = args.size() == 1 || (args.size() >= 2 && args[1] == "POS");
if (!DO_ROOM && !DO_POS) { return "Usage: SET INITIAL [ROOM|POS|SCENE]"; }
if (!DO_ROOM && !DO_POS) { return "usage: set initial [room|pos|scene]"; }
if (!GameControl::set_initial_room || !GameControl::set_initial_pos) { return "Game not initialized"; }
std::string result;
@@ -598,7 +599,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
}
return result;
#else
return "Usage: SET PLAYER SKIN <1|2>";
return "usage: set player skin <1|2>";
#endif
}},
@@ -606,7 +607,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
// SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART] — Cambiar o reiniciar escena; solo en Debug
{.keyword = "SCENE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (Options::kiosk.enabled) { return "Not allowed in kiosk mode"; }
if (args.empty()) { return "Usage: SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART]"; }
if (args.empty()) { return "usage: scene [logo|loading|title|credits|game|ending|ending2|restart]"; }
// RESTART: reinicia la escena actual (funciona desde cualquier escena)
if (args[0] == "RESTART") {
@@ -641,7 +642,8 @@ static const std::vector<ConsoleCommand> COMMANDS = {
{.keyword = "RESTART", .execute = [](const std::vector<std::string>&) -> std::string {
SceneManager::current = SceneManager::Scene::LOGO;
return "Restarting...";
}},
},
.instant = true},
// KIOSK [ON|OFF PLEASE|PLEASE] — Modo kiosko
{.keyword = "KIOSK", .execute = [](const std::vector<std::string>& args) -> std::string {
@@ -660,7 +662,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (!Options::video.fullscreen) { Screen::get()->toggleVideoMode(); }
return "Kiosk mode ON";
}
return "Usage: KIOSK [ON]";
return "usage: kiosk [on]";
}},
// AUDIO [ON|OFF|VOL <0-100>] — Audio maestro (estado + volumen)
@@ -689,9 +691,9 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Options::audio.volume = static_cast<float>(VAL) / 100.0F;
Audio::get()->enable(Options::audio.enabled);
return "Audio vol:" + std::to_string(VAL);
} catch (...) { return "Usage: AUDIO VOL <0-100>"; }
} catch (...) { return "usage: audio vol <0-100>"; }
}
return "Usage: AUDIO [ON|OFF|VOL N]";
return "usage: audio [on|off|vol n]";
}},
// MUSIC [ON|OFF|VOL <0-100>] — Volumen e interruptor de música
@@ -724,9 +726,9 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Audio::get()->setMusicVolume(Options::audio.music.volume);
}
return "Music vol:" + std::to_string(VAL);
} catch (...) { return "Usage: MUSIC VOL <0-100>"; }
} catch (...) { return "usage: music vol <0-100>"; }
}
return "Usage: MUSIC [ON|OFF|VOL N]";
return "usage: music [on|off|vol n]";
}},
// SOUND [ON|OFF|VOL <0-100>] — Volumen e interruptor de efectos de sonido
@@ -759,9 +761,9 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Audio::get()->setSoundVolume(Options::audio.sound.volume);
}
return "Sound vol:" + std::to_string(VAL);
} catch (...) { return "Usage: SOUND VOL <0-100>"; }
} catch (...) { return "usage: sound vol <0-100>"; }
}
return "Usage: SOUND [ON|OFF|VOL N]";
return "usage: sound [on|off|vol n]";
}},
// EXIT / QUIT — Cerrar la aplicacion (bloqueado en kiosk)
@@ -771,14 +773,16 @@ static const std::vector<ConsoleCommand> COMMANDS = {
}
SceneManager::current = SceneManager::Scene::QUIT;
return "Quitting...";
}},
},
.instant = true},
{.keyword = "QUIT", .execute = [](const std::vector<std::string>& args) -> std::string {
if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) {
return "Not allowed in kiosk mode";
}
SceneManager::current = SceneManager::Scene::QUIT;
return "Quitting...";
}},
},
.instant = true},
// SIZE — Devuelve el tamaño actual de la ventana en píxeles
{.keyword = "SIZE", .execute = [](const std::vector<std::string>&) -> std::string {
@@ -793,25 +797,26 @@ static const std::vector<ConsoleCommand> COMMANDS = {
printHelp();
std::string result =
"Commands:\n"
"fullscreen, zoom, intscale, vsync, driver, palette, audio, music, sound, set, restart, kiosk, exit, quit, show, hide, size, help\n"
"-- more info on the terminal";
"fullscreen, zoom, intscale, vsync, driver, palette, audio, music, sound, set, restart, kiosk, exit, quit, show, hide, size, help\n";
#ifdef _DEBUG
result += "\n[debug] debug room scene";
result += "\ncheat";
result +=
"\nDebug commands:\n"
"debug, room, scene, cheat\n";
#endif
result += "-- more info on the terminal";
return result;
}},
{.keyword = "?", .execute = [](const std::vector<std::string>&) -> std::string {
printHelp();
std::string result =
"Commands:\n"
"fullscreen, zoom, intscale, vsync, driver, palette, audio, music, sound, set, restart, kiosk, exit, quit, show, hide, size, help\n"
"-- more info on the terminal";
"fullscreen, zoom, intscale, vsync, driver, palette, audio, music, sound, set, restart, kiosk, exit, quit, show, hide, size, help\n";
#ifdef _DEBUG
result += "\n[debug] debug room scene";
result += "\ncheat";
result +=
"\nDebug commands:\n"
"debug, room, scene, cheat\n";
#endif
result += "-- more info on the terminal";
return result;
}},
};
@@ -1009,6 +1014,9 @@ void Console::update(float delta_time) {
if (y_ <= -height_) {
y_ = -height_;
status_ = Status::HIDDEN;
// Resetear el mensaje una vez completamente oculta
msg_lines_ = {std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION)};
target_height_ = calcTargetHeight(static_cast<int>(msg_lines_.size()));
}
break;
}
@@ -1053,9 +1061,8 @@ void Console::toggle() {
if (on_toggle) { on_toggle(true); }
break;
case Status::ACTIVE:
// Al cerrar: resetear a 1 línea para el próximo ciclo; cerrar con la altura actual
// Al cerrar: mantener el texto visible hasta que esté completamente oculta
status_ = Status::VANISHING;
msg_lines_ = {std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION)};
target_height_ = height_; // No animar durante VANISHING
history_index_ = -1;
saved_input_.clear();
@@ -1132,9 +1139,11 @@ void Console::processCommand() {
const std::vector<std::string> ARGS(TOKENS.begin() + 1, TOKENS.end());
std::string result;
bool found = false;
bool instant = false;
for (const auto& command : COMMANDS) {
if (command.keyword == cmd) {
result = command.execute(ARGS);
instant = command.instant;
found = true;
break;
}
@@ -1147,8 +1156,14 @@ void Console::processCommand() {
// Actualizar la altura objetivo para animar el resize
target_height_ = calcTargetHeight(static_cast<int>(msg_lines_.size()));
// Reiniciar el typewriter para revelar la respuesta letra a letra
typewriter_chars_ = 0;
// Typewriter: instantáneo si el comando lo requiere, letra a letra si no
if (instant) {
int total = 0;
for (const auto& l : msg_lines_) { total += static_cast<int>(l.size()); }
typewriter_chars_ = total;
} else {
typewriter_chars_ = 0;
}
typewriter_timer_ = 0.0F;
}
}