#pragma once #include // for SDL_Event #include // for SDL_Renderer (ui_renderer_ software renderer) #include // for Uint64 #include // for SDL_Surface (ui_surface_) #include // for SDL_Window #include // for array #include // for unique_ptr, shared_ptr #include // for string #include // for vector #include "ui/app_logo.hpp" // for AppLogo #include "ball.hpp" // for Ball #include "boids_mgr/boid_manager.hpp" // for BoidManager #include "defines.hpp" // for GravityDirection, ColorTheme, ShapeType #include "external/texture.hpp" // for Texture #include "gpu/gpu_ball_buffer.hpp" // for GpuBallBuffer, BallGPUData #include "gpu/gpu_context.hpp" // for GpuContext #include "gpu/gpu_pipeline.hpp" // for GpuPipeline #include "gpu/gpu_sprite_batch.hpp" // for GpuSpriteBatch #include "gpu/gpu_texture.hpp" // for GpuTexture #include "input/input_handler.hpp" // for InputHandler #include "scene/scene_manager.hpp" // for SceneManager #include "shapes_mgr/shape_manager.hpp" // for ShapeManager #include "state/state_manager.hpp" // for StateManager #include "theme_manager.hpp" // for ThemeManager #include "ui/ui_manager.hpp" // for UIManager class Engine { public: // Interfaz pública principal bool initialize(int width = 0, int height = 0, int zoom = 0, bool fullscreen = false, AppMode initial_mode = AppMode::SANDBOX); void run(); void shutdown(); // === Métodos públicos para InputHandler === // Gravedad y física void pushBallsAwayFromGravity(); void handleGravityToggle(); void handleGravityDirectionChange(GravityDirection direction, const char* notification_text); // Display y depuración void toggleVSync(); void toggleDebug(); void toggleHelp(); // Figuras 3D void toggleShapeMode(); void activateShape(ShapeType type, const char* notification_text); void handleShapeScaleChange(bool increase); void resetShapeScale(); void toggleDepthZoom(); // Boids (comportamiento de enjambre) void toggleBoidsMode(bool force_gravity_on = true); // Temas de colores void cycleTheme(bool forward); void switchThemeByNumpad(int numpad_key); void toggleThemePage(); void pauseDynamicTheme(); // Sprites/Texturas void switchTexture(); // Escenarios (número de pelotas) void changeScenario(int scenario_id, const char* notification_text); // Zoom y fullscreen void handleZoomIn(); void handleZoomOut(); void toggleFullscreen(); void toggleRealFullscreen(); void toggleIntegerScaling(); // PostFX presets void handlePostFXCycle(); void handlePostFXToggle(); void setInitialPostFX(int mode); void setPostFXParamOverrides(float vignette, float chroma); // Modo kiosko void setKioskMode(bool enabled) { kiosk_mode_ = enabled; } bool isKioskMode() const { return kiosk_mode_; } // Escenario custom (tecla 9, --custom-balls) void setCustomScenario(int balls); bool isCustomScenarioEnabled() const { return custom_scenario_enabled_; } bool isCustomAutoAvailable() const { return custom_auto_available_; } int getCustomScenarioBalls() const { return custom_scenario_balls_; } // Control manual del benchmark (--skip-benchmark, --max-balls) void setSkipBenchmark(); void setMaxBallsOverride(int n); // Notificaciones (público para InputHandler) void showNotificationForAction(const std::string& text); // Modos de aplicación (DEMO/LOGO) void toggleDemoMode(); void toggleDemoLiteMode(); void toggleLogoMode(); // === Métodos públicos para StateManager (automatización DEMO/LOGO sin notificación) === void enterShapeMode(ShapeType type); // Activar figura (sin notificación) void exitShapeMode(bool force_gravity = true); // Volver a física (sin notificación) void switchTextureSilent(); // Cambiar textura (sin notificación) void setTextureByIndex(size_t index); // Restaurar textura específica // === Getters públicos para UIManager (Debug HUD) === bool getVSyncEnabled() const { return vsync_enabled_; } bool getFullscreenEnabled() const { return fullscreen_enabled_; } bool getRealFullscreenEnabled() const { return real_fullscreen_enabled_; } ScalingMode getCurrentScalingMode() const { return current_scaling_mode_; } int getCurrentScreenWidth() const { return current_screen_width_; } int getCurrentScreenHeight() const { return current_screen_height_; } std::string getCurrentTextureName() const { if (texture_names_.empty()) return ""; return texture_names_[current_texture_index_]; } int getBaseScreenWidth() const { return base_screen_width_; } int getBaseScreenHeight() const { return base_screen_height_; } int getMaxAutoScenario() const { return max_auto_scenario_; } size_t getCurrentTextureIndex() const { return current_texture_index_; } bool isPostFXEnabled() const { return postfx_enabled_; } int getPostFXMode() const { return postfx_effect_mode_; } float getPostFXVignette() const { return postfx_uniforms_.vignette_strength; } float getPostFXChroma() const { return postfx_uniforms_.chroma_strength; } float getPostFXScanline() const { return postfx_uniforms_.scanline_strength; } private: // === Componentes del sistema (Composición) === std::unique_ptr input_handler_; // Manejo de entradas SDL std::unique_ptr scene_manager_; // Gestión de bolas y física std::unique_ptr shape_manager_; // Gestión de figuras 3D std::unique_ptr boid_manager_; // Gestión de comportamiento boids std::unique_ptr state_manager_; // Gestión de estados (DEMO/LOGO) std::unique_ptr ui_manager_; // Gestión de UI (HUD, FPS, notificaciones) std::unique_ptr app_logo_; // Gestión de logo periódico en pantalla // === SDL window === SDL_Window* window_ = nullptr; // === SDL_GPU rendering pipeline === std::unique_ptr gpu_ctx_; // Device + swapchain std::unique_ptr gpu_pipeline_; // Sprite + ball + postfx pipelines std::unique_ptr sprite_batch_; // Per-frame vertex/index batch (bg + shape + UI) std::unique_ptr gpu_ball_buffer_; // Instanced ball instance data (PHYSICS/BOIDS) std::vector ball_gpu_data_; // CPU-side staging vector (reused each frame) std::unique_ptr offscreen_tex_; // Offscreen render target (Pass 1) std::unique_ptr white_tex_; // 1×1 white (background gradient) std::unique_ptr ui_tex_; // UI text overlay texture // GPU sprite textures (one per ball skin, parallel to textures_/texture_names_) std::unique_ptr gpu_texture_; // Active GPU sprite texture std::vector> gpu_textures_; // All GPU sprite textures // === SDL_Renderer (software, for UI text via SDL3_ttf) === // Renders to ui_surface_, then uploaded as gpu texture overlay. SDL_Renderer* ui_renderer_ = nullptr; SDL_Surface* ui_surface_ = nullptr; // Legacy Texture objects — kept for ball physics sizing and AppLogo std::shared_ptr texture_ = nullptr; // Textura activa actual std::vector> textures_; // Todas las texturas disponibles std::vector texture_names_; // Nombres de texturas (sin extensión) size_t current_texture_index_ = 0; // Índice de textura activa int current_ball_size_ = 10; // Tamaño actual de pelotas (dinámico) // Estado del simulador bool should_exit_ = false; // Sistema de timing Uint64 last_frame_time_ = 0; float delta_time_ = 0.0f; // PostFX uniforms (passed to GPU each frame) PostFXUniforms postfx_uniforms_ = {0.0f, 0.0f, 0.0f, 0.0f}; int postfx_effect_mode_ = 0; bool postfx_enabled_ = false; float postfx_override_vignette_ = -1.f; // -1 = sin override float postfx_override_chroma_ = -1.f; // Sistema de zoom dinámico int current_window_zoom_ = DEFAULT_WINDOW_ZOOM; // V-Sync y fullscreen bool vsync_enabled_ = true; bool fullscreen_enabled_ = false; bool real_fullscreen_enabled_ = false; bool kiosk_mode_ = false; ScalingMode current_scaling_mode_ = ScalingMode::INTEGER; // Resolución base (configurada por CLI o default) int base_screen_width_ = DEFAULT_SCREEN_WIDTH; int base_screen_height_ = DEFAULT_SCREEN_HEIGHT; // Resolución dinámica actual (cambia en fullscreen real) int current_screen_width_ = DEFAULT_SCREEN_WIDTH; int current_screen_height_ = DEFAULT_SCREEN_HEIGHT; // Resolución física real de ventana/pantalla (para texto absoluto) int physical_window_width_ = DEFAULT_SCREEN_WIDTH; int physical_window_height_ = DEFAULT_SCREEN_HEIGHT; // Sistema de temas (delegado a ThemeManager) std::unique_ptr theme_manager_; int theme_page_ = 0; // Modo de simulación actual (PHYSICS/SHAPE/BOIDS) SimulationMode current_mode_ = SimulationMode::PHYSICS; // Sistema de Modo DEMO (auto-play) y LOGO int max_auto_scenario_ = 5; // Escenario custom (--custom-balls) int custom_scenario_balls_ = 0; bool custom_scenario_enabled_ = false; bool custom_auto_available_ = false; bool skip_benchmark_ = false; // Bucket sort per z-ordering (SHAPE mode) static constexpr int DEPTH_SORT_BUCKETS = 256; std::array, DEPTH_SORT_BUCKETS> depth_buckets_; // Métodos principales del loop void calculateDeltaTime(); void update(); void render(); // Benchmark de rendimiento (determina max_auto_scenario_ al inicio) void runPerformanceBenchmark(); // Métodos auxiliares privados // Sistema de cambio de sprites dinámico void switchTextureInternal(bool show_notification); // Sistema de zoom dinámico int calculateMaxWindowZoom() const; void setWindowZoom(int new_zoom); void zoomIn(); void zoomOut(); void updatePhysicalWindowSize(); // Rendering (GPU path replaces addSpriteToBatch) void addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale = 1.0f); // Sistema de Figuras 3D void toggleShapeModeInternal(bool force_gravity_on_exit = true); void activateShapeInternal(ShapeType type); void updateShape(); void generateShape(); // PostFX helper void applyPostFXPreset(int mode); // GPU helpers bool loadGpuSpriteTexture(size_t index); // Upload one sprite texture to GPU void recreateOffscreenTexture(); // Recreate when resolution changes void renderUIToSurface(); // Render text/UI to ui_surface_ void uploadUISurface(SDL_GPUCommandBuffer* cmd_buf); // Upload ui_surface_ → ui_tex_ };