diff --git a/source/core/input/mouse.cpp b/source/core/input/mouse.cpp index ff4f2db..e8d84c7 100644 --- a/source/core/input/mouse.cpp +++ b/source/core/input/mouse.cpp @@ -1,15 +1,32 @@ #include "core/input/mouse.hpp" +#include + namespace Mouse { Uint32 cursor_hide_time = 3000; // Tiempo en milisegundos para ocultar el cursor Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió -bool cursor_visible = true; // Estado del cursor +bool cursor_visible = false; // Estado del cursor (inicia ocult) // Modo forzado: Usado cuando SDLManager entra en pantalla completa. // Cuando está activado, el cursor permanece oculto independientemente del movimiento del ratón. // SDLManager controla esto mediante llamadas a setForceHidden(). bool force_hidden = false; +// Temps d'inicialització per ignorar esdeveniments fantasma de SDL +Uint32 initialization_time = 0; +constexpr Uint32 IGNORE_MOTION_DURATION = 1000; // Ignorar primers 1000ms + +void forceHide() { + // Forçar ocultació sincronitzant estat SDL i estat intern + std::cout << "[Mouse::forceHide] Ocultant cursor i sincronitzant estat. cursor_visible=" << cursor_visible + << " -> false" << std::endl; + SDL_HideCursor(); + cursor_visible = false; + last_mouse_move_time = 0; + initialization_time = SDL_GetTicks(); // Marcar temps per ignorar esdeveniments inicials + std::cout << "[Mouse::forceHide] Ignorant moviments durant " << IGNORE_MOTION_DURATION << "ms" << std::endl; +} + void setForceHidden(bool force) { force_hidden = force; @@ -39,8 +56,18 @@ void handleEvent(const SDL_Event& event) { // MODO NORMAL: Mostrar cursor al mover el ratón if (event.type == SDL_EVENT_MOUSE_MOTION) { - last_mouse_move_time = SDL_GetTicks(); + Uint32 current_time = SDL_GetTicks(); + + // Ignorar esdeveniments fantasma de SDL durant el període inicial + if (initialization_time > 0 && (current_time - initialization_time < IGNORE_MOTION_DURATION)) { + std::cout << "[Mouse::handleEvent] Ignorant moviment fantasma de SDL. time=" << current_time + << " (inicialització fa " << (current_time - initialization_time) << "ms)" << std::endl; + return; + } + + last_mouse_move_time = current_time; if (!cursor_visible) { + std::cout << "[Mouse::handleEvent] Mostrant cursor per moviment REAL. time=" << last_mouse_move_time << std::endl; SDL_ShowCursor(); cursor_visible = true; } @@ -56,6 +83,8 @@ void updateCursorVisibility() { // MODO NORMAL: Auto-ocultar basado en timeout Uint32 current_time = SDL_GetTicks(); if (cursor_visible && (current_time - last_mouse_move_time > cursor_hide_time)) { + std::cout << "[Mouse::updateCursorVisibility] Ocultant cursor per timeout. current=" << current_time + << " last=" << last_mouse_move_time << " diff=" << (current_time - last_mouse_move_time) << std::endl; SDL_HideCursor(); cursor_visible = false; } diff --git a/source/core/input/mouse.hpp b/source/core/input/mouse.hpp index df8e5ac..d3bad75 100644 --- a/source/core/input/mouse.hpp +++ b/source/core/input/mouse.hpp @@ -7,6 +7,7 @@ extern Uint32 cursor_hide_time; // Tiempo en milisegundos para ocultar el c extern Uint32 last_mouse_move_time; // Última vez que el ratón se movió extern bool cursor_visible; // Estado del cursor +void forceHide(); // Forçar ocultació del cursor (sincronitza estat intern) void handleEvent(const SDL_Event& event); void updateCursorVisibility(); diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index d2d72b9..5c71b3a 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -141,6 +141,12 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) // Configurar viewport scaling updateLogicalPresentation(); + // Inicialitzar sistema de cursor + // En fullscreen: forzar ocultació permanent + if (is_fullscreen_) { + Mouse::setForceHidden(true); + } + std::cout << "SDL3 inicialitzat: " << current_width_ << "x" << current_height_ << " (logic: " << Defaults::Game::WIDTH << "x" << Defaults::Game::HEIGHT << ")"; @@ -148,9 +154,6 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) std::cout << " [FULLSCREEN]"; } std::cout << std::endl; - - // Inicialitzar mòdul Mouse amb l'estat actual de fullscreen - Mouse::setForceHidden(is_fullscreen_); } SDLManager::~SDLManager() { diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 4a7c213..17c815f 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -11,6 +11,7 @@ #include "core/audio/audio_cache.hpp" #include "core/defaults.hpp" #include "core/input/input.hpp" +#include "core/input/mouse.hpp" #include "core/rendering/sdl_manager.hpp" #include "core/resources/resource_helper.hpp" #include "core/resources/resource_loader.hpp" @@ -217,6 +218,12 @@ auto Director::run() -> int { // Crear gestor SDL amb configuració de Options SDLManager sdl(initial_width, initial_height, Options::window.fullscreen); + // CRÍTIC: Forçar ocultació del cursor DESPRÉS de tota la inicialització SDL + // Això evita que SDL mostre el cursor automàticament durant la creació de la finestra + if (!Options::window.fullscreen) { + Mouse::forceHide(); + } + // Inicialitzar sistema d'audio Audio::init(); Audio::get()->setMusicVolume(1.0); diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index 840be36..82d9525 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -62,6 +62,12 @@ EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context) inicialitzar_lletres(); } +EscenaLogo::~EscenaLogo() { + // Aturar tots els sons i la música + Audio::get()->stopAllSounds(); + std::cout << "Escena Logo: Sons aturats\n"; +} + void EscenaLogo::executar() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); diff --git a/source/game/escenes/escena_logo.hpp b/source/game/escenes/escena_logo.hpp index 49b19e0..18488b5 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/escenes/escena_logo.hpp @@ -21,6 +21,7 @@ class EscenaLogo { public: explicit EscenaLogo(SDLManager& sdl, GestorEscenes::ContextEscenes& context); + ~EscenaLogo(); // Destructor per aturar sons void executar(); // Bucle principal de l'escena private: