From b8dca0a46f6f2b5c4180c4c2a22a781369ebdbf2 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 26 Dec 2024 10:03:02 +0100 Subject: [PATCH] =?UTF-8?q?Fet=20el=20fade=20out=20del=20title=20de=20vide?= =?UTF-8?q?o=20i=20audio=20i=20el=20fade=20in=20del=20joc=20de=20video=20i?= =?UTF-8?q?=20audio=20Actualitzat=20jail=5Faudio=20a=20la=20=C3=BAltima=20?= =?UTF-8?q?versi=C3=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/config/param_320x256.txt | 2 +- data/sound/game_start.wav | Bin 0 -> 78286 bytes source/director.cpp | 1 + source/fade.cpp | 67 ++---- source/fade.h | 22 +- source/game.cpp | 64 +++--- source/game.h | 6 +- source/jail_audio.cpp | 372 ++++++++++++++++++---------------- source/jail_audio.h | 36 ++-- source/title.cpp | 13 +- 10 files changed, 287 insertions(+), 296 deletions(-) create mode 100644 data/sound/game_start.wav diff --git a/data/config/param_320x256.txt b/data/config/param_320x256.txt index ee312d0..4908f1d 100644 --- a/data/config/param_320x256.txt +++ b/data/config/param_320x256.txt @@ -14,7 +14,7 @@ fade.num_squares_height 128 fade.random_squares_delay 1 fade.random_squares_mult 500 fade.post_duration 80 -fade.venetian_size 16 +fade.venetian_size 12 ## SCOREBOARD scoreboard.x 0 diff --git a/data/sound/game_start.wav b/data/sound/game_start.wav new file mode 100644 index 0000000000000000000000000000000000000000..96093f29588c3aaa9b1aa5e33e42f817a6859018 GIT binary patch literal 78286 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

)OBTc2^vT&ra_0x11fNl9vkM$O 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 + "/data/music/credits.ogg", AssetType::MUSIC); // Sonidos + Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/balloon.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble1.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble2.wav", AssetType::SOUND); diff --git a/source/fade.cpp b/source/fade.cpp index 6042fe0..119f8bc 100644 --- a/source/fade.cpp +++ b/source/fade.cpp @@ -123,7 +123,6 @@ void Fade::update() // Dibuja sobre el backbuffer_ auto temp = SDL_GetRenderTarget(renderer_); SDL_SetRenderTarget(renderer_, backbuffer_); - SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_NONE); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_); @@ -135,8 +134,6 @@ void Fade::update() SDL_RenderFillRect(renderer_, &square_[index2]); } - SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); - // Deja el renderizador como estaba SDL_SetRenderTarget(renderer_, temp); } @@ -160,9 +157,11 @@ void Fade::update() // Dibuja sobre el backbuffer_ auto temp = SDL_GetRenderTarget(renderer_); SDL_SetRenderTarget(renderer_, backbuffer_); - + SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_NONE); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_); - for (auto rect : square_) + + // Dibuja el cuadrado correspondiente + for (const auto rect : square_) { SDL_RenderFillRect(renderer_, &rect); } @@ -170,11 +169,12 @@ void Fade::update() // Deja el renderizador como estaba SDL_SetRenderTarget(renderer_, temp); - const auto h = counter_ / 3; - for (int i = 0; i < (int)square_.size(); ++i) + // Modifica el tamaño de los rectangulos + const auto h = counter_ / 2; + for (size_t i = 0; i < square_.size(); ++i) { // A partir del segundo rectangulo se pinta en función del anterior - square_[i].h = i == 0 ? h : std::max(square_[i - 1].h - 3, 0); + square_.at(i).h = i == 0 ? h : std::max(square_.at(i - 1).h - 2, 0); } } else @@ -255,12 +255,8 @@ void Fade::activate() } // Limpia la textura - auto temp = SDL_GetRenderTarget(renderer_); - SDL_SetRenderTarget(renderer_, backbuffer_); a_ = mode_ == FadeMode::OUT ? 0 : 255; - SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_); - SDL_RenderClear(renderer_); - SDL_SetRenderTarget(renderer_, temp); + cleanBackbuffer(r_, g_, b_, a_); // Deja el color listo para usar a_ = mode_ == FadeMode::OUT ? 255 : 0; @@ -270,12 +266,16 @@ void Fade::activate() case FadeType::VENETIAN: { - cleanBackbuffer(0, 0, 0, 0); - rect1_ = {0, 0, param.game.width, 0}; - square_.clear(); - a_ = 255; + // Limpia la textura + a_ = mode_ == FadeMode::OUT ? 0 : 255; + cleanBackbuffer(r_, g_, b_, a_); + + // Deja el color listo para usar + a_ = mode_ == FadeMode::OUT ? 255 : 0; // Añade los cuadrados al vector + square_.clear(); + rect1_ = {0, 0, param.game.width, 0}; const int max = param.game.height / param.fade.venetian_size; for (int i = 0; i < max; ++i) @@ -289,31 +289,6 @@ void Fade::activate() } } -// Comprueba si está activo -bool Fade::isEnabled() const -{ - return enabled_; -} - -// Comprueba si ha terminado la transicion -bool Fade::hasEnded() const -{ - // Ha terminado cuando ha finalizado la transición y se ha deshabilitado - return !enabled_ && finished_; -} - -// Establece el tipo de fade -void Fade::setType(FadeType type) -{ - type_ = type; -} - -// Establece el modo de fade -void Fade::setMode(FadeMode mode) -{ - mode_ = mode; -} - // Establece el color del fade void Fade::setColor(Uint8 r, Uint8 g, Uint8 b) { @@ -322,12 +297,6 @@ void Fade::setColor(Uint8 r, Uint8 g, Uint8 b) b_ = b; } -// Establece la duración posterior -void Fade::setPost(int value) -{ - post_duration_ = value; -} - // Limpia el backbuffer void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { @@ -347,6 +316,8 @@ void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a) int Fade::calculateValue(int min, int max, int current) { if (max == 0) + { return 0; + } return std::clamp(current * 100 / max, 0, 100); } \ No newline at end of file diff --git a/source/fade.h b/source/fade.h index f10950b..b41dc6d 100644 --- a/source/fade.h +++ b/source/fade.h @@ -75,24 +75,16 @@ public: // Activa el fade void activate(); - // Comprueba si ha terminado la transicion - bool hasEnded() const; - - // Comprueba si está activo - bool isEnabled() const; - - // Establece el tipo de fade - void setType(FadeType type); - - // Establece el modo de fade - void setMode(FadeMode mode); - // Establece el color del fade void setColor(Uint8 r, Uint8 g, Uint8 b); - // Establece la duración posterior - void setPost(int value); - // Getters int getValue() const { return value_; } + bool isEnabled() const { return enabled_; } + bool hasEnded() const { return !enabled_ && finished_; } + + // Setters + void setType(FadeType type) { type_ = type; } + void setMode(FadeMode mode) { mode_ = mode; } + void setPost(int value) { post_duration_ = value; } }; \ No newline at end of file diff --git a/source/game.cpp b/source/game.cpp index b12365a..432d548 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -65,8 +65,8 @@ Game::Game(int player_id, int current_stage, bool demo) scoreboard_ = Scoreboard::get(); fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b); - fade_in_->setPost(param.fade.post_duration); - fade_in_->setType(FadeType::RANDOM_SQUARE); + fade_in_->setPost(0); + fade_in_->setType(FadeType::VENETIAN); fade_in_->setMode(FadeMode::IN); fade_in_->activate(); @@ -94,14 +94,6 @@ Game::Game(int player_id, int current_stage, bool demo) Stage::total_power += Stage::get(i).power_to_complete; } #endif - - // Crea los primeros globos y el mensaje de inicio - if (!demo_.enabled) - { - balloon_manager_->createTwoBigBalloons(); - evaluateAndSetMenace(); - createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("get_ready")); - } } Game::~Game() @@ -282,6 +274,26 @@ void Game::updateStage() } } +// Actualiza el estado de fade in +void Game::updateFadeInState() +{ + if (state_ == GameState::FADE_IN) + { + if (fade_in_->hasEnded()) + { + state_ = GameState::PLAYING; + + // Crea los primeros globos y el mensaje de inicio + if (!demo_.enabled) + { + balloon_manager_->createTwoBigBalloons(); + evaluateAndSetMenace(); + createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("get_ready")); + } + } + } +} + // Actualiza el estado de fin de la partida void Game::updateGameOverState() { @@ -969,7 +981,7 @@ void Game::disableTimeStopItem() void Game::checkMusicStatus() { // Si se ha completado el juego o los jugadores han terminado, detiene la música - state_ == GameState::COMPLETED || allPlayersAreGameOver() ? stopMusic() : playMusic(); + state_ == GameState::FADE_IN || state_ == GameState::COMPLETED || allPlayersAreGameOver() ? stopMusic() : playMusic(); } // Bucle para el juego @@ -1781,6 +1793,7 @@ void Game::updateGame() moveBullets(); updateItems(); updateStage(); + updateFadeInState(); updateGameOverState(); updateCompletedState(); updateSmartSprites(); @@ -1808,21 +1821,24 @@ void Game::cleanVectors() // Gestiona el nivel de amenaza void Game::updateMenace() { - const auto stage = Stage::get(Stage::number); - const float percent = Stage::power / stage.power_to_complete; - const int difference = stage.max_menace - stage.min_menace; - - // Aumenta el nivel de amenaza en función de la puntuación - menace_threshold_ = stage.min_menace + (difference * percent); - - // Si el nivel de amenza es inferior al umbral - if (menace_current_ < menace_threshold_) + if (state_ == GameState::PLAYING) { - // Crea una formación de enemigos - balloon_manager_->deployBalloonFormation(Stage::number); + const auto stage = Stage::get(Stage::number); + const float percent = Stage::power / stage.power_to_complete; + const int difference = stage.max_menace - stage.min_menace; - // Recalcula el nivel de amenaza con el nuevo globo - evaluateAndSetMenace(); + // Aumenta el nivel de amenaza en función de la puntuación + menace_threshold_ = stage.min_menace + (difference * percent); + + // Si el nivel de amenza es inferior al umbral + if (menace_current_ < menace_threshold_) + { + // Crea una formación de enemigos + balloon_manager_->deployBalloonFormation(Stage::number); + + // Recalcula el nivel de amenaza con el nuevo globo + evaluateAndSetMenace(); + } } } diff --git a/source/game.h b/source/game.h index 6f142d4..528f6d2 100644 --- a/source/game.h +++ b/source/game.h @@ -65,6 +65,7 @@ private: // Enum enum class GameState { + FADE_IN, PLAYING, COMPLETED, GAME_OVER, @@ -165,7 +166,7 @@ private: int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases int menace_current_ = 0; // Nivel de amenaza actual int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos - GameState state_ = GameState::PLAYING; // Estado + GameState state_ = GameState::FADE_IN; // Estado #ifdef DEBUG bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados #endif @@ -194,6 +195,9 @@ private: // Comprueba si hay cambio de fase y actualiza las variables void updateStage(); + // Actualiza el estado de fade in + void updateFadeInState(); + // Actualiza el estado de fin de la partida void updateGameOverState(); diff --git a/source/jail_audio.cpp b/source/jail_audio.cpp index 47af976..be7031b 100644 --- a/source/jail_audio.cpp +++ b/source/jail_audio.cpp @@ -1,91 +1,91 @@ #ifndef JA_USESDLMIXER - #include "jail_audio.h" -#include // para uint8_t -#include // para NULL, fseek, fclose, fopen, fread, ftell, FILE -#include // para free, malloc -#include "stb_vorbis.c" // para stb_vorbis_decode_memory +#include "stb_vorbis.c" +#include +#include #define JA_MAX_SIMULTANEOUS_CHANNELS 5 -struct JA_Sound_t -{ - Uint32 length{0}; - Uint8 *buffer{NULL}; +struct JA_Sound_t { + Uint32 length {0}; + Uint8* buffer {NULL}; }; -struct JA_Channel_t -{ - JA_Sound_t *sound; - int pos{0}; - int times{0}; - JA_Channel_state state{JA_CHANNEL_FREE}; +struct JA_Channel_t { + JA_Sound_t *sound; + int pos {0}; + int times {0}; + JA_Channel_state state { JA_CHANNEL_FREE }; }; -struct JA_Music_t -{ - int samples{0}; - int pos{0}; - int times{0}; - short *output{NULL}; - JA_Music_state state{JA_MUSIC_INVALID}; +struct JA_Music_t { + int samples {0}; + int pos {0}; + int times {0}; + short* output {NULL}; + JA_Music_state state {JA_MUSIC_INVALID}; }; -JA_Music_t *current_music{NULL}; -JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; +JA_Music_t *current_music{NULL}; +JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; -int JA_freq{48000}; -SDL_AudioFormat JA_format{AUDIO_S16}; -Uint8 JA_channels{2}; -int JA_musicVolume = 128; -int JA_soundVolume = 64; -bool JA_musicEnabled = true; -bool JA_soundEnabled = true; +int JA_freq {48000}; +SDL_AudioFormat JA_format {AUDIO_S16}; +Uint8 JA_channels {2}; +int JA_musicVolume = 128; +int JA_soundVolume = 64; +bool JA_musicEnabled = true; +bool JA_soundEnabled = true; SDL_AudioDeviceID sdlAudioDevice = 0; -void audioCallback(void *userdata, uint8_t *stream, int len) -{ +bool fading = false; +int fade_start_time; +int fade_duration; +int fade_initial_volume; + +void audioCallback(void * userdata, uint8_t * stream, int len) { SDL_memset(stream, 0, len); - if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) - { - const int size = SDL_min(len, current_music->samples * 2 - current_music->pos); - SDL_MixAudioFormat(stream, (Uint8 *)(current_music->output + current_music->pos), AUDIO_S16, size, JA_musicVolume); - current_music->pos += size / 2; - if (size < len) - { - if (current_music->times != 0) - { - SDL_MixAudioFormat(stream + size, (Uint8 *)current_music->output, AUDIO_S16, len - size, JA_musicVolume); - current_music->pos = (len - size) / 2; - if (current_music->times > 0) - current_music->times--; + if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { + int volume = JA_musicVolume; + if (fading) { + int time = SDL_GetTicks(); + if (time > (fade_start_time+fade_duration)) { + fading = false; + current_music->pos = 0; + current_music->state = JA_MUSIC_STOPPED; + volume = 0; + } else { + const int time_passed = time - fade_start_time; + const float percent = (float)time_passed / (float)fade_duration; + volume = JA_musicVolume * (1.0 - percent); } - else - { + } + const int size = SDL_min(len, (current_music->samples-current_music->pos)*2); + SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, volume); + current_music->pos += size/2; + if (size < len) { + if (current_music->times != 0) { + SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, volume); + current_music->pos = (len-size)/2; + if (current_music->times > 0) current_music->times--; + } else { current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } } } // Mixar els channels mi amol - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) - { - if (channels[i].state == JA_CHANNEL_PLAYING) - { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].state == JA_CHANNEL_PLAYING) { const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume); channels[i].pos += size; - if (size < len) - { - if (channels[i].times != 0) - { - SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume); - channels[i].pos = len - size; - if (channels[i].times > 0) - channels[i].times--; - } - else - { + if (size < len) { + if (channels[i].times != 0) { + SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume); + channels[i].pos = len-size; + if (channels[i].times > 0) channels[i].times--; + } else { JA_StopChannel(i); } } @@ -95,55 +95,52 @@ void audioCallback(void *userdata, uint8_t *stream, int len) void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) { + #ifdef DEBUG + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG); + #endif + + SDL_Log("Iniciant JailAudio..."); JA_freq = freq; JA_format = format; JA_channels = channels; SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; - if (sdlAudioDevice != 0) - SDL_CloseAudioDevice(sdlAudioDevice); + if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); + if (sdlAudioDevice==0) + { + SDL_Log("FAILED!\n"); + SDL_Log("Failed to initialize SDL audio!\n"); + } else { + SDL_Log("OK!\n"); + } SDL_PauseAudioDevice(sdlAudioDevice, 0); } -void JA_Quit() -{ +void JA_Quit() { SDL_PauseAudioDevice(sdlAudioDevice, 1); - if (sdlAudioDevice != 0) - SDL_CloseAudioDevice(sdlAudioDevice); + if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); sdlAudioDevice = 0; } -JA_Music_t *JA_LoadMusic(const char *filename) +JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length) { int chan, samplerate; - - // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. - FILE *f = fopen(filename, "rb"); - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - Uint8 *buffer = (Uint8 *)malloc(fsize + 1); - if (fread(buffer, fsize, 1, f) != 1) - return NULL; - fclose(f); - JA_Music_t *music = new JA_Music_t(); - music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output); - free(buffer); + music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output); // [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert - // music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); +// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); - if (cvt.needed) - { + SDL_Log("Music length: %f\n", float(music->samples)/float(JA_freq)); + if (cvt.needed) { cvt.len = music->samples * chan * 2; - cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult); + cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); SDL_memcpy(cvt.buf, music->output, cvt.len); SDL_ConvertAudio(&cvt); free(music->output); - music->output = (short *)cvt.buf; + music->output = (short*)cvt.buf; } music->pos = 0; music->state = JA_MUSIC_STOPPED; @@ -151,13 +148,29 @@ JA_Music_t *JA_LoadMusic(const char *filename) return music; } +JA_Music_t *JA_LoadMusic(const char* filename) +{ + // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. + FILE *f = fopen(filename, "rb"); + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + Uint8 *buffer = (Uint8*)malloc(fsize + 1); + if (fread(buffer, fsize, 1, f)!=1) return NULL; + fclose(f); + + JA_Music_t *music = JA_LoadMusic(buffer, fsize); + + free(buffer); + + return music; +} + void JA_PlayMusic(JA_Music_t *music, const int loop) { - if (!JA_musicEnabled || !music) - return; + if (!JA_musicEnabled) return; - if (current_music != NULL) - { + if (current_music != NULL) { current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } @@ -169,78 +182,108 @@ void JA_PlayMusic(JA_Music_t *music, const int loop) void JA_PauseMusic() { - if (!JA_musicEnabled) - return; + if (!JA_musicEnabled) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; current_music->state = JA_MUSIC_PAUSED; } void JA_ResumeMusic() { - if (!JA_musicEnabled) - return; + if (!JA_musicEnabled) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; current_music->state = JA_MUSIC_PLAYING; } void JA_StopMusic() { - if (!JA_musicEnabled) - return; + if (!JA_musicEnabled) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; } -JA_Music_state JA_GetMusicState() +void JA_FadeOutMusic(const int milliseconds) { - if (!JA_musicEnabled) - return JA_MUSIC_DISABLED; + if (!JA_musicEnabled) return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; - if (current_music == NULL) - return JA_MUSIC_INVALID; + fading = true; + fade_start_time = SDL_GetTicks(); + fade_duration = milliseconds; + fade_initial_volume = JA_musicVolume; +} + +JA_Music_state JA_GetMusicState() { + if (!JA_musicEnabled) return JA_MUSIC_DISABLED; + + if (current_music == NULL) return JA_MUSIC_INVALID; return current_music->state; } -void JA_DeleteMusic(JA_Music_t *music) -{ - if (current_music == music) - current_music = NULL; +void JA_DeleteMusic(JA_Music_t *music) { + if (current_music == music) current_music = NULL; free(music->output); delete music; } int JA_SetMusicVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; + JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; return JA_musicVolume; } +void JA_SetMusicPosition(float value) +{ + if (!current_music) return; + current_music->pos = value * JA_freq; +} + +float JA_GetMusicPosition() +{ + if (!current_music) return 0; + return float(current_music->pos)/float(JA_freq); +} + void JA_EnableMusic(const bool value) { - if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING) - JA_StopMusic(); + if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic(); JA_musicEnabled = value; } -JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length) -{ + + + + +JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) { JA_Sound_t *sound = new JA_Sound_t(); sound->buffer = buffer; sound->length = length; return sound; } -JA_Sound_t *JA_LoadSound(const char *filename) -{ +JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) { + JA_Sound_t *sound = new JA_Sound_t(); + SDL_AudioSpec wavSpec; + SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size),1, &wavSpec, &sound->buffer, &sound->length); + + SDL_AudioCVT cvt; + SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); + cvt.len = sound->length; + cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); + SDL_memcpy(cvt.buf, sound->buffer, sound->length); + SDL_ConvertAudio(&cvt); + SDL_FreeWAV(sound->buffer); + sound->buffer = cvt.buf; + sound->length = cvt.len_cvt; + + return sound; +} + +JA_Sound_t *JA_LoadSound(const char* filename) { JA_Sound_t *sound = new JA_Sound_t(); SDL_AudioSpec wavSpec; SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); @@ -248,7 +291,7 @@ JA_Sound_t *JA_LoadSound(const char *filename) SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); cvt.len = sound->length; - cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult); + cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); SDL_memcpy(cvt.buf, sound->buffer, sound->length); SDL_ConvertAudio(&cvt); SDL_FreeWAV(sound->buffer); @@ -260,16 +303,11 @@ JA_Sound_t *JA_LoadSound(const char *filename) int JA_PlaySound(JA_Sound_t *sound, const int loop) { - if (!JA_soundEnabled || !sound) - return 0; + if (!JA_soundEnabled) return -1; int channel = 0; - while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) - { - channel++; - } - if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) - channel = 0; + while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } + if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; channels[channel].sound = sound; channels[channel].times = loop; @@ -280,10 +318,8 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop) void JA_DeleteSound(JA_Sound_t *sound) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) - { - if (channels[i].sound == sound) - JA_StopChannel(i); + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].sound == sound) JA_StopChannel(i); } SDL_free(sound->buffer); delete sound; @@ -291,60 +327,41 @@ void JA_DeleteSound(JA_Sound_t *sound) void JA_PauseChannel(const int channel) { - if (!JA_soundEnabled) - return; + if (!JA_soundEnabled) return; - if (channel == -1) - { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) - { - if (channels[i].state == JA_CHANNEL_PLAYING) - channels[i].state = JA_CHANNEL_PAUSED; + if (channel == -1) { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED; } - } - else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) - { - if (channels[channel].state == JA_CHANNEL_PLAYING) - channels[channel].state = JA_CHANNEL_PAUSED; + } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { + if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED; } } void JA_ResumeChannel(const int channel) { - if (!JA_soundEnabled) - return; + if (!JA_soundEnabled) return; - if (channel == -1) - { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) - { - if (channels[i].state == JA_CHANNEL_PAUSED) - channels[i].state = JA_CHANNEL_PLAYING; + if (channel == -1) { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING; } - } - else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) - { - if (channels[channel].state == JA_CHANNEL_PAUSED) - channels[channel].state = JA_CHANNEL_PLAYING; + } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { + if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING; } } void JA_StopChannel(const int channel) { - if (!JA_soundEnabled) - return; + if (!JA_soundEnabled) return; - if (channel == -1) - { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) - { + if (channel == -1) { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { channels[i].state = JA_CHANNEL_FREE; channels[i].pos = 0; channels[i].sound = NULL; } - } - else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) - { + } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { channels[channel].state = JA_CHANNEL_FREE; channels[channel].pos = 0; channels[channel].sound = NULL; @@ -353,18 +370,15 @@ void JA_StopChannel(const int channel) JA_Channel_state JA_GetChannelState(const int channel) { - if (!JA_soundEnabled) - return JA_SOUND_DISABLED; + if (!JA_soundEnabled) return JA_SOUND_DISABLED; - if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) - return JA_CHANNEL_INVALID; + if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; return channels[channel].state; } int JA_SetSoundVolume(int volume) { - JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; + JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; return JA_soundVolume; } @@ -372,17 +386,15 @@ void JA_EnableSound(const bool value) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) - JA_StopChannel(i); + if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i); } JA_soundEnabled = value; } int JA_SetVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; - JA_soundVolume = JA_musicVolume / 2; + JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; + JA_soundVolume = JA_musicVolume/2; return JA_musicVolume; } diff --git a/source/jail_audio.h b/source/jail_audio.h index 6f96f50..d4d8772 100644 --- a/source/jail_audio.h +++ b/source/jail_audio.h @@ -1,42 +1,32 @@ #pragma once +#include -#include // para SDL_AudioFormat -#include // para Uint32, Uint8 -struct JA_Music_t; // lines 5-5 -struct JA_Sound_t; // lines 6-6 +enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED }; +enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED }; -enum JA_Channel_state -{ - JA_CHANNEL_INVALID, - JA_CHANNEL_FREE, - JA_CHANNEL_PLAYING, - JA_CHANNEL_PAUSED, - JA_SOUND_DISABLED -}; -enum JA_Music_state -{ - JA_MUSIC_INVALID, - JA_MUSIC_PLAYING, - JA_MUSIC_PAUSED, - JA_MUSIC_STOPPED, - JA_MUSIC_DISABLED -}; +struct JA_Sound_t; +struct JA_Music_t; void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); void JA_Quit(); -JA_Music_t *JA_LoadMusic(const char *filename); +JA_Music_t *JA_LoadMusic(const char* filename); +JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length); void JA_PlayMusic(JA_Music_t *music, const int loop = -1); void JA_PauseMusic(); void JA_ResumeMusic(); void JA_StopMusic(); +void JA_FadeOutMusic(const int milliseconds); JA_Music_state JA_GetMusicState(); void JA_DeleteMusic(JA_Music_t *music); int JA_SetMusicVolume(int volume); +void JA_SetMusicPosition(float value); +float JA_GetMusicPosition(); void JA_EnableMusic(const bool value); -JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length); -JA_Sound_t *JA_LoadSound(const char *filename); +JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length); +JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length); +JA_Sound_t *JA_LoadSound(const char* filename); int JA_PlaySound(JA_Sound_t *sound, const int loop = 0); void JA_PauseChannel(const int channel); void JA_ResumeChannel(const int channel); diff --git a/source/title.cpp b/source/title.cpp index a35be30..c9e3981 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -31,7 +31,7 @@ Title::Title() fade_(std::make_unique()), tiled_bg_(std::make_unique(param.game.game_area.rect, TiledBGMode::RANDOM)), game_logo_(std::make_unique(param.game.game_area.center_x, param.title.title_c_c_position)), - mini_logo_sprite_(std::make_unique(Resource::get()->getTexture("logo_jailgames_mini.png"))), + mini_logo_sprite_(std::make_unique(Resource::get()->getTexture("logo_jailgames_mini.png"))), define_buttons_(std::make_unique()), num_controllers_(Input::get()->getNumControllers()) { @@ -71,11 +71,11 @@ void Title::update() Screen::get()->update(); // Actualiza las variables de globalInputs - globalInputs::update(); + globalInputs::update(); // Comprueba el fundido y si se ha acabado fade_->update(); - JA_SetMusicVolume(100 - fade_->getValue()); + // JA_SetMusicVolume(100 - fade_->getValue()); if (fade_->hasEnded()) { if (post_fade_ == -1) @@ -109,7 +109,10 @@ void Title::update() // Reproduce la música if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) { - JA_PlayMusic(Resource::get()->getMusic("title.ogg")); + if (!fade_->isEnabled()) + { + JA_PlayMusic(Resource::get()->getMusic("title.ogg")); + } } // Actualiza el logo con el título del juego @@ -255,6 +258,8 @@ void Title::checkInput() if (section::options == section::Options::TITLE_2 || ALLOW_TITLE_ANIMATION_SKIP) { fade_->activate(); + JA_FadeOutMusic(1500); + JA_PlaySound(Resource::get()->getSound("game_start.wav")); post_fade_ = controller.player_id; return; }