From c22c4e2e7cfeb6d15b560ffe4564339e51b59e1e Mon Sep 17 00:00:00 2001 From: XProger Date: Fri, 29 Sep 2017 04:22:49 +0300 Subject: [PATCH] #23 clip sounds by dist (optimization), stop music and screaming after death x_x --- src/controller.h | 8 ++------ src/inventory.h | 28 +++++++++++++--------------- src/lara.h | 27 +++++++++++++++------------ src/level.h | 14 +++++++------- src/sound.h | 14 ++++++++++++++ src/trigger.h | 2 +- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/controller.h b/src/controller.h index 6a41469..88e8b42 100644 --- a/src/controller.h +++ b/src/controller.h @@ -61,7 +61,7 @@ struct IGame { virtual int* invCount(TR::Entity::Type type) { return NULL; } virtual bool invChooseKey(TR::Entity::Type hole) { return false; } - virtual Sound::Sample* playSound(int id, const vec3 &pos, int flags, int group = -1) const { return NULL; } + virtual Sound::Sample* playSound(int id, const vec3 &pos = vec3(0.0f), int flags = 0) const { return NULL; } virtual void playTrack(int track, bool restart = false) {} virtual void stopTrack() {} }; @@ -308,10 +308,6 @@ struct Controller { return pos; } - Sound::Sample* playSound(int id, const vec3 &pos, int flags) const { - return game->playSound(id, pos, flags, entity); - } - vec3 getDir() const { return vec3(angle.x, angle.y); } @@ -525,7 +521,7 @@ struct Controller { default : cmdEffect(fx); break; } } else - playSound(fx, pos, Sound::Flags::PAN); + game->playSound(fx, pos, Sound::Flags::PAN); } break; } diff --git a/src/inventory.h b/src/inventory.h index 515ede1..35f31ab 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -332,7 +332,7 @@ struct Inventory { if (phaseRing == 0.0f || phaseRing == 1.0f) { active = !active; vec3 p; - game->playSound(active ? TR::SND_INV_SHOW : TR::SND_INV_HIDE, p, 0, 0); + game->playSound(active ? TR::SND_INV_SHOW : TR::SND_INV_HIDE, p); chosen = false; if (active) { @@ -418,7 +418,7 @@ struct Inventory { switch (item->type) { case TR::Entity::INV_PASSPORT : { - game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); + game->playSound(TR::SND_INV_PAGE); item->value = 1; passportSlotCount = 2; passportSlots[0] = TR::LEVEL_1; @@ -441,8 +441,8 @@ struct Inventory { if (key == cDown ) { slot = (slot + 1) % passportSlotCount; }; } // passport pages - if (key == cLeft && item->value > 0) { item->value--; item->anim->dir = -1.0f; game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); } - if (key == cRight && item->value < 2) { item->value++; item->anim->dir = 1.0f; game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); } + if (key == cLeft && item->value > 0) { item->value--; item->anim->dir = -1.0f; game->playSound(TR::SND_INV_PAGE); } + if (key == cRight && item->value < 2) { item->value++; item->anim->dir = 1.0f; game->playSound(TR::SND_INV_PAGE); } if (key == cAction && phaseChoose == 1.0f) { TR::LevelID id = game->getLevel()->id; @@ -476,7 +476,7 @@ struct Inventory { case 3 : settings.detail.setWater(q); break; } if (q == settings.detail.quality[slot]) - game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); + game->playSound(TR::SND_INV_PAGE); } } @@ -497,7 +497,7 @@ struct Inventory { v = key == cLeft ? max(0.0f, v - 0.05f) : min(1.0f, v + 0.05f); changeTimer = 0.2f; if (slot == 1) - game->playSound(TR::SND_PISTOLS_SHOT, vec3(), 0, 0); + game->playSound(TR::SND_PISTOLS_SHOT); game->applySettings(Core::settings); } } @@ -574,23 +574,21 @@ struct Inventory { default : ; } - if (index != targetIndex) { - vec3 p; - game->playSound(TR::SND_INV_SPIN, p, 0, 0); - } + if (index != targetIndex) + game->playSound(TR::SND_INV_SPIN); if (lastKey != key && key == cAction && phaseChoose == 0.0f) { vec3 p; chosen = true; switch (item->type) { - case TR::Entity::INV_COMPASS : game->playSound(TR::SND_INV_COMPASS, p, 0, 0); break; - case TR::Entity::INV_HOME : game->playSound(TR::SND_INV_HOME, p, 0, 0); break; - case TR::Entity::INV_CONTROLS : game->playSound(TR::SND_INV_CONTROLS, p, 0, 0); break; + case TR::Entity::INV_COMPASS : game->playSound(TR::SND_INV_COMPASS); break; + case TR::Entity::INV_HOME : game->playSound(TR::SND_INV_HOME); break; + case TR::Entity::INV_CONTROLS : game->playSound(TR::SND_INV_CONTROLS); break; case TR::Entity::INV_PISTOLS : case TR::Entity::INV_SHOTGUN : case TR::Entity::INV_MAGNUMS : - case TR::Entity::INV_UZIS : game->playSound(TR::SND_INV_WEAPON, p, 0, 0); break; - default : game->playSound(TR::SND_INV_SHOW, p, 0, 0); break; + case TR::Entity::INV_UZIS : game->playSound(TR::SND_INV_WEAPON); break; + default : game->playSound(TR::SND_INV_SHOW); break; } item->choose(); } diff --git a/src/lara.h b/src/lara.h index ee14de1..537b77e 100644 --- a/src/lara.h +++ b/src/lara.h @@ -612,8 +612,8 @@ struct Lara : Character { default : ; } - if (wpnState == Weapon::IS_HIDDEN && wState == Weapon::IS_ARMED) playSound(TR::SND_UNHOLSTER, pos, Sound::Flags::PAN); - if (wpnState == Weapon::IS_ARMED && wState == Weapon::IS_HIDDEN) playSound(TR::SND_HOLSTER, pos, Sound::Flags::PAN); + if (wpnState == Weapon::IS_HIDDEN && wState == Weapon::IS_ARMED) game->playSound(TR::SND_UNHOLSTER, pos, Sound::Flags::PAN); + if (wpnState == Weapon::IS_ARMED && wState == Weapon::IS_HIDDEN) game->playSound(TR::SND_HOLSTER, pos, Sound::Flags::PAN); // swap layers // 0 - body (full) @@ -788,7 +788,7 @@ struct Lara : Character { // shotgun reload sound if (wpnCurrent == Weapon::SHOTGUN) { if (anim.frameIndex == 10) - playSound(TR::SND_SHOTGUN_RELOAD, pos, Sound::Flags::PAN); + game->playSound(TR::SND_SHOTGUN_RELOAD, pos, Sound::Flags::PAN); } } } @@ -856,8 +856,8 @@ struct Lara : Character { } if (shots) { - playSound(wpnGetSound(), pos, Sound::Flags::PAN); - playSound(TR::SND_RICOCHET, nearPos, Sound::Flags::PAN); + game->playSound(wpnGetSound(), pos, Sound::Flags::PAN); + game->playSound(TR::SND_RICOCHET, nearPos, Sound::Flags::PAN); if (wpnAmmo && *wpnAmmo != UNLIMITED_AMMO && wpnCurrent == Weapon::SHOTGUN) *wpnAmmo -= 1; @@ -1289,7 +1289,7 @@ struct Lara : Character { void doBubbles() { int count = rand() % 3; if (!count) return; - playSound(TR::SND_BUBBLE, pos, Sound::Flags::PAN); + game->playSound(TR::SND_BUBBLE, pos, Sound::Flags::PAN); vec3 head = animation.getJoints(getMatrix(), 14, true) * vec3(0.0f, 0.0f, 50.0f); for (int i = 0; i < count; i++) { int index = Sprite::add(game, TR::Entity::BUBBLE, getRoomIndex(), int(head.x), int(head.y), int(head.z), Sprite::FRAME_RANDOM, true); @@ -1353,6 +1353,9 @@ struct Lara : Character { if (health > 0.0f) return; + Sound::stop(TR::SND_SCREAM); + game->stopTrack(); + switch (hitType) { case TR::HIT_FALL : { animation.setState(STATE_DEATH); @@ -1406,7 +1409,7 @@ struct Lara : Character { case TR::Entity::INV_MEDIKIT_BIG : damageTime = LARA_DAMAGE_TIME; health = min(LARA_MAX_HEALTH, health + (item == TR::Entity::INV_MEDIKIT_SMALL ? LARA_MAX_HEALTH / 2 : LARA_MAX_HEALTH)); - playSound(TR::SND_HEALTH, pos, Sound::PAN); + game->playSound(TR::SND_HEALTH, pos, Sound::PAN); //TODO: remove medikit item break; case TR::Entity::INV_PUZZLE_1 : @@ -1624,12 +1627,12 @@ struct Lara : Character { if (usedKey == TR::Entity::NONE) { if (isPressed(ACTION) && !game->invChooseKey(entity.type)) - playSound(TR::SND_NO, pos, Sound::PAN); // no compatible items in inventory + game->playSound(TR::SND_NO, pos, Sound::PAN); // no compatible items in inventory return; } if (TR::Entity::convToInv(TR::Entity::getItemForHole(entity.type)) != usedKey) { // check compatibility if user select other - playSound(TR::SND_NO, pos, Sound::PAN); // uncompatible item + game->playSound(TR::SND_NO, pos, Sound::PAN); // uncompatible item return; } @@ -1787,7 +1790,7 @@ struct Lara : Character { case TR::Action::SECRET : if (!level->secrets[cmd.args]) { level->secrets[cmd.args] = true; - if (!playSound(TR::SND_SECRET, pos, 0)) + if (!game->playSound(TR::SND_SECRET, pos)) game->playTrack(TR::TRACK_SECRET); } break; @@ -2434,7 +2437,7 @@ struct Lara : Character { case STAND_AIR : velocity.y += (velocity.y >= 128.0f ? 30.0f : GRAVITY) * Core::deltaTime; if (velocity.y >= 154.0f) - playSound(TR::SND_SCREAM, pos, Sound::PAN); + game->playSound(TR::SND_SCREAM, pos, Sound::PAN); /* if (state == STATE_FALL || state == STATE_FAST_DIVE) { velocity.x *= 0.95 * Core::deltaTime; @@ -2589,7 +2592,7 @@ struct Lara : Character { // get hit dir if (hitDir == -1) { if (health > 0) - playSound(TR::SND_HIT, pos, Sound::PAN); + game->playSound(TR::SND_HIT, pos, Sound::PAN); hitTime = 0.0f; } diff --git a/src/level.h b/src/level.h index 044c85f..570877c 100644 --- a/src/level.h +++ b/src/level.h @@ -270,7 +270,7 @@ struct Level : IGame { return inventory.chooseKey(hole); } - virtual Sound::Sample* playSound(int id, const vec3 &pos, int flags, int group = -1) const { + virtual Sound::Sample* playSound(int id, const vec3 &pos = vec3(0.0f), int flags = 0) const { if (level.version == TR::VER_TR1_PSX && id == TR::SND_SECRET) return NULL; @@ -291,7 +291,7 @@ struct Level : IGame { } if (b.flags.gain) volume = max(0.0f, volume - randf() * 0.25f); //if (b.flags.camera) flags &= ~Sound::PAN; - return Sound::play(level.getSampleStream(index), pos, volume, pitch, flags, group * 1000 + index); + return Sound::play(level.getSampleStream(index), pos, volume, pitch, flags, id); } return NULL; } @@ -327,8 +327,6 @@ struct Level : IGame { } curTrack = track; - if (track == 0) return; - if (sndSoundtrack) { sndSoundtrack->setVolume(-1.0f, 0.2f); if (sndCurrent == sndSoundtrack) @@ -336,6 +334,8 @@ struct Level : IGame { sndSoundtrack = NULL; } + if (track <= 0) return; + char title[32]; sprintf(title, "audio/track_%02d.ogg", track); @@ -343,7 +343,7 @@ struct Level : IGame { } virtual void stopTrack() { - playTrack(0); + playTrack(-1); } //============================== @@ -533,13 +533,13 @@ struct Level : IGame { // init sounds //sndSoundtrack = Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), vec3(0.0f), 1, 1, Sound::Flags::LOOP); - sndUnderwater = lara->playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC); + sndUnderwater = playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC); if (sndUnderwater) sndUnderwater->volume = sndUnderwater->volumeTarget = 0.0f; for (int i = 0; i < level.soundSourcesCount; i++) { TR::SoundSource &src = level.soundSources[i]; - lara->playSound(src.id, vec3(float(src.x), float(src.y), float(src.z)), Sound::PAN | src.flags); + playSound(src.id, vec3(float(src.x), float(src.y), float(src.z)), Sound::PAN | src.flags); } lastTitle = false; diff --git a/src/sound.h b/src/sound.h index 8cd38aa..dfa623d 100644 --- a/src/sound.h +++ b/src/sound.h @@ -704,6 +704,14 @@ namespace Sound { Sample* play(Stream *stream, const vec3 &pos, float volume = 1.0f, float pitch = 0.0f, int flags = 0, int id = - 1) { if (!stream) return NULL; if (volume > 0.001f) { + if (!(flags & (STATIC | MUSIC)) && (flags & PAN)) { + vec3 d = pos - listener.matrix.getPos(); + if (fabsf(d.x) > SND_FADEOFF_DIST || fabsf(d.y) > SND_FADEOFF_DIST || fabsf(d.z) > SND_FADEOFF_DIST) { + delete stream; + return NULL; + } + } + if (flags & (UNIQUE | REPLAY)) for (int i = 0; i < channelsCount; i++) if (channels[i]->id == id) { @@ -725,6 +733,12 @@ namespace Sound { return NULL; } + void stop(int id = -1) { + for (int i = 0; i < channelsCount; i++) + if (id == -1 || channels[i]->id == id) + channels[i]->stop(); + } + void stopAll() { for (int i = 0; i < channelsCount; i++) delete channels[i]; diff --git a/src/trigger.h b/src/trigger.h index 1d78faa..2a79643 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -123,7 +123,7 @@ struct TrapDartgun : Controller { Sprite::add(game, TR::Entity::SMOKE, entity.room, (int)p.x, (int)p.y, (int)p.z); - playSound(TR::SND_DART, pos, Sound::Flags::PAN); + game->playSound(TR::SND_DART, pos, Sound::Flags::PAN); return true; }