#include "audio.hpp" #include // Para SDL_LogInfo, SDL_LogCategory, SDL_G... #include // Para clamp #include // Para std::cout #include "core/resources/resource.hpp" // Para Resource #include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM... #include "game/options.hpp" // Para AudioOptions, audio, MusicOptions // Singleton Audio* Audio::instance = nullptr; // Inicializa la instancia única del singleton void Audio::init() { Audio::instance = new Audio(); } // Libera la instancia void Audio::destroy() { delete Audio::instance; } // Obtiene la instancia auto Audio::get() -> Audio* { return Audio::instance; } // Constructor Audio::Audio() { initSDLAudio(); } // Destructor Audio::~Audio() { JA_Quit(); } // Método principal void Audio::update() { JA_Update(); } // Reproduce la música void Audio::playMusic(const std::string& name, const int loop) { bool newLoop = (loop != 0); // Si ya está sonando exactamente la misma pista y mismo modo loop, no hacemos nada if (music_.state == MusicState::PLAYING && music_.name == name && music_.loop == newLoop) { return; } // Intentar obtener recurso; si falla, no tocar estado auto* resource = Resource::get()->getMusic(name); if (!resource) { // manejo de error opcional return; } // Si hay algo reproduciéndose, detenerlo primero (si el backend lo requiere) if (music_.state == MusicState::PLAYING) { JA_StopMusic(); // sustituir por la función de stop real del API si tiene otro nombre } // Llamada al motor para reproducir la nueva pista JA_PlayMusic(resource, loop); // Actualizar estado y metadatos después de iniciar con éxito music_.name = name; music_.loop = newLoop; music_.state = MusicState::PLAYING; } // Pausa la música void Audio::pauseMusic() { if (music_enabled_ && music_.state == MusicState::PLAYING) { JA_PauseMusic(); music_.state = MusicState::PAUSED; } } // Continua la música pausada void Audio::resumeMusic() { if (music_enabled_ && music_.state == MusicState::PAUSED) { JA_ResumeMusic(); music_.state = MusicState::PLAYING; } } // Detiene la música void Audio::stopMusic() { if (music_enabled_) { JA_StopMusic(); music_.state = MusicState::STOPPED; } } // Reproduce un sonido void Audio::playSound(const std::string& name, Group group) const { if (sound_enabled_) { JA_PlaySound(Resource::get()->getSound(name), 0, static_cast(group)); } } // Detiene todos los sonidos void Audio::stopAllSounds() const { if (sound_enabled_) { JA_StopChannel(-1); } } // Realiza un fundido de salida de la música void Audio::fadeOutMusic(int milliseconds) const { if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) { JA_FadeOutMusic(milliseconds); } } // Consulta directamente el estado real de la música en jailaudio auto Audio::getRealMusicState() -> MusicState { JA_Music_state ja_state = JA_GetMusicState(); switch (ja_state) { case JA_MUSIC_PLAYING: return MusicState::PLAYING; case JA_MUSIC_PAUSED: return MusicState::PAUSED; case JA_MUSIC_STOPPED: case JA_MUSIC_INVALID: case JA_MUSIC_DISABLED: default: return MusicState::STOPPED; } } // Establece el volumen de los sonidos void Audio::setSoundVolume(int sound_volume, Group group) const { if (sound_enabled_) { sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME); const float CONVERTED_VOLUME = (sound_volume / 100.0F) * (Options::audio.volume / 100.0F); JA_SetSoundVolume(CONVERTED_VOLUME, static_cast(group)); } } // Establece el volumen de la música void Audio::setMusicVolume(int music_volume) const { if (music_enabled_) { music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME); const float CONVERTED_VOLUME = (music_volume / 100.0F) * (Options::audio.volume / 100.0F); JA_SetMusicVolume(CONVERTED_VOLUME); } } // Aplica la configuración void Audio::applySettings() { enable(Options::audio.enabled); } // Establecer estado general void Audio::enable(bool value) { enabled_ = value; setSoundVolume(enabled_ ? Options::audio.sound.volume : MIN_VOLUME); setMusicVolume(enabled_ ? Options::audio.music.volume : MIN_VOLUME); } // Inicializa SDL Audio void Audio::initSDLAudio() { if (!SDL_Init(SDL_INIT_AUDIO)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_AUDIO could not initialize! SDL Error: %s", SDL_GetError()); } else { JA_Init(FREQUENCY, SDL_AUDIO_S16LE, 2); enable(Options::audio.enabled); std::cout << "Audio system initialized successfully\n"; } }