diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index de4cceddb6..d7a9281982 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -61,6 +61,7 @@ #include "platform/Crash.h" #include "platform/Platform.h" #include "profiling/Profiling.h" +#include "rct2/RCT2.h" #include "ride/TrackData.h" #include "ride/TrackDesignRepository.h" #include "scenario/Scenario.h" diff --git a/src/openrct2/Limits.h b/src/openrct2/Limits.h index e87151ccc6..fac488b501 100644 --- a/src/openrct2/Limits.h +++ b/src/openrct2/Limits.h @@ -21,6 +21,11 @@ namespace OpenRCT2::Limits constexpr uint16_t MaxTrainsPerRide = 255; constexpr uint16_t MaxCarsPerTrain = 255; constexpr const uint16_t MaxVehicleColours = MaxTrainsPerRide; // this should really be MaxTrainsPerRide * MaxCarsPerTrain + // MaxVehicleColours should be set to MaxTrainsPerRide or MaxCarsPerTrain, whichever is higher. + // Sadly, using std::max() will cause compilation failures when using MaxVehicleColours as an array size, + // hence the usage of static asserts. + static_assert(MaxVehicleColours >= MaxTrainsPerRide); + static_assert(MaxVehicleColours >= MaxCarsPerTrain); constexpr uint8_t MaxCircuitsPerRide = 20; constexpr uint8_t MaxAwards = RCT12::Limits::MaxAwards; constexpr uint8_t NumColourSchemes = RCT12::Limits::NumColourSchemes; diff --git a/src/openrct2/actions/TrackDesignAction.cpp b/src/openrct2/actions/TrackDesignAction.cpp index 3282d1193f..4a5fa16c4f 100644 --- a/src/openrct2/actions/TrackDesignAction.cpp +++ b/src/openrct2/actions/TrackDesignAction.cpp @@ -14,7 +14,6 @@ #include "../management/Research.h" #include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" -#include "../rct12/RCT12.h" #include "../ride/RideConstruction.h" #include "../ride/TrackDesign.h" #include "RideCreateAction.h" @@ -249,17 +248,16 @@ GameActions::Result TrackDesignAction::Execute() const ride->entrance_style = gLastEntranceStyle; } - for (int32_t i = 0; i < RCT12::Limits::NumColourSchemes; i++) + for (int32_t i = 0; i < OpenRCT2::Limits::NumColourSchemes; i++) { ride->track_colour[i].main = _td.track_spine_colour[i]; ride->track_colour[i].additional = _td.track_rail_colour[i]; ride->track_colour[i].supports = _td.track_support_colour[i]; } - for (size_t i = 0; i <= OpenRCT2::Limits::MaxTrainsPerRide; i++) + for (size_t i = 0; i < OpenRCT2::Limits::MaxVehicleColours; i++) { - auto tdIndex = i % std::size(_td.vehicle_colours); - ride->vehicle_colours[i] = _td.vehicle_colours[tdIndex]; + ride->vehicle_colours[i] = _td.vehicle_colours[i]; } for (int32_t count = 1; count == 1 || r.Error != GameActions::Status::Ok; ++count) diff --git a/src/openrct2/rct2/Limits.h b/src/openrct2/rct2/Limits.h index 966884652e..9e139e1d99 100644 --- a/src/openrct2/rct2/Limits.h +++ b/src/openrct2/rct2/Limits.h @@ -16,6 +16,7 @@ namespace RCT2::Limits constexpr uint8_t MaxStaff = 200; constexpr uint8_t MaxBanners = 250; constexpr uint8_t MaxTrainsPerRide = 32; + constexpr uint8_t MaxVehicleColours = 32; constexpr uint8_t DowntimeHistorySize = 8; constexpr uint16_t MaxEntities = 10000; constexpr uint16_t MaxEntitiesRCTCExtended = 15000; // Used in files marked with “classic flag” 0xF diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index 6ab45fb4d7..3c4b586a18 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -72,11 +72,11 @@ namespace RCT2 uint8_t Type; // 0x000 // pointer to static info. for example, wild mouse type is 0x36, subtype is // 0x4c. - RCT12ObjectEntryIndex Subtype; // 0x001 - uint16_t Pad002; // 0x002 - uint8_t Mode; // 0x004 - uint8_t ColourSchemeType; // 0x005 - RCT12VehicleColour VehicleColours[Limits::MaxTrainsPerRide]; // 0x006 + RCT12ObjectEntryIndex Subtype; // 0x001 + uint16_t Pad002; // 0x002 + uint8_t Mode; // 0x004 + uint8_t ColourSchemeType; // 0x005 + RCT12VehicleColour VehicleColours[Limits::MaxVehicleColours]; // 0x006 uint8_t Pad046[0x03]; // 0x046, Used to be track colours in RCT1 without expansions // 0 = closed, 1 = open, 2 = test uint8_t Status; // 0x049 @@ -256,33 +256,33 @@ namespace RCT2 uint8_t BreakdownSoundModifier; // 0x1AC // Used to oscillate the sound when ride breaks down. // 0 = no change, 255 = max change - uint8_t NotFixedTimeout; // 0x1AD - uint8_t LastCrashType; // 0x1AE - uint8_t ConnectedMessageThrottle; // 0x1AF - money32 IncomePerHour; // 0x1B0 - money32 Profit; // 0x1B4 - uint8_t QueueTime[Limits::MaxStationsPerRide]; // 0x1B8 - uint8_t TrackColourMain[Limits::NumColourSchemes]; // 0x1BC - uint8_t TrackColourAdditional[Limits::NumColourSchemes]; // 0x1C0 - uint8_t TrackColourSupports[Limits::NumColourSchemes]; // 0x1C4 - uint8_t Music; // 0x1C8 - uint8_t EntranceStyle; // 0x1C9 - uint16_t VehicleChangeTimeout; // 0x1CA - uint8_t NumBlockBrakes; // 0x1CC - uint8_t LiftHillSpeed; // 0x1CD - uint16_t GuestsFavourite; // 0x1CE - uint32_t LifecycleFlags; // 0x1D0 - uint8_t VehicleColoursExtended[Limits::MaxTrainsPerRide]; // 0x1D4 - uint16_t TotalAirTime; // 0x1F4 - uint8_t CurrentTestStation; // 0x1F6 - uint8_t NumCircuits; // 0x1F7 - int16_t CableLiftX; // 0x1F8 - int16_t CableLiftY; // 0x1FA - uint8_t CableLiftZ; // 0x1FC - uint8_t Pad1FD; // 0x1FD - uint16_t CableLift; // 0x1FE - uint16_t QueueLength[Limits::MaxStationsPerRide]; // 0x200 - uint8_t Pad208[0x58]; // 0x208 + uint8_t NotFixedTimeout; // 0x1AD + uint8_t LastCrashType; // 0x1AE + uint8_t ConnectedMessageThrottle; // 0x1AF + money32 IncomePerHour; // 0x1B0 + money32 Profit; // 0x1B4 + uint8_t QueueTime[Limits::MaxStationsPerRide]; // 0x1B8 + uint8_t TrackColourMain[Limits::NumColourSchemes]; // 0x1BC + uint8_t TrackColourAdditional[Limits::NumColourSchemes]; // 0x1C0 + uint8_t TrackColourSupports[Limits::NumColourSchemes]; // 0x1C4 + uint8_t Music; // 0x1C8 + uint8_t EntranceStyle; // 0x1C9 + uint16_t VehicleChangeTimeout; // 0x1CA + uint8_t NumBlockBrakes; // 0x1CC + uint8_t LiftHillSpeed; // 0x1CD + uint16_t GuestsFavourite; // 0x1CE + uint32_t LifecycleFlags; // 0x1D0 + uint8_t VehicleColoursExtended[Limits::MaxVehicleColours]; // 0x1D4 + uint16_t TotalAirTime; // 0x1F4 + uint8_t CurrentTestStation; // 0x1F6 + uint8_t NumCircuits; // 0x1F7 + int16_t CableLiftX; // 0x1F8 + int16_t CableLiftY; // 0x1FA + uint8_t CableLiftZ; // 0x1FC + uint8_t Pad1FD; // 0x1FD + uint16_t CableLift; // 0x1FE + uint16_t QueueLength[Limits::MaxStationsPerRide]; // 0x200 + uint8_t Pad208[0x58]; // 0x208 uint8_t GetMinCarsPerTrain() const; uint8_t GetMaxCarsPerTrain() const; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 3c18185470..e58cfd3e4e 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1270,7 +1270,7 @@ namespace RCT2 dst->mode = static_cast(src->Mode); dst->colour_scheme_type = src->ColourSchemeType; - for (uint8_t i = 0; i < Limits::MaxTrainsPerRide; i++) + for (uint8_t i = 0; i < Limits::MaxVehicleColours; i++) { dst->vehicle_colours[i].Body = src->VehicleColours[i].BodyColour; dst->vehicle_colours[i].Trim = src->VehicleColours[i].TrimColour; diff --git a/src/openrct2/rct2/T6Exporter.cpp b/src/openrct2/rct2/T6Exporter.cpp index f1d44d754f..5fa48a4c2d 100644 --- a/src/openrct2/rct2/T6Exporter.cpp +++ b/src/openrct2/rct2/T6Exporter.cpp @@ -16,6 +16,7 @@ #include "../localisation/StringIds.h" #include "../object/ObjectList.h" #include "../rct12/SawyerChunkWriter.h" +#include "../rct2/RCT2.h" #include "../ride/Ride.h" #include "../ride/RideData.h" #include "../ride/Station.h" @@ -56,10 +57,10 @@ namespace RCT2 tempStream.WriteValue(_trackDesign->flags); tempStream.WriteValue(static_cast(_trackDesign->ride_mode)); tempStream.WriteValue((_trackDesign->colour_scheme & 0x3) | (2 << 2)); - for (auto& colour : _trackDesign->vehicle_colours) + for (auto i = 0; i < RCT2::Limits::MaxVehicleColours; i++) { - tempStream.WriteValue(colour.Body); - tempStream.WriteValue(colour.Trim); + tempStream.WriteValue(_trackDesign->vehicle_colours[i].Body); + tempStream.WriteValue(_trackDesign->vehicle_colours[i].Trim); } tempStream.WriteValue(0); tempStream.WriteValue(_trackDesign->entrance_style); @@ -91,9 +92,9 @@ namespace RCT2 tempStream.Write(&_trackDesign->vehicle_object.Entry, sizeof(RCTObjectEntry)); tempStream.WriteValue(_trackDesign->space_required_x); tempStream.WriteValue(_trackDesign->space_required_y); - for (auto& colour : _trackDesign->vehicle_colours) + for (auto i = 0; i < RCT2::Limits::MaxVehicleColours; i++) { - tempStream.WriteValue(colour.Tertiary); + tempStream.WriteValue(_trackDesign->vehicle_colours[i].Tertiary); } tempStream.WriteValue(_trackDesign->lift_hill_speed | (_trackDesign->num_circuits << 5)); diff --git a/src/openrct2/rct2/T6Importer.cpp b/src/openrct2/rct2/T6Importer.cpp index 6746d651ff..06bbbc8f6c 100644 --- a/src/openrct2/rct2/T6Importer.cpp +++ b/src/openrct2/rct2/T6Importer.cpp @@ -16,6 +16,7 @@ #include "../object/ObjectRepository.h" #include "../object/RideObject.h" #include "../rct12/SawyerChunkReader.h" +#include "../rct2/RCT2.h" #include "../ride/Ride.h" #include "../ride/RideData.h" #include "../ride/TrackDesign.h" @@ -79,7 +80,7 @@ namespace RCT2 td->ride_mode = static_cast(td6.RideMode); td->track_flags = 0; td->colour_scheme = td6.VersionAndColourScheme & 0x3; - for (auto i = 0; i < Limits::MaxTrainsPerRide; ++i) + for (auto i = 0; i < Limits::MaxVehicleColours; ++i) { td->vehicle_colours[i].Body = td6.VehicleColours[i].BodyColour; td->vehicle_colours[i].Trim = td6.VehicleColours[i].TrimColour; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 0db5b03387..ef6ae35ce9 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -2181,7 +2181,7 @@ std::pair Ride::GetMeasurement() VehicleColour RideGetVehicleColour(const Ride& ride, int32_t vehicleIndex) { // Prevent indexing array out of bounds - vehicleIndex = std::min(vehicleIndex, OpenRCT2::Limits::MaxCarsPerTrain); + vehicleIndex = std::min(vehicleIndex, static_cast(std::size(ride.vehicle_colours))); return ride.vehicle_colours[vehicleIndex]; } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 2ef79e82f3..4576c7e8ae 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -119,7 +119,7 @@ struct Ride ObjectEntryIndex subtype; RideMode mode; uint8_t colour_scheme_type; - VehicleColour vehicle_colours[OpenRCT2::Limits::MaxTrainsPerRide + 1]; + VehicleColour vehicle_colours[OpenRCT2::Limits::MaxVehicleColours]; // 0 = closed, 1 = open, 2 = test RideStatus status; std::string custom_name; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 0001a9f851..30cfc7e68a 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -47,8 +47,7 @@ #include "../object/ObjectRepository.h" #include "../object/SmallSceneryEntry.h" #include "../object/StationObject.h" -#include "../rct1/RCT1.h" -#include "../rct1/Tables.h" +#include "../rct2/RCT2.h" #include "../ride/RideConstruction.h" #include "../util/SawyerCoding.h" #include "../util/Util.h" @@ -102,12 +101,12 @@ ResultWithMessage TrackDesign::CreateTrackDesign(TrackDesignState& tds, const Ri ride_mode = ride.mode; colour_scheme = ride.colour_scheme_type & 3; - for (int32_t i = 0; i < RCT2::Limits::MaxTrainsPerRide; i++) + for (size_t i = 0; i < std::size(vehicle_colours); i++) { vehicle_colours[i] = ride.vehicle_colours[i]; } - for (int32_t i = 0; i < RCT12::Limits::NumColourSchemes; i++) + for (int32_t i = 0; i < OpenRCT2::Limits::NumColourSchemes; i++) { track_spine_colour[i] = ride.track_colour[i].main; track_rail_colour[i] = ride.track_colour[i].additional; @@ -1998,7 +1997,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon ride->entrance_style = gLastEntranceStyle; } - for (int32_t i = 0; i < RCT12::Limits::NumColourSchemes; i++) + for (int32_t i = 0; i < OpenRCT2::Limits::NumColourSchemes; i++) { ride->track_colour[i].main = td6->track_spine_colour[i]; ride->track_colour[i].additional = td6->track_rail_colour[i]; @@ -2009,7 +2008,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon // in the preview window if (!GetRideTypeDescriptor(td6->type).HasFlag(RIDE_TYPE_FLAG_HAS_TRACK)) { - for (int32_t i = 0; i < RCT12::Limits::MaxVehicleColours; i++) + for (size_t i = 0; i < std::size(ride->vehicle_colours); i++) { ride->vehicle_colours[i] = td6->vehicle_colours[i]; } diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index d461120c1a..0f07e8d24a 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -9,11 +9,10 @@ #pragma once +#include "../Limits.h" #include "../actions/GameActionResult.h" #include "../common.h" #include "../object/Object.h" -#include "../rct12/RCT12.h" -#include "../rct2/RCT2.h" #include "../world/Map.h" #include "VehicleColour.h" @@ -126,7 +125,7 @@ struct TrackDesign RideMode ride_mode; uint8_t track_flags; uint8_t colour_scheme; - std::array vehicle_colours; + std::array vehicle_colours; uint8_t entrance_style; uint8_t total_air_time; uint8_t depart_flags; @@ -149,9 +148,9 @@ struct TrackDesign uint8_t intensity; uint8_t nausea; money64 upkeep_cost; - uint8_t track_spine_colour[RCT12::Limits::NumColourSchemes]; - uint8_t track_rail_colour[RCT12::Limits::NumColourSchemes]; - uint8_t track_support_colour[RCT12::Limits::NumColourSchemes]; + uint8_t track_spine_colour[OpenRCT2::Limits::NumColourSchemes]; + uint8_t track_rail_colour[OpenRCT2::Limits::NumColourSchemes]; + uint8_t track_support_colour[OpenRCT2::Limits::NumColourSchemes]; uint32_t flags2; ObjectEntryDescriptor vehicle_object; uint8_t space_required_x; diff --git a/src/openrct2/ride/TrackDesignSave.cpp b/src/openrct2/ride/TrackDesignSave.cpp index 6470723f4e..ca4fbbafad 100644 --- a/src/openrct2/ride/TrackDesignSave.cpp +++ b/src/openrct2/ride/TrackDesignSave.cpp @@ -20,6 +20,7 @@ #include "../object/LargeSceneryObject.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" +#include "../rct2/RCT2.h" #include "../util/SawyerCoding.h" #include "../util/Util.h" #include "../windows/Intent.h" diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 282ba1d5a6..4ad2f901ad 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -28,6 +28,7 @@ #include "../platform/Platform.h" #include "../rct12/RCT12.h" #include "../rct12/SawyerChunkReader.h" +#include "../rct2/RCT2.h" #include "Scenario.h" #include "ScenarioSources.h" diff --git a/test/tests/S6ImportExportTests.cpp b/test/tests/S6ImportExportTests.cpp index 2bdf26c669..fd7f99e9b9 100644 --- a/test/tests/S6ImportExportTests.cpp +++ b/test/tests/S6ImportExportTests.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include