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 0000000..96093f2 Binary files /dev/null and b/data/sound/game_start.wav differ diff --git a/source/director.cpp b/source/director.cpp index ff848db..bbc31ca 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -388,6 +388,7 @@ void Director::setFileList() Asset::get()->add(prefix + "/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; }