From bb73dd0dfb781e0653789057f948d613428ea142 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 31 Aug 2019 13:14:19 +0200 Subject: [PATCH] Refactor track element to use 16 bytes --- src/openrct2/actions/RideDemolishAction.hpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 11 +- src/openrct2/rct12/RCT12.cpp | 34 +++--- src/openrct2/rct12/RCT12.h | 27 +++++ src/openrct2/rct2/S6Exporter.cpp | 14 ++- src/openrct2/rct2/S6Importer.cpp | 14 ++- src/openrct2/ride/RideTypes.h | 1 + src/openrct2/ride/Track.cpp | 119 ++++++++++---------- src/openrct2/ride/Track.h | 35 +++--- src/openrct2/ride/TrackDesign.cpp | 6 +- src/openrct2/world/TileElement.h | 56 +++++---- test/testpaint/Compat.cpp | 108 +++++++++--------- 12 files changed, 243 insertions(+), 184 deletions(-) diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 3919e7e793..3530f747a9 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -295,7 +295,7 @@ private: if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK) continue; - if (it.element->AsTrack()->GetRideIndex() != _rideIndex) + if (it.element->AsTrack()->GetRideIndex() != (ride_idnew_t)_rideIndex) continue; int32_t x = it.x * 32, y = it.y * 32; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 73e6450338..72e5e8a7e5 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2127,13 +2127,16 @@ private: dst2->SetInverted(src2->IsInverted()); dst2->SetBrakeBoosterSpeed(src2->GetBrakeBoosterSpeed()); dst2->SetHasGreenLight(src2->HasGreenLight()); - dst2->SetSeatRotation(4); - dst2->SetMazeEntry(src2->GetMazeEntry()); dst2->SetPhotoTimeout(src2->GetPhotoTimeout()); + dst2->SetDoorAState(src2->GetDoorAState()); + dst2->SetDoorBState(src2->GetDoorBState()); + auto ride = get_ride(dst2->GetRideIndex()); + if (ride && ride->type == RIDE_TYPE_MAZE) + { + dst2->SetMazeEntry(src2->GetMazeEntry()); + } // Skipping IsHighlighted() - // TODO: Import Door A and Door B states. - break; } case TILE_ELEMENT_TYPE_SMALL_SCENERY: diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index c3f3e5c9c3..30d32809ba 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -175,7 +175,7 @@ uint8_t RCT12TrackElement::GetTrackType() const uint8_t RCT12TrackElement::GetSequenceIndex() const { - return sequence & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; + return sequence & RCT12_TRACK_ELEMENT_SEQUENCE_SEQUENCE_MASK; } uint8_t RCT12TrackElement::GetRideIndex() const @@ -190,22 +190,22 @@ uint8_t RCT12TrackElement::GetColourScheme() const uint8_t RCT12TrackElement::GetStationIndex() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK) >> 4; + return (sequence & RCT12_TRACK_ELEMENT_SEQUENCE_STATION_INDEX_MASK) >> 4; } bool RCT12TrackElement::HasChain() const { - return type & TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + return type & RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; } bool RCT12TrackElement::HasCableLift() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + return colour & RCT12_TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; } bool RCT12TrackElement::IsInverted() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + return colour & RCT12_TRACK_ELEMENT_COLOUR_FLAG_INVERTED; } uint8_t RCT12TrackElement::GetBrakeBoosterSpeed() const @@ -235,12 +235,12 @@ uint8_t RCT12TrackElement::GetPhotoTimeout() const uint8_t RCT12TrackElement::GetDoorAState() const { - return (colour & TRACK_ELEMENT_DOOR_A_MASK) >> 2; + return (colour & RCT12_TRACK_ELEMENT_DOOR_A_MASK) >> 2; } uint8_t RCT12TrackElement::GetDoorBState() const { - return (colour & TRACK_ELEMENT_DOOR_B_MASK) >> 5; + return (colour & RCT12_TRACK_ELEMENT_DOOR_B_MASK) >> 5; } uint8_t RCT12SmallSceneryElement::GetEntryIndex() const @@ -685,13 +685,13 @@ void RCT12TrackElement::SetTrackType(uint8_t newType) void RCT12TrackElement::SetSequenceIndex(uint8_t newSequenceIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (newSequenceIndex & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK); + sequence &= ~RCT12_TRACK_ELEMENT_SEQUENCE_SEQUENCE_MASK; + sequence |= (newSequenceIndex & RCT12_TRACK_ELEMENT_SEQUENCE_SEQUENCE_MASK); } void RCT12TrackElement::SetStationIndex(uint8_t newStationIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK; + sequence &= ~RCT12_TRACK_ELEMENT_SEQUENCE_STATION_INDEX_MASK; sequence |= (newStationIndex << 4); } @@ -708,20 +708,20 @@ void RCT12TrackElement::SetColourScheme(uint8_t newColourScheme) void RCT12TrackElement::SetHasCableLift(bool on) { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + colour &= ~RCT12_TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; if (on) - colour |= TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + colour |= RCT12_TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; } void RCT12TrackElement::SetInverted(bool inverted) { if (inverted) { - colour |= TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + colour |= RCT12_TRACK_ELEMENT_COLOUR_FLAG_INVERTED; } else { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + colour &= ~RCT12_TRACK_ELEMENT_COLOUR_FLAG_INVERTED; } } @@ -756,11 +756,11 @@ void RCT12TrackElement::SetHasChain(bool on) { if (on) { - type |= TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + type |= RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; } else { - type &= ~TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + type &= ~RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; } } @@ -777,7 +777,7 @@ void RCT12TrackElement::SetMazeEntry(uint16_t newMazeEntry) void RCT12TrackElement::SetPhotoTimeout(uint8_t value) { - sequence &= MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; + sequence &= RCT12_TRACK_ELEMENT_SEQUENCE_SEQUENCE_MASK; sequence |= (value << 4); } diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 9b1dc60a1f..25dbb0c462 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -57,6 +57,33 @@ enum class RCT12TrackDesignVersion : uint8_t unknown }; +enum +{ + RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT = 1 << 7, +}; + +enum +{ + RCT12_TRACK_ELEMENT_SEQUENCE_STATION_INDEX_MASK = 0b01110000, + RCT12_TRACK_ELEMENT_SEQUENCE_SEQUENCE_MASK = 0b00001111, + RCT12_TRACK_ELEMENT_SEQUENCE_TAKING_PHOTO_MASK = 0b11110000, +}; + +enum +{ + // Not anything to do with colour but uses + // that field in the tile element + + // Used for multi-dimension coaster + RCT12_TRACK_ELEMENT_COLOUR_FLAG_INVERTED = (1 << 2), + + // Used for giga coaster + RCT12_TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT = (1 << 3), + + RCT12_TRACK_ELEMENT_DOOR_A_MASK = 0b00011100, + RCT12_TRACK_ELEMENT_DOOR_B_MASK = 0b11100000, +}; + // Everything before this point has been researched #define RCT12_RESEARCHED_ITEMS_SEPARATOR (-1) // Everything before this point and after separator still requires research diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index e82e8653e1..417426d922 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -1422,9 +1422,19 @@ void S6Exporter::ExportTileElement(RCT12TileElement* dst, TileElement* src) dst2->SetInverted(src2->IsInverted()); dst2->SetBrakeBoosterSpeed(src2->GetBrakeBoosterSpeed()); dst2->SetHasGreenLight(src2->HasGreenLight()); - dst2->SetSeatRotation(src2->GetSeatRotation()); - dst2->SetMazeEntry(src2->GetMazeEntry()); dst2->SetPhotoTimeout(src2->GetPhotoTimeout()); + auto ride = get_ride(dst2->GetRideIndex()); + if (ride) + { + if (ride->type == RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER) + { + dst2->SetSeatRotation(src2->GetSeatRotation()); + } + else if (ride->type == RIDE_TYPE_MAZE) + { + dst2->SetMazeEntry(src2->GetMazeEntry()); + } + } // Skipping IsHighlighted() break; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 40e8c7a9ac..7320169979 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1056,10 +1056,20 @@ public: dst2->SetInverted(src2->IsInverted()); dst2->SetBrakeBoosterSpeed(src2->GetBrakeBoosterSpeed()); dst2->SetHasGreenLight(src2->HasGreenLight()); - dst2->SetSeatRotation(src2->GetSeatRotation()); - dst2->SetMazeEntry(src2->GetMazeEntry()); dst2->SetPhotoTimeout(src2->GetPhotoTimeout()); // Skipping IsHighlighted() + auto ride = get_ride(dst2->GetRideIndex()); + if (ride) + { + if (ride->type == RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER) + { + dst2->SetSeatRotation(src2->GetSeatRotation()); + } + else if (ride->type == RIDE_TYPE_MAZE) + { + dst2->SetMazeEntry(src2->GetMazeEntry()); + } + } break; } diff --git a/src/openrct2/ride/RideTypes.h b/src/openrct2/ride/RideTypes.h index 473a6a8008..99c2b87e2a 100644 --- a/src/openrct2/ride/RideTypes.h +++ b/src/openrct2/ride/RideTypes.h @@ -12,4 +12,5 @@ #include typedef uint8_t ride_id_t; +typedef uint32_t ride_idnew_t; // Temporary, old one can be removed after switching save format. struct Ride; diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index fdc49ddd52..b74b85a7ac 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -1074,18 +1074,18 @@ void track_get_front(CoordsXYE* input, CoordsXYE* output) bool TrackElement::HasChain() const { - return type & TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + return Flags2 & TRACK_ELEMENT_FLAGS2_CHAIN_LIFT; } void TrackElement::SetHasChain(bool on) { if (on) { - type |= TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + Flags2 |= TRACK_ELEMENT_FLAGS2_CHAIN_LIFT; } else { - type &= ~TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_CHAIN_LIFT; } } @@ -1215,155 +1215,159 @@ bool track_element_has_speed_setting(uint8_t trackType) uint8_t TrackElement::GetSeatRotation() const { - return colour >> 4; + return ColourScheme >> 4; } void TrackElement::SetSeatRotation(uint8_t newSeatRotation) { - colour &= 0x0F; - colour |= (newSeatRotation << 4); + ColourScheme &= ~TRACK_ELEMENT_COLOUR_SEAT_ROTATION_MASK; + ColourScheme |= (newSeatRotation << 4); } bool TrackElement::IsTakingPhoto() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK) != 0; + return OnridePhotoBits != 0; } void TrackElement::SetPhotoTimeout() { - sequence &= MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (3 << 4); + OnridePhotoBits = 3; } void TrackElement::SetPhotoTimeout(uint8_t value) { - sequence &= MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (value << 4); + OnridePhotoBits = value; } uint8_t TrackElement::GetPhotoTimeout() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK) >> 4; + return OnridePhotoBits; } void TrackElement::DecrementPhotoTimeout() { - // We should only touch the upper 4 bits, avoid underflow into the lower 4. - if (sequence & MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK) - { - sequence -= (1 << 4); - } + OnridePhotoBits = std::max(0, OnridePhotoBits - 1); } uint16_t TrackElement::GetMazeEntry() const { - return mazeEntry; + return MazeEntry; } void TrackElement::SetMazeEntry(uint16_t newMazeEntry) { - mazeEntry = newMazeEntry; + MazeEntry = newMazeEntry; } void TrackElement::MazeEntryAdd(uint16_t addVal) { - mazeEntry |= addVal; + MazeEntry |= addVal; } void TrackElement::MazeEntrySubtract(uint16_t subVal) { - mazeEntry &= ~subVal; + MazeEntry &= ~subVal; } -uint8_t TrackElement::GetTrackType() const +uint16_t TrackElement::GetTrackType() const { - return trackType; + return TrackType; } -void TrackElement::SetTrackType(uint8_t newType) +void TrackElement::SetTrackType(uint16_t newType) { - trackType = newType; + TrackType = newType; } uint8_t TrackElement::GetSequenceIndex() const { - return sequence & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; + return Sequence; } void TrackElement::SetSequenceIndex(uint8_t newSequenceIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (newSequenceIndex & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK); + Sequence = newSequenceIndex; } uint8_t TrackElement::GetStationIndex() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK) >> 4; + return StationIndex; } void TrackElement::SetStationIndex(uint8_t newStationIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK; - sequence |= (newStationIndex << 4); + StationIndex = newStationIndex; } uint8_t TrackElement::GetDoorAState() const { - return (colour & TRACK_ELEMENT_DOOR_A_MASK) >> 2; + return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_A_MASK) >> 2; } uint8_t TrackElement::GetDoorBState() const { - return (colour & TRACK_ELEMENT_DOOR_B_MASK) >> 5; + return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_B_MASK) >> 5; } -ride_id_t TrackElement::GetRideIndex() const +void TrackElement::SetDoorAState(uint8_t newState) { - return rideIndex; + ColourScheme &= ~TRACK_ELEMENT_COLOUR_DOOR_A_MASK; + ColourScheme |= ((newState << 2) & TRACK_ELEMENT_COLOUR_DOOR_A_MASK); } -void TrackElement::SetRideIndex(ride_id_t newRideIndex) +void TrackElement::SetDoorBState(uint8_t newState) { - rideIndex = newRideIndex; + ColourScheme &= ~TRACK_ELEMENT_COLOUR_DOOR_B_MASK; + ColourScheme |= ((newState << 5) & TRACK_ELEMENT_COLOUR_DOOR_B_MASK); +} + +ride_idnew_t TrackElement::GetRideIndex() const +{ + return RideIndex; +} + +void TrackElement::SetRideIndex(ride_idnew_t newRideIndex) +{ + RideIndex = newRideIndex; } uint8_t TrackElement::GetColourScheme() const { - return colour & 0x3; + return ColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK; } void TrackElement::SetColourScheme(uint8_t newColourScheme) { - colour &= ~0x3; - colour |= (newColourScheme & 0x3); + ColourScheme &= ~TRACK_ELEMENT_COLOUR_SCHEME_MASK; + ColourScheme |= (newColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK); } bool TrackElement::HasCableLift() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + return Flags2 & TRACK_ELEMENT_FLAGS2_CABLE_LIFT; } void TrackElement::SetHasCableLift(bool on) { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_CABLE_LIFT; if (on) - colour |= TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + Flags2 |= TRACK_ELEMENT_FLAGS2_CABLE_LIFT; } bool TrackElement::IsInverted() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + return Flags2 & TRACK_ELEMENT_FLAGS2_INVERTED; } void TrackElement::SetInverted(bool inverted) { if (inverted) { - colour |= TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + Flags2 |= TRACK_ELEMENT_FLAGS2_INVERTED; } else { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_INVERTED; } } @@ -1403,37 +1407,36 @@ void TrackElement::SetIsIndestructible(bool isIndestructible) uint8_t TrackElement::GetBrakeBoosterSpeed() const { - return (sequence >> 4) << 1; + return BrakeBoosterSpeed << 1; } void TrackElement::SetBrakeBoosterSpeed(uint8_t speed) { - sequence &= ~0b11110000; - sequence |= ((speed >> 1) << 4); + BrakeBoosterSpeed = (speed >> 1); } -uint8_t TrackElement::HasGreenLight() const +bool TrackElement::HasGreenLight() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT) != 0; + return (Flags2 & TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT) != 0; } -void TrackElement::SetHasGreenLight(uint8_t greenLight) +void TrackElement::SetHasGreenLight(bool on) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT; - if (greenLight) + Flags2 &= ~TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT; + if (on) { - sequence |= MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT; + Flags2 |= TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT; } } bool TrackElement::IsHighlighted() const { - return (type & TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT); + return (Flags2 & TRACK_ELEMENT_FLAGS2_HIGHLIGHT); } void TrackElement::SetHighlight(bool on) { - type &= ~TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_HIGHLIGHT; if (on) - type |= TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT; + Flags2 |= TRACK_ELEMENT_FLAGS2_HIGHLIGHT; } diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index f24e71a354..3e0b7c80e3 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -13,6 +13,8 @@ #include "../object/Object.h" #include "Ride.h" +typedef uint16_t track_type_t; + #pragma pack(push, 1) struct rct_trackdefinition { @@ -53,32 +55,27 @@ struct rct_track_coordinates enum { TRACK_ELEMENT_FLAG_TERMINAL_STATION = 1 << 3, - TRACK_ELEMENT_FLAG_INVERTED = 1 << 6, + TD6_TRACK_ELEMENT_FLAG_INVERTED = 1 << 6, }; enum { - TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT = 1 << 7, -}; - -enum -{ - // Not anything to do with colour but uses - // that field in the map element - - // Used for multi-dimension coaster - TRACK_ELEMENT_COLOUR_FLAG_INVERTED = (1 << 2), - + TRACK_ELEMENT_FLAGS2_CHAIN_LIFT = 1 << 0, + TRACK_ELEMENT_FLAGS2_INVERTED = 1 << 1, // Used for giga coaster - TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT = (1 << 3), - - TRACK_ELEMENT_DOOR_A_MASK = 0b00011100, - TRACK_ELEMENT_DOOR_B_MASK = 0b11100000, + TRACK_ELEMENT_FLAGS2_CABLE_LIFT = 1 << 2, + TRACK_ELEMENT_FLAGS2_HIGHLIGHT = 1 << 3, + TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT = 1 << 4, }; -#define TRACK_ELEMENT_FLAG_MAGNITUDE_MASK 0x0F -#define TRACK_ELEMENT_FLAG_COLOUR_MASK 0x30 -#define TRACK_ELEMENT_FLAG_STATION_NO_MASK 0x02 +enum +{ + TRACK_ELEMENT_COLOUR_SCHEME_MASK = 0b00000011, + // Not colour related, but shares the field. + TRACK_ELEMENT_COLOUR_DOOR_A_MASK = 0b00011100, + TRACK_ELEMENT_COLOUR_DOOR_B_MASK = 0b11100000, + TRACK_ELEMENT_COLOUR_SEAT_ROTATION_MASK = 0b11110000, +}; #define MAX_STATION_PLATFORM_LENGTH 32 diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 642df48b92..c0f1685726 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -225,7 +225,7 @@ rct_string_id TrackDesign::CreateTrackDesignTrack(const Ride& ride) if (RideData4[ride.type].flags & RIDE_TYPE_FLAG4_HAS_ALTERNATIVE_TRACK_TYPE && trackElement.element->AsTrack()->IsInverted()) { - trackFlags |= TRACK_ELEMENT_FLAG_INVERTED; + trackFlags |= TD6_TRACK_ELEMENT_FLAG_INVERTED; } track.flags = trackFlags; @@ -1504,11 +1504,11 @@ static bool track_design_place_ride(TrackDesign* td6, int16_t x, int16_t y, int1 uint32_t seatRotation = track.flags & 0x0F; int32_t liftHillAndAlternativeState = 0; - if (track.flags & TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT) + if (track.flags & RCT12_TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT) { liftHillAndAlternativeState |= 1; } - if (track.flags & TRACK_ELEMENT_FLAG_INVERTED) + if (track.flags & TD6_TRACK_ELEMENT_FLAG_INVERTED) { liftHillAndAlternativeState |= 2; } diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index 0c4035ba04..24afa0b9a4 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -17,6 +17,7 @@ struct Banner; struct rct_scenery_entry; struct rct_footpath_entry; +typedef uint16_t track_type_t; #pragma pack(push, 1) @@ -254,42 +255,46 @@ assert_struct_size(PathElement, 16); struct TrackElement : TileElementBase { - uint8_t trackType; // 4 +private: + track_type_t TrackType; union { struct { - // The lower 4 bits are the track sequence. - // The upper 4 bits are either station bits or on-ride photo bits. - // - // Station bits: - // - Bit 8 marks green light - // - Bit 5-7 are station index. - // - // On-ride photo bits: - // - Bits 7 and 8 are never set - // - Bits 5 and 6 are set when a vehicle triggers the on-ride photo and act like a countdown from 3. - // - If any of the bits 5-8 are set, the game counts it as a photo being taken. - uint8_t sequence; // 5. - uint8_t colour; // 6 + uint8_t Sequence; + uint8_t ColourScheme; + union + { + // - Bits 3 and 4 are never set + // - Bits 1 and 2 are set when a vehicle triggers the on-ride photo and act like a countdown from 3. + // - If any of the bits 1-4 are set, the game counts it as a photo being taken. + uint8_t OnridePhotoBits; + // Contains the brake/booster speed, divided by 2. + uint8_t BrakeBoosterSpeed; + }; + uint8_t StationIndex; + }; + struct + { + uint16_t MazeEntry; // 5 }; - uint16_t mazeEntry; // 5 }; - ride_id_t rideIndex; // 7 + uint8_t Flags2; + ride_idnew_t RideIndex; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-private-field" - uint8_t pad_08[8]; + uint8_t pad[1]; #pragma clang diagnostic pop public: - uint8_t GetTrackType() const; - void SetTrackType(uint8_t newEntryIndex); + track_type_t GetTrackType() const; + void SetTrackType(track_type_t newEntryIndex); uint8_t GetSequenceIndex() const; void SetSequenceIndex(uint8_t newSequenceIndex); - ride_id_t GetRideIndex() const; - void SetRideIndex(ride_id_t newRideIndex); + uint32_t GetRideIndex() const; + void SetRideIndex(uint32_t newRideIndex); uint8_t GetColourScheme() const; void SetColourScheme(uint8_t newColourScheme); @@ -315,8 +320,8 @@ public: uint8_t GetBrakeBoosterSpeed() const; void SetBrakeBoosterSpeed(uint8_t speed); - uint8_t HasGreenLight() const; - void SetHasGreenLight(uint8_t greenLight); + bool HasGreenLight() const; + void SetHasGreenLight(bool on); uint8_t GetSeatRotation() const; void SetSeatRotation(uint8_t newSeatRotation); @@ -335,10 +340,12 @@ public: bool IsHighlighted() const; void SetHighlight(bool on); - // Used in RCT1, will be reintroduced at some point. + // Used by ghost train, RCT1 feature, will be reintroduced at some point. // (See https://github.com/OpenRCT2/OpenRCT2/issues/7059) uint8_t GetDoorAState() const; uint8_t GetDoorBState() const; + void SetDoorAState(uint8_t newState); + void SetDoorBState(uint8_t newState); }; assert_struct_size(TrackElement, 16); @@ -556,7 +563,6 @@ enum enum { - TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6), SURFACE_ELEMENT_HAS_TRACK_THAT_NEEDS_WATER = (1 << 6), }; diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index a3b3f01897..c73715dc9d 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -210,186 +210,188 @@ bool is_csg_loaded() uint8_t TrackElement::GetSeatRotation() const { - return colour >> 4; + return ColourScheme >> 4; } void TrackElement::SetSeatRotation(uint8_t newSeatRotation) { - colour &= 0x0F; - colour |= (newSeatRotation << 4); + ColourScheme &= ~TRACK_ELEMENT_COLOUR_SEAT_ROTATION_MASK; + ColourScheme |= (newSeatRotation << 4); } bool TrackElement::IsTakingPhoto() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK) != 0; + return OnridePhotoBits != 0; } void TrackElement::SetPhotoTimeout() { - sequence &= MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (3 << 4); + OnridePhotoBits = 3; +} + +void TrackElement::SetPhotoTimeout(uint8_t value) +{ + OnridePhotoBits = value; +} + +uint8_t TrackElement::GetPhotoTimeout() const +{ + return OnridePhotoBits; } void TrackElement::DecrementPhotoTimeout() { - // We should only touch the upper 4 bits, avoid underflow into the lower 4. - if (sequence & MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK) - { - sequence -= (1 << 4); - } + OnridePhotoBits = std::max(0, OnridePhotoBits - 1); } uint16_t TrackElement::GetMazeEntry() const { - return mazeEntry; + return MazeEntry; } void TrackElement::SetMazeEntry(uint16_t newMazeEntry) { - mazeEntry = newMazeEntry; + MazeEntry = newMazeEntry; } void TrackElement::MazeEntryAdd(uint16_t addVal) { - mazeEntry |= addVal; + MazeEntry |= addVal; } void TrackElement::MazeEntrySubtract(uint16_t subVal) { - mazeEntry &= ~subVal; + MazeEntry &= ~subVal; } -uint8_t TrackElement::GetTrackType() const +track_type_t TrackElement::GetTrackType() const { - return trackType; + return TrackType; } -void TrackElement::SetTrackType(uint8_t newType) +void TrackElement::SetTrackType(track_type_t newType) { - trackType = newType; + TrackType = newType; } uint8_t TrackElement::GetSequenceIndex() const { - return sequence & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; + return Sequence; } void TrackElement::SetSequenceIndex(uint8_t newSequenceIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK; - sequence |= (newSequenceIndex & MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK); + Sequence = newSequenceIndex; } uint8_t TrackElement::GetStationIndex() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK) >> 4; + return StationIndex; } void TrackElement::SetStationIndex(uint8_t newStationIndex) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK; - sequence |= (newStationIndex << 4); + StationIndex = newStationIndex; } uint8_t TrackElement::GetDoorAState() const { - return (colour & TRACK_ELEMENT_DOOR_A_MASK) >> 2; + return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_A_MASK) >> 2; } uint8_t TrackElement::GetDoorBState() const { - return (colour & TRACK_ELEMENT_DOOR_B_MASK) >> 5; + return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_B_MASK) >> 5; } -uint8_t TrackElement::GetRideIndex() const +ride_idnew_t TrackElement::GetRideIndex() const { - return rideIndex; + return RideIndex; } -void TrackElement::SetRideIndex(uint8_t newRideIndex) +void TrackElement::SetRideIndex(ride_idnew_t newRideIndex) { - rideIndex = newRideIndex; + RideIndex = newRideIndex; } uint8_t TrackElement::GetColourScheme() const { - return colour & 0x3; + return ColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK; } void TrackElement::SetColourScheme(uint8_t newColourScheme) { - colour &= ~0x3; - colour |= (newColourScheme & 0x3); + ColourScheme &= ~TRACK_ELEMENT_COLOUR_SCHEME_MASK; + ColourScheme |= (newColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK); } bool TrackElement::HasCableLift() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + return Flags2 & TRACK_ELEMENT_FLAGS2_CABLE_LIFT; } void TrackElement::SetHasCableLift(bool on) { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_CABLE_LIFT; if (on) - colour |= TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT; + Flags2 |= TRACK_ELEMENT_FLAGS2_CABLE_LIFT; } bool TrackElement::IsInverted() const { - return colour & TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + return Flags2 & TRACK_ELEMENT_FLAGS2_INVERTED; } void TrackElement::SetInverted(bool inverted) { if (inverted) { - colour |= TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + Flags2 |= TRACK_ELEMENT_FLAGS2_INVERTED; } else { - colour &= ~TRACK_ELEMENT_COLOUR_FLAG_INVERTED; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_INVERTED; } } uint8_t TrackElement::GetBrakeBoosterSpeed() const { - return (sequence >> 4) << 1; + return BrakeBoosterSpeed << 1; } void TrackElement::SetBrakeBoosterSpeed(uint8_t speed) { - sequence &= ~0b11110000; - sequence |= ((speed >> 1) << 4); + BrakeBoosterSpeed = (speed >> 1); } -uint8_t TrackElement::HasGreenLight() const +bool TrackElement::HasGreenLight() const { - return (sequence & MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT) != 0; + return (Flags2 & TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT) != 0; } -void TrackElement::SetHasGreenLight(uint8_t greenLight) +void TrackElement::SetHasGreenLight(bool on) { - sequence &= ~MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT; - if (greenLight) + Flags2 &= ~TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT; + if (on) { - sequence |= MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT; + Flags2 |= TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT; } } bool TrackElement::HasChain() const { - return type & TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + return (Flags2 & TRACK_ELEMENT_FLAGS2_CHAIN_LIFT) != 0; } void TrackElement::SetHasChain(bool on) { if (on) { - type |= TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + Flags2 |= TRACK_ELEMENT_FLAGS2_CHAIN_LIFT; } else { - type &= ~TRACK_ELEMENT_TYPE_FLAG_CHAIN_LIFT; + Flags2 &= ~TRACK_ELEMENT_FLAGS2_CHAIN_LIFT; } } @@ -431,7 +433,7 @@ uint32_t SurfaceElement::GetWaterHeight() const bool TrackElement::IsHighlighted() const { - return (type & TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT); + return (Flags2 & TRACK_ELEMENT_FLAGS2_HIGHLIGHT); } uint8_t PathElement::GetEdges() const