From c3d24cc07d2b6be19e54bd3874bc03a55df2aa23 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 18 Oct 2025 19:00:16 +0200 Subject: [PATCH] feat: Argumentos CLI para establecer AppMode inicial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Permite arrancar directamente en modo DEMO, DEMO_LITE, LOGO o SANDBOX mediante argumentos de línea de comandos, eliminando necesidad de cambiar manualmente el modo después del arranque. Nuevos argumentos: - `-m, --mode ` - Establece modo inicial - `sandbox` - Control manual (default) - `demo` - Auto-play completo (figuras + temas + colisiones) - `demo-lite` - Auto-play simple (solo física/figuras) - `logo` - Modo logo (easter egg con convergencia) Ejemplos de uso: ```bash # Arrancar en modo DEMO ./vibe3_physics --mode demo ./vibe3_physics -m demo # Arrancar en DEMO_LITE (solo física) ./vibe3_physics -m demo-lite # Arrancar directo en LOGO ./vibe3_physics --mode logo # Combinar con otros argumentos ./vibe3_physics -w 1920 -h 1080 --mode demo ./vibe3_physics -F -m demo-lite # Fullscreen + DEMO_LITE ``` Implementación: 1. main.cpp: Parsing de argumento --mode con validación 2. engine.h: Nuevo parámetro `initial_mode` en initialize() 3. engine.cpp: Aplicación del modo vía StateManager::setState() Si no se especifica --mode, se usa SANDBOX (comportamiento actual). El modo se aplica después de inicializar StateManager, garantizando que todos los componentes estén listos antes del cambio de estado. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- source/defines.h | 6 +++--- source/engine.cpp | 7 ++++++- source/engine.h | 2 +- source/main.cpp | 30 ++++++++++++++++++++++++++++-- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/source/defines.h b/source/defines.h index d46a234..a24a8fc 100644 --- a/source/defines.h +++ b/source/defines.h @@ -289,9 +289,9 @@ constexpr float LOGO_FLIP_TRIGGER_MAX = 0.80f; // 80% máximo de progres constexpr int LOGO_FLIP_WAIT_PROBABILITY = 50; // 50% probabilidad de elegir el camino "esperar flip" // Configuración de AppLogo (logo periódico en pantalla) -constexpr float APPLOGO_DISPLAY_INTERVAL = 20.0f; // Intervalo entre apariciones del logo (segundos) -constexpr float APPLOGO_DISPLAY_DURATION = 5.0f; // Duración de visibilidad del logo (segundos) -constexpr float APPLOGO_FADE_DURATION = 0.5f; // Duración del fade in/out (segundos) +constexpr float APPLOGO_DISPLAY_INTERVAL = 5.0f; // Intervalo entre apariciones del logo (segundos) +constexpr float APPLOGO_DISPLAY_DURATION = 10.0f; // Duración de visibilidad del logo (segundos) +constexpr float APPLOGO_FADE_DURATION = 1.9f; // Duración del fade in/out (segundos) constexpr float APPLOGO_HEIGHT_PERCENT = 0.4f; // Altura del logo = 40% de la altura de pantalla constexpr float APPLOGO_PADDING_PERCENT = 0.1f; // Padding desde esquina inferior-derecha = 10% constexpr float APPLOGO_LOGO2_DELAY = 0.25f; // Retraso de Logo 2 respecto a Logo 1 (segundos) diff --git a/source/engine.cpp b/source/engine.cpp index b810c7f..f9575f5 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -37,7 +37,7 @@ // getExecutableDirectory() ya está definido en defines.h como inline // Implementación de métodos públicos -bool Engine::initialize(int width, int height, int zoom, bool fullscreen) { +bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMode initial_mode) { bool success = true; // Obtener resolución de pantalla para validación @@ -246,6 +246,11 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) { state_manager_ = std::make_unique(); state_manager_->initialize(this); // Callback al Engine + // Establecer modo inicial si no es SANDBOX (default) + if (initial_mode != AppMode::SANDBOX) { + state_manager_->setState(initial_mode, current_screen_width_, current_screen_height_); + } + // Actualizar ShapeManager con StateManager (dependencia circular - StateManager debe existir primero) shape_manager_->initialize(this, scene_manager_.get(), ui_manager_.get(), state_manager_.get(), current_screen_width_, current_screen_height_); diff --git a/source/engine.h b/source/engine.h index 8ce5dad..6ffc418 100644 --- a/source/engine.h +++ b/source/engine.h @@ -26,7 +26,7 @@ class Engine { public: // Interfaz pública principal - bool initialize(int width = 0, int height = 0, int zoom = 0, bool fullscreen = false); + bool initialize(int width = 0, int height = 0, int zoom = 0, bool fullscreen = false, AppMode initial_mode = AppMode::SANDBOX); void run(); void shutdown(); diff --git a/source/main.cpp b/source/main.cpp index 411fba4..b2be446 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,6 +1,8 @@ #include #include +#include #include "engine.h" +#include "defines.h" // getExecutableDirectory() ya está definido en defines.h como inline @@ -13,13 +15,17 @@ void printHelp() { std::cout << " -z, --zoom Zoom de ventana (default: 3)\n"; std::cout << " -f, --fullscreen Modo pantalla completa (F3 - letterbox)\n"; std::cout << " -F, --real-fullscreen Modo pantalla completa real (F4 - nativo)\n"; + std::cout << " -m, --mode Modo inicial: sandbox, demo, demo-lite, logo (default: sandbox)\n"; std::cout << " --help Mostrar esta ayuda\n\n"; std::cout << "Ejemplos:\n"; std::cout << " vibe3_physics # 320x240 zoom 3 (ventana 960x720)\n"; std::cout << " vibe3_physics -w 1920 -h 1080 # 1920x1080 zoom 1 (auto)\n"; std::cout << " vibe3_physics -w 640 -h 480 -z 2 # 640x480 zoom 2 (ventana 1280x960)\n"; std::cout << " vibe3_physics -f # Fullscreen letterbox (F3)\n"; - std::cout << " vibe3_physics -F # Fullscreen real (F4 - resolución nativa)\n\n"; + std::cout << " vibe3_physics -F # Fullscreen real (F4 - resolución nativa)\n"; + std::cout << " vibe3_physics --mode demo # Arrancar en modo DEMO (auto-play)\n"; + std::cout << " vibe3_physics -m demo-lite # Arrancar en modo DEMO_LITE (solo física)\n"; + std::cout << " vibe3_physics -F --mode logo # Fullscreen + modo LOGO (easter egg)\n\n"; std::cout << "Nota: Si resolución > pantalla, se usa default. Zoom se ajusta automáticamente.\n"; } @@ -29,6 +35,7 @@ int main(int argc, char* argv[]) { int zoom = 0; bool fullscreen = false; bool real_fullscreen = false; + AppMode initial_mode = AppMode::SANDBOX; // Modo inicial (default: SANDBOX) // Parsear argumentos for (int i = 1; i < argc; i++) { @@ -72,6 +79,25 @@ int main(int argc, char* argv[]) { fullscreen = true; } else if (strcmp(argv[i], "-F") == 0 || strcmp(argv[i], "--real-fullscreen") == 0) { real_fullscreen = true; + } else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mode") == 0) { + if (i + 1 < argc) { + std::string mode_str = argv[++i]; + if (mode_str == "sandbox") { + initial_mode = AppMode::SANDBOX; + } else if (mode_str == "demo") { + initial_mode = AppMode::DEMO; + } else if (mode_str == "demo-lite") { + initial_mode = AppMode::DEMO_LITE; + } else if (mode_str == "logo") { + initial_mode = AppMode::LOGO; + } else { + std::cerr << "Error: Modo '" << mode_str << "' no válido. Usa: sandbox, demo, demo-lite, logo\n"; + return -1; + } + } else { + std::cerr << "Error: -m/--mode requiere un valor\n"; + return -1; + } } else { std::cerr << "Error: Opción desconocida '" << argv[i] << "'\n"; printHelp(); @@ -86,7 +112,7 @@ int main(int argc, char* argv[]) { Engine engine; - if (!engine.initialize(width, height, zoom, fullscreen)) { + if (!engine.initialize(width, height, zoom, fullscreen, initial_mode)) { std::cout << "¡Error al inicializar el engine!" << std::endl; return -1; }