diff --git a/src/openrct2/ride/RideAudio.cpp b/src/openrct2/ride/RideAudio.cpp index 2b3d885428..7df021f764 100644 --- a/src/openrct2/ride/RideAudio.cpp +++ b/src/openrct2/ride/RideAudio.cpp @@ -20,6 +20,7 @@ #include "../object/MusicObject.h" #include "../object/ObjectManager.h" #include "Ride.h" +#include "RideData.h" #include #include @@ -31,21 +32,6 @@ namespace OpenRCT2::RideAudio { constexpr size_t MAX_RIDE_MUSIC_CHANNELS = 32; - /** - * Represents a particular instance of ride music that can be heard in a viewport. - * These are created each frame via enumerating each ride / viewport. - */ - struct ViewportRideMusicInstance - { - ::RideId RideId; - uint8_t TrackIndex{}; - - size_t Offset{}; - int16_t Volume{}; - int16_t Pan{}; - uint16_t Frequency{}; - }; - /** * Represents an audio channel to play a particular ride's music track. */ @@ -186,56 +172,60 @@ namespace OpenRCT2::RideAudio _musicInstances.clear(); } - static void StartRideMusicChannel(const ViewportRideMusicInstance& instance) + void DefaultStartRideMusicChannel(const ViewportRideMusicInstance& instance) { auto& objManager = GetContext()->GetObjectManager(); - - // Create new music channel auto ride = get_ride(instance.RideId); - if (ride->type == RIDE_TYPE_CIRCUS) + auto musicObj = static_cast(objManager.GetLoadedObject(ObjectType::Music, ride->music)); + if (musicObj != nullptr) { - ObjectEntryDescriptor desc(ObjectType::Audio, AudioObjectIdentifiers::Rct2Circus); - auto audioObj = static_cast(objManager.GetLoadedObject(desc)); - if (audioObj != nullptr) + auto track = musicObj->GetTrack(instance.TrackIndex); + if (track != nullptr) { - auto source = audioObj->GetSample(0); - if (source != nullptr) + auto stream = track->Asset.GetStream(); + if (stream != nullptr) { - auto channel = CreateAudioChannel(source, MixerGroup::Sound, false, 0); - if (channel != nullptr) + auto audioContext = GetContext()->GetAudioContext(); + auto source = audioContext->CreateStreamFromWAV(std::move(stream)); + if (source != nullptr) { - _musicChannels.emplace_back(instance, channel, nullptr); - } - } - } - } - else - { - auto musicObj = static_cast(objManager.GetLoadedObject(ObjectType::Music, ride->music)); - if (musicObj != nullptr) - { - auto track = musicObj->GetTrack(instance.TrackIndex); - if (track != nullptr) - { - auto stream = track->Asset.GetStream(); - if (stream != nullptr) - { - auto audioContext = GetContext()->GetAudioContext(); - auto source = audioContext->CreateStreamFromWAV(std::move(stream)); - if (source != nullptr) + auto shouldLoop = musicObj->GetTrackCount() == 1; + auto channel = CreateAudioChannel(source, MixerGroup::RideMusic, shouldLoop, 0); + if (channel != nullptr) { - auto shouldLoop = musicObj->GetTrackCount() == 1; - auto channel = CreateAudioChannel(source, MixerGroup::RideMusic, shouldLoop, 0); - if (channel != nullptr) - { - _musicChannels.emplace_back(instance, channel, source); - } + _musicChannels.emplace_back(instance, channel, source); } } } } } } + void CircusStartRideMusicChannel(const ViewportRideMusicInstance& instance) + { + auto& objManager = GetContext()->GetObjectManager(); + ObjectEntryDescriptor desc(ObjectType::Audio, AudioObjectIdentifiers::Rct2Circus); + auto audioObj = static_cast(objManager.GetLoadedObject(desc)); + if (audioObj != nullptr) + { + auto source = audioObj->GetSample(0); + if (source != nullptr) + { + auto channel = CreateAudioChannel(source, MixerGroup::Sound, false, 0); + if (channel != nullptr) + { + _musicChannels.emplace_back(instance, channel, nullptr); + } + } + } + } + + static void StartRideMusicChannel(const ViewportRideMusicInstance& instance) + { + // Create new music channel + auto ride = get_ride(instance.RideId); + const auto& rtd = ride->GetRideTypeDescriptor(); + rtd.StartRideMusic(instance); + } static void StopInactiveRideMusicChannels() { diff --git a/src/openrct2/ride/RideAudio.h b/src/openrct2/ride/RideAudio.h index c91de90e9c..aee993fe0d 100644 --- a/src/openrct2/ride/RideAudio.h +++ b/src/openrct2/ride/RideAudio.h @@ -9,6 +9,8 @@ #pragma once +#include "../Identifiers.h" + #include struct CoordsXYZ; @@ -16,8 +18,26 @@ struct Ride; namespace OpenRCT2::RideAudio { + /** + * Represents a particular instance of ride music that can be heard in a viewport. + * These are created each frame via enumerating each ride / viewport. + */ + struct ViewportRideMusicInstance + { + ::RideId RideId; + uint8_t TrackIndex{}; + + size_t Offset{}; + int16_t Volume{}; + int16_t Pan{}; + uint16_t Frequency{}; + }; + void ClearAllViewportInstances(); void StopAllChannels(); void UpdateMusicChannels(); void UpdateMusicInstance(Ride& ride, const CoordsXYZ& rideCoords, uint16_t sampleRate); + + void DefaultStartRideMusicChannel(const ViewportRideMusicInstance& instance); + void CircusStartRideMusicChannel(const ViewportRideMusicInstance& instance); } // namespace OpenRCT2::RideAudio diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index ce6e8ed677..4a93ddec66 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -27,6 +27,7 @@ #include "../sprites.h" #include "../util/Util.h" #include "Ride.h" +#include "RideAudio.h" #include "RideEntry.h" #include "ShopItem.h" #include "Track.h" @@ -153,6 +154,7 @@ struct UpkeepCostsDescriptor using RideTrackGroup = OpenRCT2::BitSet; using RideMusicUpdateFunction = void (*)(Ride*); using PeepUpdateRideLeaveEntranceFunc = void (*)(Guest*, Ride*, CoordsXYZD&); +using StartRideMusicFunction = void (*)(const OpenRCT2::RideAudio::ViewportRideMusicInstance&); struct RideTypeDescriptor { uint8_t AlternateType; @@ -200,6 +202,7 @@ struct RideTypeDescriptor // json name lookup std::string_view Name; + StartRideMusicFunction StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel; TrackDesignCreateMode DesignCreateMode = TrackDesignCreateMode::Default; @@ -399,6 +402,7 @@ constexpr const RideTypeDescriptor DummyRTD = SET_FIELD(ColourPreview, { static_cast(SPR_NONE), static_cast(SPR_NONE) }), SET_FIELD(ColourKey, RideColourKey::Ride), SET_FIELD(Name, "invalid"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::Ride), diff --git a/src/openrct2/ride/coaster/meta/HybridCoaster.h b/src/openrct2/ride/coaster/meta/HybridCoaster.h index e37f6b73ec..87b3d177a9 100644 --- a/src/openrct2/ride/coaster/meta/HybridCoaster.h +++ b/src/openrct2/ride/coaster/meta/HybridCoaster.h @@ -51,5 +51,6 @@ constexpr const RideTypeDescriptor HybridCoasterRTD = SET_FIELD(ColourPreview, { SPR_RIDE_DESIGN_PREVIEW_HYBRID_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_HYBRID_COASTER_SUPPORTS }), SET_FIELD(ColourKey, RideColourKey::Ride), SET_FIELD(Name, "hybrid_rc"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), }; // clang-format on diff --git a/src/openrct2/ride/gentle/meta/Circus.h b/src/openrct2/ride/gentle/meta/Circus.h index 281d1ebe8e..63d26e440b 100644 --- a/src/openrct2/ride/gentle/meta/Circus.h +++ b/src/openrct2/ride/gentle/meta/Circus.h @@ -50,6 +50,7 @@ constexpr const RideTypeDescriptor CircusRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Ride), SET_FIELD(Name, "circus"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::CircusStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, CircusMusicUpdate), }; diff --git a/src/openrct2/ride/gentle/meta/Maze.h b/src/openrct2/ride/gentle/meta/Maze.h index f56fb2edf8..cace50e220 100644 --- a/src/openrct2/ride/gentle/meta/Maze.h +++ b/src/openrct2/ride/gentle/meta/Maze.h @@ -10,6 +10,7 @@ #pragma once #include "../../../sprites.h" +#include "../../RideAudio.h" #include "../../RideData.h" #include "../../ShopItem.h" #include "../../Track.h" @@ -51,6 +52,7 @@ constexpr const RideTypeDescriptor MazeRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Ride), SET_FIELD(Name, "maze"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Maze), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::Ride), diff --git a/src/openrct2/ride/gentle/meta/SpiralSlide.h b/src/openrct2/ride/gentle/meta/SpiralSlide.h index bdf8839ff8..462323ba42 100644 --- a/src/openrct2/ride/gentle/meta/SpiralSlide.h +++ b/src/openrct2/ride/gentle/meta/SpiralSlide.h @@ -53,6 +53,7 @@ constexpr const RideTypeDescriptor SpiralSlideRTD = SET_FIELD(ColourPreview, { SPR_RIDE_DESIGN_PREVIEW_SPIRAL_SLIDE_TRACK, 0 }), SET_FIELD(ColourKey, RideColourKey::Ride), SET_FIELD(Name, "spiral_slide"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::Ride), diff --git a/src/openrct2/ride/shops/meta/CashMachine.h b/src/openrct2/ride/shops/meta/CashMachine.h index a5ad8f9480..bca2ecc019 100644 --- a/src/openrct2/ride/shops/meta/CashMachine.h +++ b/src/openrct2/ride/shops/meta/CashMachine.h @@ -47,6 +47,7 @@ constexpr const RideTypeDescriptor CashMachineRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::CashMachine), SET_FIELD(Name, "cash_machine"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::KioskOrFacility), diff --git a/src/openrct2/ride/shops/meta/DrinkStall.h b/src/openrct2/ride/shops/meta/DrinkStall.h index 1d83365f24..70d062da44 100644 --- a/src/openrct2/ride/shops/meta/DrinkStall.h +++ b/src/openrct2/ride/shops/meta/DrinkStall.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor DrinkStallRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Drink), SET_FIELD(Name, "drink_stall"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::ShopOrStall), diff --git a/src/openrct2/ride/shops/meta/FirstAid.h b/src/openrct2/ride/shops/meta/FirstAid.h index 60a9c87c6a..52f2f3efaa 100644 --- a/src/openrct2/ride/shops/meta/FirstAid.h +++ b/src/openrct2/ride/shops/meta/FirstAid.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor FirstAidRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::FirstAid), SET_FIELD(Name, "first_aid"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::KioskOrFacility), diff --git a/src/openrct2/ride/shops/meta/FoodStall.h b/src/openrct2/ride/shops/meta/FoodStall.h index 152c5be14d..cc8ee3b067 100644 --- a/src/openrct2/ride/shops/meta/FoodStall.h +++ b/src/openrct2/ride/shops/meta/FoodStall.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor FoodStallRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Food), SET_FIELD(Name, "food_stall"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::ShopOrStall), diff --git a/src/openrct2/ride/shops/meta/InformationKiosk.h b/src/openrct2/ride/shops/meta/InformationKiosk.h index 5a08cd7693..693455ace1 100644 --- a/src/openrct2/ride/shops/meta/InformationKiosk.h +++ b/src/openrct2/ride/shops/meta/InformationKiosk.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor InformationKioskRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::InfoKiosk), SET_FIELD(Name, "information_kiosk"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::KioskOrFacility), diff --git a/src/openrct2/ride/shops/meta/Shop.h b/src/openrct2/ride/shops/meta/Shop.h index cf44a3ab0a..c709e59cda 100644 --- a/src/openrct2/ride/shops/meta/Shop.h +++ b/src/openrct2/ride/shops/meta/Shop.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor ShopRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Shop), SET_FIELD(Name, "shop"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::ShopOrStall), diff --git a/src/openrct2/ride/shops/meta/Toilets.h b/src/openrct2/ride/shops/meta/Toilets.h index f219638794..6399e3f9fd 100644 --- a/src/openrct2/ride/shops/meta/Toilets.h +++ b/src/openrct2/ride/shops/meta/Toilets.h @@ -48,6 +48,7 @@ constexpr const RideTypeDescriptor ToiletsRTD = SET_FIELD(ColourPreview, { 0, 0 }), SET_FIELD(ColourKey, RideColourKey::Toilets), SET_FIELD(Name, "toilets"), + SET_FIELD(StartRideMusic, OpenRCT2::RideAudio::DefaultStartRideMusicChannel), SET_FIELD(DesignCreateMode, TrackDesignCreateMode::Default), SET_FIELD(MusicUpdateFunction, DefaultMusicUpdate), SET_FIELD(Classification, RideClassification::KioskOrFacility),