diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index 446c9cc253..63430a8305 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -50,6 +50,7 @@ namespace OpenRCT2::Audio static std::vector _audioDevices; static int32_t _currentAudioDevice = -1; static ObjectEntryIndex _soundsAudioObjectEntryIndex = OBJECT_ENTRY_INDEX_NULL; + static ObjectEntryIndex _soundsAdditionalAudioObjectEntryIndex = OBJECT_ENTRY_INDEX_NULL; static ObjectEntryIndex _titleAudioObjectEntryIndex = OBJECT_ENTRY_INDEX_NULL; bool gGameSoundsOff = false; @@ -123,6 +124,9 @@ namespace OpenRCT2::Audio } } + objManager.LoadObject(AudioObjectIdentifiers::OpenRCT2Additional); + _soundsAdditionalAudioObjectEntryIndex = objManager.GetLoadedObjectEntryIndex( + AudioObjectIdentifiers::OpenRCT2Additional); objManager.LoadObject(AudioObjectIdentifiers::Rct2Circus); } @@ -195,12 +199,23 @@ namespace OpenRCT2::Audio return params; } - AudioObject* GetBaseAudioObject() + static std::tuple GetAudioObjectAndSampleIndex(SoundId id) { auto& objManager = GetContext()->GetObjectManager(); - auto* baseAudioObject = static_cast( - objManager.GetLoadedObject(ObjectType::Audio, _soundsAudioObjectEntryIndex)); - return baseAudioObject; + AudioObject* audioObject{}; + uint32_t sampleIndex = EnumValue(id); + if (id >= SoundId::LiftRMC) + { + audioObject = static_cast( + objManager.GetLoadedObject(ObjectType::Audio, _soundsAdditionalAudioObjectEntryIndex)); + sampleIndex -= EnumValue(SoundId::LiftRMC); + } + else + { + audioObject = static_cast( + objManager.GetLoadedObject(ObjectType::Audio, _soundsAudioObjectEntryIndex)); + } + return std::make_tuple(audioObject, sampleIndex); } static void Play(IAudioSource* audioSource, int32_t volume, int32_t pan) @@ -222,13 +237,13 @@ namespace OpenRCT2::Audio return; // Get sound from base object - auto* baseAudioObject = GetBaseAudioObject(); + auto [baseAudioObject, sampleIndex] = GetAudioObjectAndSampleIndex(soundId); if (baseAudioObject != nullptr) { - auto params = GetParametersFromLocation(baseAudioObject, EnumValue(soundId), loc); + auto params = GetParametersFromLocation(baseAudioObject, sampleIndex, loc); if (params.in_range) { - auto source = baseAudioObject->GetSample(EnumValue(soundId)); + auto source = baseAudioObject->GetSample(sampleIndex); if (source != nullptr) { Play(source, params.volume, params.pan); @@ -243,10 +258,10 @@ namespace OpenRCT2::Audio return; // Get sound from base object - auto* baseAudioObject = GetBaseAudioObject(); + auto [baseAudioObject, sampleIndex] = GetAudioObjectAndSampleIndex(soundId); if (baseAudioObject != nullptr) { - auto source = baseAudioObject->GetSample(EnumValue(soundId)); + auto source = baseAudioObject->GetSample(sampleIndex); if (source != nullptr) { Play(source, volume, pan); @@ -440,10 +455,10 @@ namespace OpenRCT2::Audio SoundId id, bool loop, int32_t volume, float pan, double rate, bool forget) { // Get sound from base object - auto baseAudioObject = GetBaseAudioObject(); + auto [baseAudioObject, sampleIndex] = GetAudioObjectAndSampleIndex(id); if (baseAudioObject != nullptr) { - auto source = baseAudioObject->GetSample(EnumValue(id)); + auto source = baseAudioObject->GetSample(sampleIndex); if (source != nullptr) { return CreateAudioChannel(source, MixerGroup::Sound, loop, volume, pan, rate, forget); diff --git a/src/openrct2/audio/audio.h b/src/openrct2/audio/audio.h index bef7e25e57..fa3e8c527f 100644 --- a/src/openrct2/audio/audio.h +++ b/src/openrct2/audio/audio.h @@ -142,6 +142,7 @@ namespace OpenRCT2::Audio constexpr std::string_view Rct2cBase = "rct2.audio.base.rctc"; constexpr std::string_view Rct2Title = "rct2.audio.title"; constexpr std::string_view Rct2Circus = "rct2.audio.circus"; + constexpr std::string_view OpenRCT2Additional = "openrct2.audio.additional"; } // namespace AudioObjectIdentifiers extern bool gGameSoundsOff; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index f86b989254..b0702538df 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -91,72 +91,6 @@ static constexpr const OpenRCT2::Audio::SoundId _screamSet2[] = { OpenRCT2::Audio::SoundId::Scream6, }; -static constexpr const uint8_t _soundParams[OpenRCT2::Audio::RCT2SoundCount][2] = { - { 1, 0 }, // LiftClassic - { 1, 0 }, // TrackFrictionClassicWood - { 1, 0 }, // FrictionClassic - { 0, 1 }, // Scream1 - { 0, 0 }, // Click1 - { 0, 0 }, // Click2 - { 0, 0 }, // PlaceItem - { 0, 1 }, // Scream2 - { 0, 1 }, // Scream3 - { 0, 1 }, // Scream4 - { 0, 1 }, // Scream5 - { 0, 1 }, // Scream6 - { 1, 0 }, // LiftFrictionWheels - { 0, 0 }, // Purchase - { 0, 0 }, // Crash - { 0, 0 }, // LayingOutWater - { 0, 0 }, // Water1 - { 0, 0 }, // Water2 - { 0, 1 }, // TrainWhistle - { 0, 1 }, // TrainDeparting - { 0, 0 }, // WaterSplash - { 1, 0 }, // GoKartEngine - { 0, 0 }, // RideLaunch1 - { 0, 0 }, // RideLaunch2 - { 0, 0 }, // Cough1 - { 0, 0 }, // Cough2 - { 0, 0 }, // Cough3 - { 0, 0 }, // Cough4 - { 1, 0 }, // Rain - { 0, 0 }, // Thunder1 - { 0, 0 }, // Thunder2 - { 1, 0 }, // TrackFrictionTrain - { 1, 0 }, // TrackFrictionWater - { 0, 0 }, // BalloonPop - { 0, 0 }, // MechanicFix - { 0, 1 }, // Scream7 - { 0, 0 }, // ToiletFlush - { 0, 0 }, // Click3 - { 0, 0 }, // Quack - { 0, 0 }, // NewsItem - { 0, 0 }, // WindowOpen - { 0, 0 }, // Laugh1 - { 0, 0 }, // Laugh2 - { 0, 0 }, // Laugh3 - { 0, 0 }, // Applause - { 0, 0 }, // HauntedHouseScare - { 0, 0 }, // HauntedHouseScream1 - { 0, 0 }, // HauntedHouseScream2 - { 0, 0 }, // BlockBrakeClose - { 0, 0 }, // BlockBrakeRelease - { 0, 0 }, // Error - { 0, 0 }, // BrakeRelease - { 1, 0 }, // LiftArrow - { 1, 0 }, // LiftWood - { 1, 0 }, // TrackFrictionWood - { 1, 0 }, // LiftWildMouse - { 1, 0 }, // LiftBM - { 1, 2 }, // TrackFrictionBM - { 0, 1 }, // Scream8 - { 0, 1 }, // Tram - { 0, 0 }, // DoorOpen - { 0, 0 }, // DoorClose - { 0, 0 }, // Portcullis -}; - // clang-format off static constexpr const uint8_t SpaceRingsTimeToSpriteMap[] = { @@ -1047,6 +981,63 @@ static OpenRCT2::Audio::VehicleSound* vehicle_sounds_update_get_vehicle_sound(Op return nullptr; } +static bool IsLoopingSound(SoundId id) +{ + switch (id) + { + case SoundId::LiftClassic: + case SoundId::TrackFrictionClassicWood: + case SoundId::FrictionClassic: + case SoundId::LiftFrictionWheels: + case SoundId::GoKartEngine: + case SoundId::TrackFrictionTrain: + case SoundId::TrackFrictionWater: + case SoundId::LiftArrow: + case SoundId::LiftWood: + case SoundId::TrackFrictionWood: + case SoundId::LiftWildMouse: + case SoundId::LiftBM: + case SoundId::TrackFrictionBM: + case SoundId::LiftRMC: + case SoundId::TrackFrictionRMC: + return true; + default: + return false; + } +} + +static bool IsFixedFrequencySound(SoundId id) +{ + switch (id) + { + case SoundId::Scream1: + case SoundId::Scream2: + case SoundId::Scream3: + case SoundId::Scream4: + case SoundId::Scream5: + case SoundId::Scream6: + case SoundId::Scream7: + case SoundId::Scream8: + case SoundId::TrainWhistle: + case SoundId::TrainDeparting: + case SoundId::Tram: + return true; + default: + return false; + } +} + +static bool IsSpecialFrequencySound(SoundId id) +{ + switch (id) + { + case SoundId::TrackFrictionBM: + return true; + default: + return false; + } +} + enum class SoundType { TrackNoises, @@ -1057,7 +1048,7 @@ template static uint16_t SoundFrequency(const OpenRCT2::Audio::S { if constexpr (type == SoundType::TrackNoises) { - if (_soundParams[static_cast(id)][1] & 2) + if (IsSpecialFrequencySound(id)) { return (baseFrequency / 2) + 4000; } @@ -1065,7 +1056,7 @@ template static uint16_t SoundFrequency(const OpenRCT2::Audio::S } else { - if (_soundParams[static_cast(id)][1] & 1) + if (IsFixedFrequencySound(id)) { return 22050; } @@ -1075,7 +1066,7 @@ template static uint16_t SoundFrequency(const OpenRCT2::Audio::S template static bool ShouldUpdateChannelRate(const OpenRCT2::Audio::SoundId id) { - return type == SoundType::TrackNoises || !(_soundParams[static_cast(id)][1] & 1); + return type == SoundType::TrackNoises || !IsFixedFrequencySound(id); } template @@ -1105,7 +1096,7 @@ static void UpdateSound( if (sound.Id == OpenRCT2::Audio::SoundId::Null) { auto frequency = SoundFrequency(id, sound_params->frequency); - auto looping = _soundParams[static_cast(id)][0]; + auto looping = IsLoopingSound(id); auto pan = sound_params->pan_x; auto channel = CreateAudioChannel( id, looping, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), false);