From 13e8442ffd53aa1e1ed9179957c018e9183f4161 Mon Sep 17 00:00:00 2001 From: XProger Date: Sun, 11 Mar 2018 04:51:13 +0300 Subject: [PATCH] looped background soundtrack, playing both underwater and soundtrack at the same time --- src/controller.h | 4 +- src/game.h | 2 +- src/level.h | 138 +++++++++++++++++++++++------------------------ 3 files changed, 69 insertions(+), 75 deletions(-) diff --git a/src/controller.h b/src/controller.h index 57074ac..c3312f7 100644 --- a/src/controller.h +++ b/src/controller.h @@ -91,8 +91,8 @@ struct IGame { virtual bool invChooseKey(int playerIndex, TR::Entity::Type hole) { return false; } virtual Sound::Sample* playSound(int id, const vec3 &pos = vec3(0.0f), int flags = 0) const { return NULL; } - virtual void playTrack(uint8 track, bool restart = false) {} - virtual void stopTrack() {} + virtual void playTrack(uint8 track) {} + virtual void stopTrack() {} }; struct Controller { diff --git a/src/game.h b/src/game.h index 74b16f6..fc9d17a 100644 --- a/src/game.h +++ b/src/game.h @@ -57,9 +57,9 @@ namespace Game { shaderCache = NULL; level = NULL; + Core::init(); Sound::callback = stopChannel; - Core::init(); Core::settings.version = SETTINGS_READING; Stream::cacheRead("settings", loadSettings, lvl); } diff --git a/src/level.h b/src/level.h index 97a4fb0..45b783f 100644 --- a/src/level.h +++ b/src/level.h @@ -41,11 +41,8 @@ struct Level : IGame { AmbientCache *ambientCache; WaterCache *waterCache; - Sound::Sample *sndSoundtrack; - Sound::Sample *sndUnderwater; - Sound::Sample *sndCurrent; - bool waitSoundtrack; - bool playNextTrack; + Sound::Sample *sndTrack, *sndWater; + bool waitTrack; bool lastTitle; bool isEnded; @@ -62,7 +59,7 @@ struct Level : IGame { virtual void loadLevel(TR::LevelID id) { if (isEnded) return; - sndCurrent = sndUnderwater = sndSoundtrack = NULL; + sndWater = sndTrack = NULL; Sound::stopAll(); isEnded = true; @@ -190,7 +187,7 @@ struct Level : IGame { uint8 track = level.state.flags.track; level.state.flags.track = 0; - playTrack(track, true); + playTrack(track); } delete[] data; @@ -572,54 +569,64 @@ struct Level : IGame { } void stopChannel(Sound::Sample *channel) { - if (channel == sndSoundtrack) { - if (sndCurrent == sndSoundtrack) - sndCurrent = NULL; - sndSoundtrack = NULL; - playNextTrack = true; + if (channel == sndTrack) { + sndTrack = NULL; + if (level.state.flags.track == TR::LEVEL_INFO[level.id].ambientTrack) // play ambient track + playTrack(0); } } + struct TrackRequest { + Level *level; + int flags; + + TrackRequest(Level *level, int flags) : level(level), flags(flags) {} + }; + static void playAsync(Stream *stream, void *userData) { - Level *level = (Level*)userData; - level->waitSoundtrack = false; - if (!stream) return; - - level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, Sound::MUSIC); - if (level->sndSoundtrack) { - if (level->level.isCutsceneLevel()) { - // level->sndSoundtrack->setVolume(0.0f, 0.0f); - // level->sndCurrent = level->sndSoundtrack; - Core::resetTime(); + TrackRequest *req = (TrackRequest*)userData; + Level *level = req->level; + level->waitTrack = false; + if (stream) { + level->sndTrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, req->flags); + if (level->sndTrack) { + if (level->level.isCutsceneLevel()) { + Core::resetTime(); + } + level->sndTrack->volume = level->sndTrack->volumeTarget = 0.0f; } - level->sndSoundtrack->setVolume(1.0f, 0.2f); } + + delete req; } - virtual void playTrack(uint8 track, bool restart = false) { + virtual void playTrack(uint8 track) { if (track == 0) track = TR::LEVEL_INFO[level.id].ambientTrack; if (level.state.flags.track == track) { - if (restart && sndSoundtrack) { - sndSoundtrack->replay(); - sndSoundtrack->setVolume(1.0f, 0.2f); + if (sndTrack) { + sndTrack->replay(); + sndTrack->setVolume(1.0f, 0.2f); } return; } + level.state.flags.track = track; - if (sndSoundtrack) { - sndSoundtrack->setVolume(-1.0f, 0.2f); - if (sndCurrent == sndSoundtrack) - sndCurrent = NULL; - sndSoundtrack = NULL; + if (sndTrack) { + sndTrack->setVolume(-1.0f, 0.2f); + sndTrack = NULL; } if (track == 0xFF) return; - waitSoundtrack = true; - getGameTrack(level.version, track, playAsync, this); + int flags = Sound::MUSIC; + if (track == TR::LEVEL_INFO[level.id].ambientTrack) + flags |= Sound::LOOP; + + waitTrack = true; + getGameTrack(level.version, track, playAsync, new TrackRequest(this, flags)); } virtual void stopTrack() { @@ -627,7 +634,7 @@ struct Level : IGame { } //============================== - Level(Stream &stream) : level(stream), inventory(this), isEnded(false), cutsceneWaitTimer(0.0f), animTexTimer(0.0f) { + Level(Stream &stream) : level(stream), inventory(this), waitTrack(false), isEnded(false), cutsceneWaitTimer(0.0f), animTexTimer(0.0f) { #ifdef _PSP Core::freeEDRAM(); #endif @@ -657,7 +664,6 @@ struct Level : IGame { player = players[0]; camera = player->camera; - zoneCache = new ZoneCache(this); ambientCache = Core::settings.detail.lighting > Core::Settings::MEDIUM ? new AmbientCache(this) : NULL; waterCache = Core::settings.detail.water > Core::Settings::LOW ? new WaterCache(this) : NULL; @@ -665,11 +671,6 @@ struct Level : IGame { initReflections(); - // init sounds - //sndSoundtrack = Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), vec3(0.0f), 1, 1, Sound::Flags::LOOP); - - sndUnderwater = NULL; - for (int i = 0; i < level.soundSourcesCount; i++) { TR::SoundSource &src = level.soundSources[i]; int flags = Sound::PAN; @@ -685,9 +686,6 @@ struct Level : IGame { waterCache = NULL; zoneCache = NULL; shadow = NULL; - sndSoundtrack = NULL; - sndUnderwater = NULL; - sndCurrent = NULL; lastTitle = true; inventory.toggle(0, Inventory::PAGE_OPTION); } @@ -695,9 +693,9 @@ struct Level : IGame { effect = TR::Effect::NONE; cube360 = NULL; - sndSoundtrack = NULL; - playNextTrack = true; - sndCurrent = sndSoundtrack; + sndWater = sndTrack = NULL; + + playTrack(0); /* if (level.id == TR::LVL_TR2_RIG) { lara->animation.setAnim(level.models[level.extra.laraSpec].animation); @@ -1436,13 +1434,8 @@ struct Level : IGame { } void update() { - if (playNextTrack) { - playTrack(0); - playNextTrack = false; - } - - if (level.isCutsceneLevel() && waitSoundtrack) { - if (!sndSoundtrack && TR::LEVEL_INFO[level.id].ambientTrack != TR::NO_TRACK) { + if (level.isCutsceneLevel() && waitTrack) { + if (!sndTrack && TR::LEVEL_INFO[level.id].ambientTrack != TR::NO_TRACK) { if (camera->timer > 0.0f) // for the case that audio stops before animation ends loadNextLevel(); return; @@ -1452,8 +1445,8 @@ struct Level : IGame { cutsceneWaitTimer -= Core::deltaTime; if (cutsceneWaitTimer > 0.0f) return; - if (sndSoundtrack) - sndSoundtrack->setVolume(1.0f, 0.0f); + if (sndTrack) + sndTrack->setVolume(1.0f, 0.0f); cutsceneWaitTimer = 0.0f; Core::resetTime(); LOG("reset timer - %d\n", Core::getTime()); @@ -1475,8 +1468,6 @@ struct Level : IGame { inventory.toggle(playerIndex); } - Sound::Sample *sndChanged = sndCurrent; - inventory.update(); if (inventory.titleTimer > 1.0f) @@ -1484,10 +1475,11 @@ struct Level : IGame { UI::update(); + float volWater, volTrack; + if (inventory.isActive() || level.isTitle()) { Sound::reverb.setRoomSize(vec3(1.0f)); - if (!level.isTitle()) - sndChanged = NULL; + volWater = volTrack = 0.0f; } else { params->time += Core::deltaTime; animTexTimer += Core::deltaTime; @@ -1511,22 +1503,24 @@ struct Level : IGame { Controller::clearInactive(); + // underwater ambient sound volume control if (camera->isUnderwater()) { - if (!sndUnderwater) { - sndUnderwater = playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC); - if (sndUnderwater) - sndUnderwater->volume = sndUnderwater->volumeTarget = 0.0f; + if (!sndWater) { + sndWater = playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC); + if (sndWater) + sndWater->volume = sndWater->volumeTarget = 0.0f; } - sndChanged = sndUnderwater; - } else - sndChanged = sndSoundtrack; + volWater = 1.0f; + } else + volWater = 0.0f; + + volTrack = 1.0f; } - if (sndChanged != sndCurrent) { - if (sndCurrent) sndCurrent->setVolume(0.0f, 0.2f); - if (sndChanged) sndChanged->setVolume(1.0f, 0.2f); - sndCurrent = sndChanged; - } + if (sndWater && sndWater->volumeTarget != volWater) + sndWater->setVolume(volWater, 0.2f); + if (sndTrack && sndTrack->volumeTarget != volTrack) + sndTrack->setVolume(volTrack, 0.2f); } void updateEffect() {