mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
Add new audio object for RMC sounds
This commit is contained in:
@@ -50,6 +50,7 @@ namespace OpenRCT2::Audio
|
||||
static std::vector<std::string> _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<AudioObject*, uint32_t> GetAudioObjectAndSampleIndex(SoundId id)
|
||||
{
|
||||
auto& objManager = GetContext()->GetObjectManager();
|
||||
auto* baseAudioObject = static_cast<AudioObject*>(
|
||||
objManager.GetLoadedObject(ObjectType::Audio, _soundsAudioObjectEntryIndex));
|
||||
return baseAudioObject;
|
||||
AudioObject* audioObject{};
|
||||
uint32_t sampleIndex = EnumValue(id);
|
||||
if (id >= SoundId::LiftRMC)
|
||||
{
|
||||
audioObject = static_cast<AudioObject*>(
|
||||
objManager.GetLoadedObject(ObjectType::Audio, _soundsAdditionalAudioObjectEntryIndex));
|
||||
sampleIndex -= EnumValue(SoundId::LiftRMC);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioObject = static_cast<AudioObject*>(
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<SoundType type> static uint16_t SoundFrequency(const OpenRCT2::Audio::S
|
||||
{
|
||||
if constexpr (type == SoundType::TrackNoises)
|
||||
{
|
||||
if (_soundParams[static_cast<uint8_t>(id)][1] & 2)
|
||||
if (IsSpecialFrequencySound(id))
|
||||
{
|
||||
return (baseFrequency / 2) + 4000;
|
||||
}
|
||||
@@ -1065,7 +1056,7 @@ template<SoundType type> static uint16_t SoundFrequency(const OpenRCT2::Audio::S
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_soundParams[static_cast<uint8_t>(id)][1] & 1)
|
||||
if (IsFixedFrequencySound(id))
|
||||
{
|
||||
return 22050;
|
||||
}
|
||||
@@ -1075,7 +1066,7 @@ template<SoundType type> static uint16_t SoundFrequency(const OpenRCT2::Audio::S
|
||||
|
||||
template<SoundType type> static bool ShouldUpdateChannelRate(const OpenRCT2::Audio::SoundId id)
|
||||
{
|
||||
return type == SoundType::TrackNoises || !(_soundParams[static_cast<uint8_t>(id)][1] & 1);
|
||||
return type == SoundType::TrackNoises || !IsFixedFrequencySound(id);
|
||||
}
|
||||
|
||||
template<SoundType type>
|
||||
@@ -1105,7 +1096,7 @@ static void UpdateSound(
|
||||
if (sound.Id == OpenRCT2::Audio::SoundId::Null)
|
||||
{
|
||||
auto frequency = SoundFrequency<type>(id, sound_params->frequency);
|
||||
auto looping = _soundParams[static_cast<uint8_t>(id)][0];
|
||||
auto looping = IsLoopingSound(id);
|
||||
auto pan = sound_params->pan_x;
|
||||
auto channel = CreateAudioChannel(
|
||||
id, looping, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), false);
|
||||
|
||||
Reference in New Issue
Block a user