diff --git a/CMakeLists.txt b/CMakeLists.txt index 78307ec3de..7380c4104b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,9 +72,9 @@ set(OPENSFX_VERSION "1.0.3") set(OPENSFX_URL "https://github.com/OpenRCT2/OpenSoundEffects/releases/download/v${OPENSFX_VERSION}/opensound.zip") set(OPENSFX_SHA1 "ffec5a97bd5035860c4c9a43fe32cf51886478e3") -set(OPENMSX_VERSION "1.3.0") +set(OPENMSX_VERSION "1.3.1") set(OPENMSX_URL "https://github.com/OpenRCT2/OpenMusic/releases/download/v${OPENMSX_VERSION}/openmusic.zip") -set(OPENMSX_SHA1 "b0cec998a3679f1cde17d91f2508ec4923c1a25c") +set(OPENMSX_SHA1 "cb7b05af97aaf7949fb509063d45df6613f20521") set(REPLAYS_VERSION "0.0.78") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") diff --git a/contributors.md b/contributors.md index 4d79b03284..9df1200171 100644 --- a/contributors.md +++ b/contributors.md @@ -277,6 +277,13 @@ The following people are not part of the development team, but have been contrib ## Music * Karst "Jalmaan" van Galen Last (AuraSpecs) * (Flyxxpy) +* Jan Büchner (Greyfade) +* Allister Brimble +* Herman Riddering + +## Sound Effects +* Karst van Galen Last (AuraSpecs) +* (ThatGuyYouKnow) ## RollerCoaster Tycoon 2 credits Design and programming by Chris Sawyer diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 8f0fa47df9..43b81094af 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3691,6 +3691,10 @@ STR_6583 :{WINDOW_COLOUR_2}Reversed Trains STR_6584 :Select to run trains backwards STR_6585 :Can’t make changes… +STR_6586 :OpenRCT2 +STR_6587 :The OpenRCT2 Title Theme is a work of Allister Brimble,{NEWLINE}licenced CC BY-SA 4.0. +STR_6588 :Thanks to Herman Riddering for allowing us to record the 35er Voigt. + ############# # Scenarios # ################ diff --git a/distribution/changelog.txt b/distribution/changelog.txt index c4600d5484..d2c814d257 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.6 (in development) ------------------------------------------------------------------------ +- Feature: [OpenMusic#41] Official Title Theme by Allister Brimble. - Improved: [#20200] Allow audio files to play to up to 44100hz sample rate (from 22050hz). - Change: [#20110] Fix a few RCT1 build height parity discrepancies. - Fix: [#19823] Parkobj, disallow overriding objects of different object types. diff --git a/openrct2.proj b/openrct2.proj index 8d84896507..4a232ac015 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -49,8 +49,8 @@ 02ddf6c685a2da8bac98a57b34be95d63192443d https://github.com/OpenRCT2/OpenSoundEffects/releases/download/v1.0.3/opensound.zip ffec5a97bd5035860c4c9a43fe32cf51886478e3 - https://github.com/OpenRCT2/OpenMusic/releases/download/v1.3.0/openmusic.zip - b0cec998a3679f1cde17d91f2508ec4923c1a25c + https://github.com/OpenRCT2/OpenMusic/releases/download/v1.3.1/openmusic.zip + cb7b05af97aaf7949fb509063d45df6613f20521 https://github.com/OpenRCT2/replays/releases/download/v0.0.78/replays.zip 31C5D07EED8481D5C6D57F9E4FE9443AAEDE7739 diff --git a/src/openrct2-ui/windows/About.cpp b/src/openrct2-ui/windows/About.cpp index 188abd94cf..1230ea7c35 100644 --- a/src/openrct2-ui/windows/About.cpp +++ b/src/openrct2-ui/windows/About.cpp @@ -74,10 +74,12 @@ static Widget _windowAboutOpenRCT2Widgets[] = { MakeWidget({168, 115 + 40}, {200, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_CHANGELOG_ELLIPSIS), // changelog button MakeWidget({168, 115 + 60}, {200, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_JOIN_DISCORD ), // "join discord" button MakeWidget({10, 250}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_OPENRCT2_DESCRIPTION_2), // More info - MakeWidget({10, 300}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_OPENRCT2_DESCRIPTION_3), // Copyright - MakeWidget({10, 350}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_SPECIAL_THANKS_1), // Special Thanks + MakeWidget({10, 280}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_OPENRCT2_DESCRIPTION_3), // Copyright + MakeWidget({10, 360}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_SPECIAL_THANKS_1), // Special Thanks MakeWidget({10, 375}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_SPECIAL_THANKS_2), // Company names MakeWidget({168, 115 + 80}, {200, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_CONTRIBUTORS_WINDOW_BUTTON), // "contributors" button + MakeWidget({10, 310}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_OPENRCT2_TITLE), // Title Theme + MakeWidget({10, 338}, {WW - 20, 50}, WindowWidgetType::LabelCentred, WindowColour::Secondary, STR_ABOUT_FAIRGROUND_ORGAN), // Fairground organ WIDGETS_END, }; diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index a45c659922..2c395aa061 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -1349,32 +1349,22 @@ private: break; case WIDX_TITLE_MUSIC_DROPDOWN: { - if (!IsRCT1TitleMusicAvailable()) + const bool rct1MusicThemeIsAvailable = IsRCT1TitleMusicAvailable(); + int32_t numItems{}; + int32_t checkedIndex{}; + for (auto theme : TitleThemeOptions) { - // Only show None and RCT2 - int32_t numItems{}; + if (theme.Kind == TitleMusicKind::RCT1 && !rct1MusicThemeIsAvailable) + continue; + + if (gConfigSound.TitleMusic == theme.Kind) + checkedIndex = numItems; + gDropdownItems[numItems].Format = STR_DROPDOWN_MENU_LABEL; - gDropdownItems[numItems++].Args = TitleMusicNames[0]; - gDropdownItems[numItems].Format = STR_DROPDOWN_MENU_LABEL; - gDropdownItems[numItems++].Args = TitleMusicNames[2]; - ShowDropdown(widget, numItems); - if (gConfigSound.TitleMusic == TitleMusicKind::None) - Dropdown::SetChecked(0, true); - else if (gConfigSound.TitleMusic == TitleMusicKind::RCT2) - Dropdown::SetChecked(1, true); - } - else - { - // Show None, RCT1, RCT2 and random - int32_t numItems{}; - for (auto musicName : TitleMusicNames) - { - gDropdownItems[numItems].Format = STR_DROPDOWN_MENU_LABEL; - gDropdownItems[numItems++].Args = musicName; - } - ShowDropdown(widget, numItems); - Dropdown::SetChecked(EnumValue(gConfigSound.TitleMusic), true); + gDropdownItems[numItems++].Args = theme.Name; } + ShowDropdown(widget, numItems); + Dropdown::SetChecked(checkedIndex, true); break; } } @@ -1407,18 +1397,20 @@ private: break; case WIDX_TITLE_MUSIC_DROPDOWN: { - auto titleMusic = static_cast(dropdownIndex); - if (!IsRCT1TitleMusicAvailable() && dropdownIndex != 0) + // HACK: When RCT1 is not available, it's not in the dropdown, so indices higher than it should be incremented + const bool rct1MusicThemeIsAvailable = IsRCT1TitleMusicAvailable(); + for (size_t i = 0; i < std::size(TitleThemeOptions) && static_cast(i) <= dropdownIndex; i++) { - titleMusic = TitleMusicKind::RCT2; + if (TitleThemeOptions[i].Kind == TitleMusicKind::RCT1 && !rct1MusicThemeIsAvailable) + dropdownIndex++; } - gConfigSound.TitleMusic = titleMusic; + gConfigSound.TitleMusic = TitleThemeOptions[dropdownIndex].Kind; ConfigSaveDefault(); Invalidate(); OpenRCT2::Audio::StopTitleMusic(); - if (titleMusic != TitleMusicKind::None) + if (gConfigSound.TitleMusic != TitleMusicKind::None) { OpenRCT2::Audio::PlayTitleMusic(); } @@ -1465,14 +1457,14 @@ private: return { 500, 0 }; } - StringId GetTitleMusicName() + StringId GetTitleMusicName() const { - auto index = EnumValue(gConfigSound.TitleMusic); - if (index < 0 || static_cast(index) >= std::size(TitleMusicNames)) - { - index = EnumValue(TitleMusicKind::None); - } - return TitleMusicNames[index]; + auto theme = std::find_if(std::begin(TitleThemeOptions), std::end(TitleThemeOptions), [](auto&& option) { + return gConfigSound.TitleMusic == option.Kind; + }); + if (theme != std::end(TitleThemeOptions)) + return theme->Name; + return STR_OPENRCT2_DROPDOWN; } void AudioPrepareDraw() @@ -2146,11 +2138,16 @@ private: STR_SAVE_EVERY_30MINUTES, STR_SAVE_EVERY_HOUR, STR_SAVE_NEVER, }; - static constexpr StringId TitleMusicNames[] = { - STR_OPTIONS_MUSIC_VALUE_NONE, - STR_ROLLERCOASTER_TYCOON_1_DROPDOWN, - STR_ROLLERCOASTER_TYCOON_2_DROPDOWN, - STR_OPTIONS_MUSIC_VALUE_RANDOM, + static constexpr struct + { + TitleMusicKind Kind; + StringId Name; + } TitleThemeOptions[] = { + { TitleMusicKind::None, STR_OPTIONS_MUSIC_VALUE_NONE }, + { TitleMusicKind::OpenRCT2, STR_OPENRCT2_DROPDOWN }, + { TitleMusicKind::RCT1, STR_ROLLERCOASTER_TYCOON_1_DROPDOWN }, + { TitleMusicKind::RCT2, STR_ROLLERCOASTER_TYCOON_2_DROPDOWN }, + { TitleMusicKind::Random, STR_OPTIONS_MUSIC_VALUE_RANDOM }, }; static constexpr StringId FullscreenModeNames[] = { diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index e9ef18924c..9ff0e79b76 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -271,19 +271,32 @@ namespace OpenRCT2::Audio static ObjectEntryDescriptor GetTitleMusicDescriptor() { + static constexpr std::array selectableAudioIds{ + AudioObjectIdentifiers::OpenRCT2Title, + AudioObjectIdentifiers::RCT1Title, + AudioObjectIdentifiers::RCT2Title, + }; + int32_t IdIndex{}; switch (gConfigSound.TitleMusic) { default: - return {}; + case TitleMusicKind::OpenRCT2: + IdIndex = 0; + break; case TitleMusicKind::RCT1: - return ObjectEntryDescriptor(ObjectType::Audio, AudioObjectIdentifiers::RCT1Title); + IdIndex = 1; + break; case TitleMusicKind::RCT2: - return ObjectEntryDescriptor(ObjectType::Audio, AudioObjectIdentifiers::RCT2Title); + IdIndex = 2; + break; case TitleMusicKind::Random: - return ObjectEntryDescriptor( - ObjectType::Audio, - (UtilRand() & 1) ? AudioObjectIdentifiers::RCT1Title : AudioObjectIdentifiers::RCT2Title); + IdIndex = UtilRand() % std::size(selectableAudioIds); + break; + case TitleMusicKind::None: + return {}; } + + return ObjectEntryDescriptor(ObjectType::Audio, selectableAudioIds[IdIndex]); } void PlayTitleMusic() diff --git a/src/openrct2/audio/audio.h b/src/openrct2/audio/audio.h index 34849ad5f2..583d6019ff 100644 --- a/src/openrct2/audio/audio.h +++ b/src/openrct2/audio/audio.h @@ -142,6 +142,7 @@ namespace OpenRCT2::Audio constexpr std::string_view RCT2Base = "rct2.audio.base"; constexpr std::string_view RCTCBase = "rct2.audio.base.rctc"; constexpr std::string_view RCT2Title = "rct2.audio.title"; + constexpr std::string_view OpenRCT2Title = "openrct2.audio.title"; constexpr std::string_view RCT2Circus = "rct2.audio.circus"; constexpr std::string_view OpenRCT2Additional = "openrct2.audio.additional"; } // namespace AudioObjectIdentifiers diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index d6caff1787..1e75cff005 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -362,7 +362,8 @@ namespace Config model->Device = reader->GetString("audio_device", ""); model->MasterSoundEnabled = reader->GetBoolean("master_sound", true); model->MasterVolume = reader->GetInt32("master_volume", 100); - model->TitleMusic = static_cast(reader->GetInt32("title_music", EnumValue(TitleMusicKind::RCT2))); + model->TitleMusic = static_cast( + reader->GetInt32("title_theme", EnumValue(TitleMusicKind::OpenRCT2))); model->SoundEnabled = reader->GetBoolean("sound", true); model->SoundVolume = reader->GetInt32("sound_volume", 100); model->RideMusicEnabled = reader->GetBoolean("ride_music", true); @@ -378,7 +379,7 @@ namespace Config writer->WriteString("audio_device", model->Device); writer->WriteBoolean("master_sound", model->MasterSoundEnabled); writer->WriteInt32("master_volume", model->MasterVolume); - writer->WriteInt32("title_music", EnumValue(model->TitleMusic)); + writer->WriteInt32("title_theme", EnumValue(model->TitleMusic)); writer->WriteBoolean("sound", model->SoundEnabled); writer->WriteInt32("sound_volume", model->SoundVolume); writer->WriteBoolean("ride_music", model->RideMusicEnabled); diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 9992cf0f49..5dd801bfba 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -251,9 +251,10 @@ enum class MeasurementFormat : int32_t enum class TitleMusicKind : int32_t { None, + Random, + OpenRCT2, RCT1, RCT2, - Random }; extern GeneralConfiguration gConfigGeneral; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 5ae21eff8b..36054623c9 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3990,6 +3990,10 @@ enum : uint16_t STR_OPTION_REVERSE_TRAINS_TIP = 6584, STR_RIDE_SET_VEHICLE_REVERSED_FAIL = 6585, + STR_OPENRCT2_DROPDOWN = 6586, + STR_ABOUT_OPENRCT2_TITLE = 6587, + STR_ABOUT_FAIRGROUND_ORGAN = 6588, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings };