#pragma once #include #include // for unique_ptr #include // for string #include // for vector #include "utils/utils.h" // for color_t #ifndef NO_SHADERS #include "core/rendering/shader_backend.hpp" // for Rendering::ShaderType namespace Rendering { class ShaderBackend; } #endif class Asset; class Text; class Screen { public: // Constantes static constexpr int WINDOW_ZOOM_MIN = 1; static constexpr int WINDOW_ZOOM_MAX = 4; #ifdef __EMSCRIPTEN__ // En WASM el tamaño de ventana está fijado a 1x, así que escalamos el // renderizado por 3 aprovechando el modo NEAREST de la textura del juego // para que los píxeles salgan nítidos. static constexpr int WASM_RENDER_SCALE = 3; #endif // Constructor y destructor Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset); ~Screen(); // Render loop void clean(color_t color = {0x00, 0x00, 0x00}); // Limpia la pantalla void start(); // Prepara para empezar a dibujar en la textura de juego void blit(); // Vuelca el contenido del renderizador en pantalla // Video y ventana void setVideoMode(bool fullscreen); // Establece el modo de video void toggleVideoMode(); // Cambia entre pantalla completa y ventana void handleCanvasResized(); // En Emscripten, reaplica setVideoMode tras un cambio del navegador (salida de fullscreen con Esc, rotación). No-op fuera de Emscripten void syncFullscreenFlagFromBrowser(bool isFullscreen); // Sincroniza el flag interno de fullscreen con el estado real del navegador. Debe llamarse antes de diferir handleCanvasResized. No-op fuera de Emscripten void toggleIntegerScale(); // Alterna el escalado entero void setIntegerScale(bool enabled); // Establece el escalado entero void toggleVSync(); // Alterna el V-Sync void setVSync(bool enabled); // Establece el V-Sync auto decWindowZoom() -> bool; // Reduce el zoom de la ventana (devuelve true si cambió) auto incWindowZoom() -> bool; // Aumenta el zoom de la ventana (devuelve true si cambió) auto setWindowZoom(int zoom) -> bool; // Establece el zoom de la ventana (devuelve true si cambió) // Borde void setBorderColor(color_t color); // Cambia el color del borde // Notificaciones void initNotifications(); // Enllaça el Text de notificacions amb `Resource`. A cridar després de `Resource::init(...)`. void notify(const std::string &text, color_t textColor, color_t outlineColor, Uint32 durationMs); // Muestra una notificación en la línea superior del canvas durante durationMs. Sobrescribe cualquier notificación activa (sin apilación). void clearNotification(); // Limpia la notificación actual // GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op. void initShaders(); // Crea el backend GPU si no existe y lo inicializa void shutdownShaders(); // Libera el backend GPU auto isGpuAccelerated() const -> bool; // true si el backend existe y reporta hardware OK void setShaderEnabled(bool enabled); // Activa o desactiva el post-procesado (persiste) void toggleShaderEnabled(); // Alterna post-procesado auto isShaderEnabled() const -> bool; // Estado actual (lee options) #ifndef NO_SHADERS void setActiveShader(Rendering::ShaderType type); // POSTFX o CRTPI auto getActiveShader() const -> Rendering::ShaderType; #endif void toggleActiveShader(); // Alterna POSTFX ↔ CRTPI // Presets de shaders (PostFX/CrtPi). Operen sobre el shader actiu. // Retornen false si GPU off / shaders off / llista buida (igual que a aee_plus). auto nextPreset() -> bool; auto prevPreset() -> bool; auto getCurrentPresetName() const -> const char*; void applyCurrentPostFXPreset(); // Escriu el preset PostFX actiu al backend void applyCurrentCrtPiPreset(); // Escriu el preset CrtPi actiu al backend private: // Helpers internos de setVideoMode void applyFullscreen(bool fullscreen); // SDL_SetWindowFullscreen + visibilidad del cursor void applyWindowedLayout(); // Calcula windowWidth/Height/dest + SDL_SetWindowSize + SDL_SetWindowPosition void applyFullscreenLayout(); // SDL_GetWindowSize + delegación a computeFullscreenGameRect void computeFullscreenGameRect(); // Calcula dest en fullscreen (integerScale / keepAspect / stretched) void applyLogicalPresentation(bool fullscreen); // SDL_SetRenderLogicalPresentation + persistencia a options // Emscripten void registerEmscriptenEventCallbacks(); // Registra los callbacks nativos de Emscripten para fullscreenchange y orientationchange. No-op fuera de Emscripten // Notificaciones void renderNotification(); // Dibuja la notificación activa (si la hay) sobre el gameCanvas #ifndef NO_SHADERS // Aplica els paràmetres actuals del shader al backend segons options // (pass-through si `videoShaderEnabled==false`, preset per defecte si true). void applyShaderParams(); #endif // Objetos y punteros SDL_Window *window; // Ventana de la aplicación SDL_Renderer *renderer; // El renderizador de la ventana Asset *asset; // Objeto con el listado de recursos SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa // Variables int windowWidth; // Ancho de la pantalla o ventana int windowHeight; // Alto de la pantalla o ventana int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla // Notificaciones - una sola activa, sin apilación ni animaciones Text *notificationText; // Fuente 8bithud dedicada a las notificaciones std::string notificationMessage; // Texto a mostrar color_t notificationTextColor; // Color del texto color_t notificationOutlineColor; // Color del outline Uint32 notificationEndTime; // SDL_GetTicks() hasta el cual se muestra int notificationY; // Fila vertical en el canvas virtual #ifndef NO_SHADERS // GPU / shaders std::unique_ptr shader_backend_; // Backend GPU (nullptr si inactivo) std::vector pixel_buffer_; // Buffer de readback del gameCanvas (ARGB8888) #endif };