forked from jaildesigner-jailgames/jaildoctors_dilemma
afegida la clase Audio
This commit is contained in:
@@ -33,6 +33,9 @@ configure_file(${CMAKE_SOURCE_DIR}/source/version.h.in ${CMAKE_BINARY_DIR}/versi
|
|||||||
|
|
||||||
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
||||||
set(APP_SOURCES
|
set(APP_SOURCES
|
||||||
|
# Core - Audio
|
||||||
|
source/core/audio/audio.cpp
|
||||||
|
|
||||||
# Core - Input
|
# Core - Input
|
||||||
source/core/input/global_inputs.cpp
|
source/core/input/global_inputs.cpp
|
||||||
source/core/input/input.cpp
|
source/core/input/input.cpp
|
||||||
|
|||||||
170
source/core/audio/audio.cpp
Normal file
170
source/core/audio/audio.cpp
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#include "audio.hpp"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_G...
|
||||||
|
|
||||||
|
#include <algorithm> // Para clamp
|
||||||
|
#include <iostream> // 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<int>(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<int>(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";
|
||||||
|
}
|
||||||
|
}
|
||||||
111
source/core/audio/audio.hpp
Normal file
111
source/core/audio/audio.hpp
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string> // Para string
|
||||||
|
#include <utility> // Para move
|
||||||
|
|
||||||
|
// --- Clase Audio: gestor de audio (singleton) ---
|
||||||
|
class Audio {
|
||||||
|
public:
|
||||||
|
// --- Enums ---
|
||||||
|
enum class Group : int {
|
||||||
|
ALL = -1, // Todos los grupos
|
||||||
|
GAME = 0, // Sonidos del juego
|
||||||
|
INTERFACE = 1 // Sonidos de la interfaz
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MusicState {
|
||||||
|
PLAYING, // Reproduciendo música
|
||||||
|
PAUSED, // Música pausada
|
||||||
|
STOPPED, // Música detenida
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constantes ---
|
||||||
|
static constexpr int MAX_VOLUME = 100; // Volumen máximo
|
||||||
|
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
|
||||||
|
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
|
||||||
|
|
||||||
|
// --- Métodos de singleton ---
|
||||||
|
static void init(); // Inicializa el objeto Audio
|
||||||
|
static void destroy(); // Libera el objeto Audio
|
||||||
|
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
||||||
|
Audio(const Audio&) = delete; // Evitar copia
|
||||||
|
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
||||||
|
|
||||||
|
// --- Método principal ---
|
||||||
|
static void update();
|
||||||
|
|
||||||
|
// --- Control de Música ---
|
||||||
|
void playMusic(const std::string& name, int loop = -1); // Reproducir música en bucle
|
||||||
|
void pauseMusic(); // Pausar reproducción de música
|
||||||
|
void resumeMusic(); // Continua la música pausada
|
||||||
|
void stopMusic(); // Detener completamente la música
|
||||||
|
void fadeOutMusic(int milliseconds) const; // Fundido de salida de la música
|
||||||
|
|
||||||
|
// --- Control de Sonidos ---
|
||||||
|
void playSound(const std::string& name, Group group = Group::GAME) const; // Reproducir sonido puntual
|
||||||
|
void stopAllSounds() const; // Detener todos los sonidos
|
||||||
|
|
||||||
|
// --- Configuración General ---
|
||||||
|
void enable(bool value); // Establecer estado general
|
||||||
|
void toggleEnabled() { enabled_ = !enabled_; } // Alternar estado general
|
||||||
|
void applySettings(); // Aplica la configuración
|
||||||
|
|
||||||
|
// --- Configuración de Sonidos ---
|
||||||
|
void enableSound() { sound_enabled_ = true; } // Habilitar sonidos
|
||||||
|
void disableSound() { sound_enabled_ = false; } // Deshabilitar sonidos
|
||||||
|
void enableSound(bool value) { sound_enabled_ = value; } // Establecer estado de sonidos
|
||||||
|
void toggleSound() { sound_enabled_ = !sound_enabled_; } // Alternar estado de sonidos
|
||||||
|
|
||||||
|
// --- Configuración de Música ---
|
||||||
|
void enableMusic() { music_enabled_ = true; } // Habilitar música
|
||||||
|
void disableMusic() { music_enabled_ = false; } // Deshabilitar música
|
||||||
|
void enableMusic(bool value) { music_enabled_ = value; } // Establecer estado de música
|
||||||
|
void toggleMusic() { music_enabled_ = !music_enabled_; } // Alternar estado de música
|
||||||
|
|
||||||
|
// --- Control de Volumen ---
|
||||||
|
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
||||||
|
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
||||||
|
|
||||||
|
// --- Getters para debug ---
|
||||||
|
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
|
||||||
|
[[nodiscard]] auto isSoundEnabled() const -> bool { return sound_enabled_; }
|
||||||
|
[[nodiscard]] auto isMusicEnabled() const -> bool { return music_enabled_; }
|
||||||
|
[[nodiscard]] auto getMusicState() const -> MusicState { return music_.state; }
|
||||||
|
[[nodiscard]] static auto getRealMusicState() -> MusicState; // Consulta directamente a jailaudio
|
||||||
|
[[nodiscard]] auto getCurrentMusicName() const -> const std::string& { return music_.name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// --- Estructuras privadas ---
|
||||||
|
struct Music {
|
||||||
|
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
||||||
|
std::string name; // Última pista de música reproducida
|
||||||
|
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
||||||
|
|
||||||
|
// Constructor para inicializar la música con valores predeterminados
|
||||||
|
Music()
|
||||||
|
: state(MusicState::STOPPED),
|
||||||
|
loop(false) {}
|
||||||
|
|
||||||
|
// Constructor para inicializar con valores específicos
|
||||||
|
Music(MusicState init_state, std::string init_name, bool init_loop)
|
||||||
|
: state(init_state),
|
||||||
|
name(std::move(init_name)),
|
||||||
|
loop(init_loop) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Variables de estado ---
|
||||||
|
Music music_; // Estado de la música
|
||||||
|
bool enabled_ = true; // Estado general del audio
|
||||||
|
bool sound_enabled_ = true; // Estado de los efectos de sonido
|
||||||
|
bool music_enabled_ = true; // Estado de la música
|
||||||
|
|
||||||
|
// --- Métodos internos ---
|
||||||
|
void initSDLAudio(); // Inicializa SDL Audio
|
||||||
|
|
||||||
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
|
Audio(); // Constructor privado
|
||||||
|
~Audio(); // Destructor privado
|
||||||
|
|
||||||
|
// --- Instancia singleton ---
|
||||||
|
static Audio* instance; // Instancia única de Audio
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user