#include #include #include #include "engine.hpp" #include "defines.hpp" #include "resource_manager.hpp" // getExecutableDirectory() ya está definido en defines.h como inline void printHelp() { std::cout << "ViBe3 Physics - Simulador de físicas avanzadas\n"; std::cout << "\nUso: vibe3_physics [opciones]\n\n"; std::cout << "Opciones:\n"; std::cout << " -w, --width Ancho de resolución (default: 320)\n"; std::cout << " -h, --height Alto de resolución (default: 240)\n"; 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 << " -k, --kiosk Modo kiosko (F4 fijo, sin ESC, sin zoom)\n"; std::cout << " -m, --mode Modo inicial: sandbox, demo, demo-lite, logo (default: sandbox)\n"; std::cout << " --custom-balls Activa escenario custom (tecla 9) con N pelotas\n"; std::cout << " --skip-benchmark Salta el benchmark y usa el máximo de bolas (50000)\n"; std::cout << " --max-balls Limita el máximo de bolas en modos DEMO/DEMO_LITE\n"; std::cout << " --postfx Arrancar con PostFX activo: vinyeta, scanlines, cromatica, complet\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"; std::cout << " vibe3_physics -k # Modo kiosko (pantalla completa real, bloqueado)\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"; } int main(int argc, char* argv[]) { int width = 0; int height = 0; int zoom = 0; int custom_balls = 0; bool fullscreen = false; bool real_fullscreen = false; bool kiosk_mode = false; bool skip_benchmark = false; int max_balls_override = 0; int initial_postfx = -1; AppMode initial_mode = AppMode::SANDBOX; // Modo inicial (default: SANDBOX) // Parsear argumentos for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--help") == 0) { printHelp(); return 0; } else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--width") == 0) { if (i + 1 < argc) { width = atoi(argv[++i]); if (width < 320) { std::cerr << "Error: Ancho mínimo es 320\n"; return -1; } } else { std::cerr << "Error: -w/--width requiere un valor\n"; return -1; } } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--height") == 0) { if (i + 1 < argc) { height = atoi(argv[++i]); if (height < 240) { std::cerr << "Error: Alto mínimo es 240\n"; return -1; } } else { std::cerr << "Error: -h/--height requiere un valor\n"; return -1; } } else if (strcmp(argv[i], "-z") == 0 || strcmp(argv[i], "--zoom") == 0) { if (i + 1 < argc) { zoom = atoi(argv[++i]); if (zoom < 1) { std::cerr << "Error: Zoom mínimo es 1\n"; return -1; } } else { std::cerr << "Error: -z/--zoom requiere un valor\n"; return -1; } } else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fullscreen") == 0) { fullscreen = true; } else if (strcmp(argv[i], "-F") == 0 || strcmp(argv[i], "--real-fullscreen") == 0) { real_fullscreen = true; } else if (strcmp(argv[i], "-k") == 0 || strcmp(argv[i], "--kiosk") == 0) { kiosk_mode = 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 if (strcmp(argv[i], "--custom-balls") == 0) { if (i + 1 < argc) { int n = atoi(argv[++i]); if (n < 1) { std::cerr << "Error: --custom-balls requiere un valor >= 1\n"; return -1; } custom_balls = n; } else { std::cerr << "Error: --custom-balls requiere un valor\n"; return -1; } } else if (strcmp(argv[i], "--skip-benchmark") == 0) { skip_benchmark = true; } else if (strcmp(argv[i], "--postfx") == 0) { if (i + 1 < argc) { std::string fx = argv[++i]; if (fx == "vinyeta") { initial_postfx = 0; } else if (fx == "scanlines") { initial_postfx = 1; } else if (fx == "cromatica") { initial_postfx = 2; } else if (fx == "complet") { initial_postfx = 3; } else { std::cerr << "Error: --postfx '" << fx << "' no válido. Usa: vinyeta, scanlines, cromatica, complet\n"; return -1; } } else { std::cerr << "Error: --postfx requiere un valor\n"; return -1; } } else if (strcmp(argv[i], "--max-balls") == 0) { if (i + 1 < argc) { int n = atoi(argv[++i]); if (n < 1) { std::cerr << "Error: --max-balls requiere un valor >= 1\n"; return -1; } max_balls_override = n; } else { std::cerr << "Error: --max-balls requiere un valor\n"; return -1; } } else { std::cerr << "Error: Opción desconocida '" << argv[i] << "'\n"; printHelp(); return -1; } } // Inicializar sistema de recursos empaquetados (intentar cargar resources.pack) std::string resources_dir = getResourcesDirectory(); std::string pack_path = resources_dir + "/resources.pack"; ResourceManager::init(pack_path); Engine engine; if (custom_balls > 0) engine.setCustomScenario(custom_balls); // pre-init: asigna campos antes del benchmark if (max_balls_override > 0) engine.setMaxBallsOverride(max_balls_override); else if (skip_benchmark) engine.setSkipBenchmark(); if (initial_postfx >= 0) engine.setInitialPostFX(initial_postfx); if (!engine.initialize(width, height, zoom, fullscreen, initial_mode)) { std::cout << "¡Error al inicializar el engine!" << std::endl; return -1; } // Si se especificó real fullscreen (F4) o modo kiosko, activar después de inicializar if (real_fullscreen || kiosk_mode) { engine.toggleRealFullscreen(); } if (kiosk_mode) { engine.setKioskMode(true); } engine.run(); engine.shutdown(); return 0; }