diff --git a/CMakeLists.txt b/CMakeLists.txt index d370278..cda414a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(EMSCRIPTEN) FetchContent_Declare( SDL3 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git - GIT_TAG release-3.2.12 + GIT_TAG release-3.4.4 GIT_SHALLOW TRUE ) set(SDL_SHARED OFF CACHE BOOL "" FORCE) diff --git a/Makefile b/Makefile index 567e64c..e171e4a 100644 --- a/Makefile +++ b/Makefile @@ -242,6 +242,7 @@ linux_release: wasm: @echo "Compilando para WebAssembly - Version: $(VERSION)" docker run --rm \ + --user $(shell id -u):$(shell id -g) \ -v $(DIR_ROOT):/src \ -w /src \ emscripten/emsdk:latest \ diff --git a/source/director.cpp b/source/director.cpp index 88362ac..dbaf38d 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -399,7 +399,7 @@ void Director::initOptions() { #ifdef __EMSCRIPTEN__ // En Emscripten la ventana la gestiona el navegador - options->windowSize = 1; + options->windowSize = 4; options->videoMode = 0; options->integerScale = true; #endif diff --git a/source/game.cpp b/source/game.cpp index 3998cc7..d41e497 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -2701,15 +2701,15 @@ void Game::checkGameInput() { // Comprueba las teclas de cambiar el tamaño de la centana y el modo de video if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { - screen->switchVideoMode(); + screen->toggleVideoMode(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { - screen->decWindowSize(); + screen->decWindowZoom(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { - screen->incWindowSize(); + screen->incWindowZoom(); } // Modo Demo activo diff --git a/source/instructions.cpp b/source/instructions.cpp index 89da39e..109fb34 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -230,15 +230,15 @@ void Instructions::checkInput() { } else #endif if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { - screen->switchVideoMode(); + screen->toggleVideoMode(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { - screen->decWindowSize(); + screen->decWindowZoom(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { - screen->incWindowSize(); + screen->incWindowZoom(); } else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) { diff --git a/source/intro.cpp b/source/intro.cpp index 8c7d15a..988ffee 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -205,15 +205,15 @@ void Intro::checkInput() { } else #endif if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { - screen->switchVideoMode(); + screen->toggleVideoMode(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { - screen->decWindowSize(); + screen->decWindowZoom(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { - screen->incWindowSize(); + screen->incWindowZoom(); } else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) { diff --git a/source/logo.cpp b/source/logo.cpp index c49ce32..2ee6eae 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -81,15 +81,15 @@ void Logo::checkInput() { } else #endif if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { - screen->switchVideoMode(); + screen->toggleVideoMode(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { - screen->decWindowSize(); + screen->decWindowZoom(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { - screen->incWindowSize(); + screen->incWindowZoom(); } else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) { diff --git a/source/screen.cpp b/source/screen.cpp index 3721e73..b54dea9 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -45,11 +45,6 @@ EM_BOOL onEmFullscreenChange(int /*eventType*/, const EmscriptenFullscreenChange return EM_FALSE; } -EM_BOOL onEmResize(int /*eventType*/, const EmscriptenUiEvent * /*event*/, void * /*userData*/) { - emscripten_async_call(deferredCanvasResize, nullptr, 0); - return EM_FALSE; -} - EM_BOOL onEmOrientationChange(int /*eventType*/, const EmscriptenOrientationChangeEvent * /*event*/, void * /*userData*/) { emscripten_async_call(deferredCanvasResize, nullptr, 0); return EM_FALSE; @@ -80,12 +75,12 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options } if (gameCanvas == nullptr) { if (options->console) { - std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } // Establece el modo de video - setVideoMode(options->videoMode); + setVideoMode(options->videoMode != 0); // Inicializa el sistema de notificaciones notificationText = new Text(asset->get("8bithud.png"), asset->get("8bithud.txt"), renderer); @@ -95,7 +90,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options notificationEndTime = 0; notificationY = 2; - // Registra callbacks natius d'Emscripten per a fullscreen/resize/orientation + // Registra callbacks natius d'Emscripten per a fullscreen/orientation registerEmscriptenEventCallbacks(); } @@ -137,126 +132,77 @@ void Screen::blit() { SDL_RenderPresent(renderer); } +// ============================================================================ +// Video y ventana +// ============================================================================ + // Establece el modo de video -void Screen::setVideoMode(int videoMode) { - // Aplica el modo de video - SDL_SetWindowFullscreen(window, videoMode != 0); - - // Si está activo el modo ventana quita el borde - if (videoMode == 0) { - // Muestra el puntero y reinicia el temporizador de inactividad - SDL_ShowCursor(); - Mouse::cursorVisible = true; - Mouse::lastMouseMoveTime = SDL_GetTicks(); - - // Esconde la ventana - // SDL_HideWindow(window); - - if (options->borderEnabled) { - windowWidth = gameCanvasWidth + borderWidth; - windowHeight = gameCanvasHeight + borderHeight; - dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight}; - } - - else { - windowWidth = gameCanvasWidth; - windowHeight = gameCanvasHeight; - dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; - } - -#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. - constexpr int WASM_RENDER_SCALE = 3; - windowWidth *= WASM_RENDER_SCALE; - windowHeight *= WASM_RENDER_SCALE; - dest.w *= WASM_RENDER_SCALE; - dest.h *= WASM_RENDER_SCALE; -#endif - - // Modifica el tamaño de la ventana - SDL_SetWindowSize(window, windowWidth * options->windowSize, windowHeight * options->windowSize); - SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); - - // Muestra la ventana - // SDL_ShowWindow(window); +void Screen::setVideoMode(bool fullscreen) { + applyFullscreen(fullscreen); + if (fullscreen) { + applyFullscreenLayout(); + } else { + applyWindowedLayout(); } - - // Si está activo el modo de pantalla completa añade el borde - else if (videoMode == SDL_WINDOW_FULLSCREEN) { - // Oculta el puntero - SDL_HideCursor(); - Mouse::cursorVisible = false; - - // Obten el alto y el ancho de la ventana - SDL_GetWindowSize(window, &windowWidth, &windowHeight); - - // Aplica el escalado al rectangulo donde se pinta la textura del juego - if (options->integerScale) { - // Calcula el tamaño de la escala máxima - int scale = 0; - while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) { - scale++; - } - - dest.w = gameCanvasWidth * scale; - dest.h = gameCanvasHeight * scale; - dest.x = (windowWidth - dest.w) / 2; - dest.y = (windowHeight - dest.h) / 2; - } else if (options->keepAspect) { - float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; - if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) { - dest.h = windowHeight; - dest.w = (int)((windowHeight * ratio) + 0.5f); - dest.x = (windowWidth - dest.w) / 2; - dest.y = (windowHeight - dest.h) / 2; - } else { - dest.w = windowWidth; - dest.h = (int)((windowWidth / ratio) + 0.5f); - dest.x = (windowWidth - dest.w) / 2; - dest.y = (windowHeight - dest.h) / 2; - } - } else { - dest.w = windowWidth; - dest.h = windowHeight; - dest.x = dest.y = 0; - } - } - - // Modifica el tamaño del renderizador - SDL_SetRenderLogicalPresentation(renderer, windowWidth, windowHeight, SDL_LOGICAL_PRESENTATION_LETTERBOX); - - // Actualiza las opciones - options->videoMode = videoMode; - options->screen.windowWidth = windowWidth; - options->screen.windowHeight = windowHeight; + applyLogicalPresentation(fullscreen); } -// Camibia entre pantalla completa y ventana -void Screen::switchVideoMode() { - options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN : 0; - setVideoMode(options->videoMode); +// Cambia entre pantalla completa y ventana +void Screen::toggleVideoMode() { + setVideoMode(options->videoMode == 0); } -// Cambia el tamaño de la ventana -void Screen::setWindowSize(int size) { - options->windowSize = size; - setVideoMode(0); +// Reduce el zoom de la ventana +auto Screen::decWindowZoom() -> bool { + if (options->videoMode != 0) { return false; } + const int PREV = options->windowSize; + options->windowSize = std::max(options->windowSize - 1, WINDOW_ZOOM_MIN); + if (options->windowSize == PREV) { return false; } + setVideoMode(false); + return true; } -// Reduce el tamaño de la ventana -void Screen::decWindowSize() { - --options->windowSize; - options->windowSize = std::max(options->windowSize, 1); - setVideoMode(0); +// Aumenta el zoom de la ventana +auto Screen::incWindowZoom() -> bool { + if (options->videoMode != 0) { return false; } + const int PREV = options->windowSize; + options->windowSize = std::min(options->windowSize + 1, WINDOW_ZOOM_MAX); + if (options->windowSize == PREV) { return false; } + setVideoMode(false); + return true; } -// Aumenta el tamaño de la ventana -void Screen::incWindowSize() { - ++options->windowSize; - options->windowSize = std::min(options->windowSize, 4); - setVideoMode(0); +// Establece el zoom de la ventana directamente +auto Screen::setWindowZoom(int zoom) -> bool { + if (options->videoMode != 0) { return false; } + if (zoom < WINDOW_ZOOM_MIN || zoom > WINDOW_ZOOM_MAX) { return false; } + if (zoom == options->windowSize) { return false; } + options->windowSize = zoom; + setVideoMode(false); + return true; +} + +// Establece el escalado entero +void Screen::setIntegerScale(bool enabled) { + if (options->integerScale == enabled) { return; } + options->integerScale = enabled; + setVideoMode(options->videoMode != 0); +} + +// Alterna el escalado entero +void Screen::toggleIntegerScale() { + setIntegerScale(!options->integerScale); +} + +// Establece el V-Sync +void Screen::setVSync(bool enabled) { + options->vSync = enabled; + SDL_SetRenderVSync(renderer, enabled ? 1 : SDL_RENDERER_VSYNC_DISABLED); +} + +// Alterna el V-Sync +void Screen::toggleVSync() { + setVSync(!options->vSync); } // Cambia el color del borde @@ -264,32 +210,100 @@ void Screen::setBorderColor(color_t color) { borderColor = color; } -// Cambia el tipo de mezcla -void Screen::setBlendMode(SDL_BlendMode blendMode) { - SDL_SetRenderDrawBlendMode(renderer, blendMode); +// ============================================================================ +// Helpers privados de setVideoMode +// ============================================================================ + +// SDL_SetWindowFullscreen + visibilidad del cursor +void Screen::applyFullscreen(bool fullscreen) { + SDL_SetWindowFullscreen(window, fullscreen); + if (fullscreen) { + SDL_HideCursor(); + Mouse::cursorVisible = false; + } else { + SDL_ShowCursor(); + Mouse::cursorVisible = true; + Mouse::lastMouseMoveTime = SDL_GetTicks(); + } } -// Establece el tamaño del borde -void Screen::setBorderWidth(int s) { - options->borderWidth = s; +// Calcula windowWidth/Height/dest para el modo ventana y aplica SDL_SetWindowSize +void Screen::applyWindowedLayout() { + if (options->borderEnabled) { + windowWidth = gameCanvasWidth + borderWidth; + windowHeight = gameCanvasHeight + borderHeight; + dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight}; + } else { + windowWidth = gameCanvasWidth; + windowHeight = gameCanvasHeight; + dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; + } + +#ifdef __EMSCRIPTEN__ + windowWidth *= WASM_RENDER_SCALE; + windowHeight *= WASM_RENDER_SCALE; + dest.w *= WASM_RENDER_SCALE; + dest.h *= WASM_RENDER_SCALE; +#endif + + // Modifica el tamaño de la ventana + SDL_SetWindowSize(window, windowWidth * options->windowSize, windowHeight * options->windowSize); + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } -// Establece el tamaño del borde -void Screen::setBorderHeight(int s) { - options->borderHeight = s; +// Obtiene el tamaño de la ventana en fullscreen y calcula el rect del juego +void Screen::applyFullscreenLayout() { + SDL_GetWindowSize(window, &windowWidth, &windowHeight); + computeFullscreenGameRect(); } -// Establece si se ha de ver el borde en el modo ventana -void Screen::setBorderEnabled(bool value) { - options->borderEnabled = value; +// Calcula el rectángulo dest para fullscreen: integerScale / keepAspect / stretched +void Screen::computeFullscreenGameRect() { + if (options->integerScale) { + // Calcula el tamaño de la escala máxima + int scale = 0; + while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) { + scale++; + } + + dest.w = gameCanvasWidth * scale; + dest.h = gameCanvasHeight * scale; + dest.x = (windowWidth - dest.w) / 2; + dest.y = (windowHeight - dest.h) / 2; + } else if (options->keepAspect) { + float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; + if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) { + dest.h = windowHeight; + dest.w = (int)((windowHeight * ratio) + 0.5f); + dest.x = (windowWidth - dest.w) / 2; + dest.y = (windowHeight - dest.h) / 2; + } else { + dest.w = windowWidth; + dest.h = (int)((windowWidth / ratio) + 0.5f); + dest.x = (windowWidth - dest.w) / 2; + dest.y = (windowHeight - dest.h) / 2; + } + } else { + dest.w = windowWidth; + dest.h = windowHeight; + dest.x = dest.y = 0; + } } -// Cambia entre borde visible y no visible -void Screen::switchBorder() { - options->borderEnabled = !options->borderEnabled; - setVideoMode(0); +// Aplica la logical presentation y persiste el estado en options +void Screen::applyLogicalPresentation(bool fullscreen) { + SDL_SetRenderLogicalPresentation(renderer, windowWidth, windowHeight, SDL_LOGICAL_PRESENTATION_LETTERBOX); + + // Actualiza las opciones + options->videoMode = fullscreen ? SDL_WINDOW_FULLSCREEN : 0; + options->screen.windowWidth = windowWidth; + options->screen.windowHeight = windowHeight; } +// ============================================================================ +// Notificaciones +// ============================================================================ + // Muestra una notificación en la línea superior durante durationMs void Screen::notify(const std::string &text, color_t textColor, color_t outlineColor, Uint32 durationMs) { notificationMessage = text; @@ -304,35 +318,6 @@ void Screen::clearNotification() { notificationMessage.clear(); } -// --- Fix per a fullscreen/resize en Emscripten --- -// Vore el bloc de comentaris a dalt i l'anonymous namespace amb els callbacks. - -void Screen::handleCanvasResized() { -#ifdef __EMSCRIPTEN__ - // La crida a SDL_SetWindowFullscreen + SDL_SetRenderLogicalPresentation - // que fa setVideoMode és l'única manera de resincronitzar l'estat intern - // de SDL amb el canvas HTML real. - setVideoMode(options->videoMode); -#endif -} - -void Screen::syncFullscreenFlagFromBrowser(bool isFullscreen) { -#ifdef __EMSCRIPTEN__ - options->videoMode = isFullscreen ? SDL_WINDOW_FULLSCREEN : 0; -#else - (void)isFullscreen; -#endif -} - -void Screen::registerEmscriptenEventCallbacks() { -#ifdef __EMSCRIPTEN__ - g_screen_instance = this; - emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, EM_FALSE, onEmFullscreenChange); - emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, EM_FALSE, onEmResize); - emscripten_set_orientationchange_callback(nullptr, EM_FALSE, onEmOrientationChange); -#endif -} - // Dibuja la notificación activa (si la hay) sobre el gameCanvas void Screen::renderNotification() { if (SDL_GetTicks() >= notificationEndTime) { @@ -346,4 +331,38 @@ void Screen::renderNotification() { notificationTextColor, 1, notificationOutlineColor); -} \ No newline at end of file +} + +// ============================================================================ +// Emscripten — fix per a fullscreen/resize (veure el bloc de comentaris al +// principi del fitxer i l'anonymous namespace amb els callbacks natius). +// ============================================================================ + +void Screen::handleCanvasResized() { +#ifdef __EMSCRIPTEN__ + // La crida a SDL_SetWindowFullscreen + SDL_SetRenderLogicalPresentation + // que fa setVideoMode és l'única manera de resincronitzar l'estat intern + // de SDL amb el canvas HTML real. + setVideoMode(options->videoMode != 0); +#endif +} + +void Screen::syncFullscreenFlagFromBrowser(bool isFullscreen) { +#ifdef __EMSCRIPTEN__ + options->videoMode = isFullscreen ? SDL_WINDOW_FULLSCREEN : 0; +#else + (void)isFullscreen; +#endif +} + +void Screen::registerEmscriptenEventCallbacks() { +#ifdef __EMSCRIPTEN__ + // IMPORTANT: NO registrem resize callback. En mòbil, fer scroll fa que el + // navegador oculti/mostri la barra d'URL, disparant un resize del DOM per + // cada scroll. Això portava a cridar setVideoMode per cada scroll, que + // re-aplicava la logical presentation i corrompia el viewport intern de SDL. + g_screen_instance = this; + emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, EM_TRUE, onEmFullscreenChange); + emscripten_set_orientationchange_callback(nullptr, EM_TRUE, onEmOrientationChange); +#endif +} diff --git a/source/screen.h b/source/screen.h index d13abce..b04fa83 100644 --- a/source/screen.h +++ b/source/screen.h @@ -13,7 +13,60 @@ constexpr int FILTER_NEAREST = 0; constexpr int FILTER_LINEAL = 1; 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, options_t *options); + ~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 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 + 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 + // Objetos y punteros SDL_Window *window; // Ventana de la aplicación SDL_Renderer *renderer; // El renderizador de la ventana @@ -27,7 +80,7 @@ class Screen { 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 int borderWidth; // Anchura del borde - int borderHeight; // Anltura del borde + int borderHeight; // Altura del borde 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 @@ -38,76 +91,4 @@ class Screen { color_t notificationOutlineColor; // Color del outline Uint32 notificationEndTime; // SDL_GetTicks() hasta el cual se muestra int notificationY; // Fila vertical en el canvas virtual - - // Dibuja la notificación activa (si la hay) sobre el gameCanvas - void renderNotification(); - - public: - // Constructor - Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options); - - // Destructor - ~Screen(); - - // Limpia la pantalla - void clean(color_t color = {0x00, 0x00, 0x00}); - - // Prepara para empezar a dibujar en la textura de juego - void start(); - - // Vuelca el contenido del renderizador en pantalla - void blit(); - - // Establece el modo de video - void setVideoMode(int videoMode); - - // Camibia entre pantalla completa y ventana - void switchVideoMode(); - - // Cambia el tamaño de la ventana - void setWindowSize(int size); - - // Reduce el tamaño de la ventana - void decWindowSize(); - - // Aumenta el tamaño de la ventana - void incWindowSize(); - - // Cambia el color del borde - void setBorderColor(color_t color); - - // Cambia el tipo de mezcla - void setBlendMode(SDL_BlendMode blendMode); - - // Establece el tamaño del borde - void setBorderWidth(int s); - void setBorderHeight(int s); - - // Establece si se ha de ver el borde en el modo ventana - void setBorderEnabled(bool value); - - // Cambia entre borde visible y no visible - void switchBorder(); - - // Muestra una notificación en la línea superior del canvas durante durationMs. - // Sobrescribe cualquier notificación activa (sin apilación). - void notify(const std::string &text, color_t textColor, color_t outlineColor, Uint32 durationMs); - - // Limpia la notificación actual - void clearNotification(); - - // En Emscripten, reaplica setVideoMode tras un canvi del navegador (eixida - // de fullscreen amb Esc, resize, canvi d'orientació). Fora d'Emscripten - // és un no-op. Vore screen.cpp per al perquè del fix. - void handleCanvasResized(); - - // Sincronitza el flag intern de fullscreen amb l'estat real del navegador. - // Ha de cridar-se abans de diferir handleCanvasResized perquè - // setVideoMode llija el valor correcte. No-op fora d'Emscripten. - void syncFullscreenFlagFromBrowser(bool isFullscreen); - - private: - // Registra els callbacks natius d'Emscripten per a fullscreenchange, - // resize i orientationchange. No-op fora d'Emscripten. - void registerEmscriptenEventCallbacks(); }; diff --git a/source/title.cpp b/source/title.cpp index 55ff816..2d64d0f 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -660,15 +660,15 @@ void Title::checkInput() { } else #endif if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { - screen->switchVideoMode(); + screen->toggleVideoMode(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { - screen->decWindowSize(); + screen->decWindowZoom(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { - screen->incWindowSize(); + screen->incWindowZoom(); } } @@ -891,7 +891,7 @@ void Title::updateMenuLabels() { // Aplica las opciones de menu seleccionadas void Title::applyOptions() { - screen->setVideoMode(options->videoMode); + screen->setVideoMode(options->videoMode != 0); lang->setLang(options->language);