diff --git a/source/director.cpp b/source/director.cpp index e0a52c9..1bf02cf 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -24,6 +24,7 @@ #include "jail_audio.hpp" // for JA_Init #include "lang.h" // for Lang, MAX_LANGUAGES, ba_BA, en_UK #include "logo.h" // for Logo +#include "mouse.hpp" // for Mouse::handleEvent, Mouse::upda... #include "screen.h" // for FILTER_NEAREST, Screen, FILTER_... #include "texture.h" // for Texture #include "title.h" // for Title @@ -649,6 +650,9 @@ SDL_AppResult Director::iterate() { } #endif + // Actualiza la visibilidad del cursor del ratón + Mouse::updateCursorVisibility(options->videoMode != 0); + // Gestiona las transiciones entre secciones handleSectionTransition(); @@ -683,6 +687,9 @@ SDL_AppResult Director::handleEvent(SDL_Event *event) { } #endif + // Gestiona la visibilidad del cursor según el movimiento del ratón + Mouse::handleEvent(*event, options->videoMode != 0); + // Reenvía el evento a la sección activa switch (activeSection) { case ActiveSection::Logo: diff --git a/source/mouse.cpp b/source/mouse.cpp new file mode 100644 index 0000000..133d9d8 --- /dev/null +++ b/source/mouse.cpp @@ -0,0 +1,35 @@ +#include "mouse.hpp" + +namespace Mouse { + Uint32 cursorHideTime = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad + Uint32 lastMouseMoveTime = 0; // Última vez que el ratón se movió + bool cursorVisible = true; // Estado del cursor + + void handleEvent(const SDL_Event &event, bool fullscreen) { + if (event.type == SDL_EVENT_MOUSE_MOTION) { + lastMouseMoveTime = SDL_GetTicks(); + if (!cursorVisible && !fullscreen) { + SDL_ShowCursor(); + cursorVisible = true; + } + } + } + + void updateCursorVisibility(bool fullscreen) { + // En pantalla completa el cursor siempre está oculto + if (fullscreen) { + if (cursorVisible) { + SDL_HideCursor(); + cursorVisible = false; + } + return; + } + + // En modo ventana, lo oculta tras el periodo de inactividad + const Uint32 currentTime = SDL_GetTicks(); + if (cursorVisible && (currentTime - lastMouseMoveTime > cursorHideTime)) { + SDL_HideCursor(); + cursorVisible = false; + } + } +} // namespace Mouse diff --git a/source/mouse.hpp b/source/mouse.hpp new file mode 100644 index 0000000..1af8555 --- /dev/null +++ b/source/mouse.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace Mouse { + extern Uint32 cursorHideTime; // Tiempo en milisegundos para ocultar el cursor por inactividad + extern Uint32 lastMouseMoveTime; // Última vez que el ratón se movió + extern bool cursorVisible; // Estado del cursor + + // Procesa un evento de ratón. En pantalla completa ignora el movimiento + // para no volver a mostrar el cursor. + void handleEvent(const SDL_Event &event, bool fullscreen); + + // Actualiza la visibilidad del cursor. En modo ventana lo oculta + // después de cursorHideTime ms sin movimiento. En pantalla completa + // lo mantiene siempre oculto. + void updateCursorVisibility(bool fullscreen); +} // namespace Mouse diff --git a/source/screen.cpp b/source/screen.cpp index a2b0699..3a65ed7 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -5,6 +5,8 @@ #include // for max, min #include // for basic_ostream, operator<<, cout, endl #include // for basic_string, char_traits, string + +#include "mouse.hpp" // for Mouse::cursorVisible, Mouse::lastMouseMoveTime class Asset; // Constructor @@ -86,8 +88,10 @@ void Screen::setVideoMode(int videoMode) { // Si está activo el modo ventana quita el borde if (videoMode == 0) { - // Muestra el puntero + // Muestra el puntero y reinicia el temporizador de inactividad SDL_ShowCursor(); + Mouse::cursorVisible = true; + Mouse::lastMouseMoveTime = SDL_GetTicks(); // Esconde la ventana // SDL_HideWindow(window); @@ -104,6 +108,17 @@ void Screen::setVideoMode(int videoMode) { 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); @@ -116,6 +131,7 @@ void Screen::setVideoMode(int videoMode) { 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);