From 520b1b481968de0da34b734542b54495cafea3ab Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 20 Feb 2019 20:03:48 +0000 Subject: [PATCH 1/5] Try out changed sprite structs for main game --- src/openrct2/Editor.cpp | 7 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/peep/Peep.h | 34 +------ src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 4 +- src/openrct2/ride/CableLift.cpp | 2 +- src/openrct2/ride/Ride.cpp | 4 +- src/openrct2/ride/Vehicle.cpp | 34 +++---- src/openrct2/ride/Vehicle.h | 44 +++------ src/openrct2/ride/water/SplashBoats.cpp | 2 +- src/openrct2/world/Sprite.cpp | 8 +- src/openrct2/world/Sprite.h | 125 +++++++----------------- src/openrct2/world/SpriteBase.h | 30 ++++++ 13 files changed, 115 insertions(+), 183 deletions(-) create mode 100644 src/openrct2/world/SpriteBase.h diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index d0ee7c04cb..f28f53713c 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -308,8 +308,11 @@ namespace Editor // for (int32_t i = 0; i < MAX_SPRITES; i++) { - rct_sprite* sprite = get_sprite(i); - user_string_free(sprite->generic.name_string_idx); + auto peep = get_sprite(i)->AsPeep(); + if (peep != nullptr) + { + user_string_free(peep->name_string_idx); + } } reset_sprite_list(); diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index b51c9608c4..fb1a6f3184 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4044,7 +4044,7 @@ void rct_peep::UpdateRideLeaveVehicle() if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_16)) { - for (; vehicle->is_child; vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)) + for (; vehicle->IsChild(); vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)) { uint16_t trackType = vehicle->track_type >> 2; if (trackType == TRACK_ELEM_FLAT || trackType > TRACK_ELEM_MIDDLE_STATION) diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index fdab0d2eb7..8395315f3c 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -15,6 +15,7 @@ #include "../ride/Ride.h" #include "../ride/RideTypes.h" #include "../world/Location.hpp" +#include "../world/SpriteBase.h" #include @@ -519,7 +520,6 @@ enum PeepRideDecision PEEP_RIDE_DECISION_THINKING = 1 << 2, }; -#pragma pack(push, 1) struct rct_peep_thought { PeepThoughtType type; // 0 @@ -527,33 +527,9 @@ struct rct_peep_thought uint8_t freshness; // 2 larger is less fresh uint8_t fresh_timeout; // 3 updates every tick }; -assert_struct_size(rct_peep_thought, 4); -struct rct_peep +struct rct_peep : rct_sprite_common { - uint8_t sprite_identifier; // 0x00 - uint8_t misc_identifier; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // 0x1E - uint8_t pad_1F[3]; rct_string_id name_string_idx; // 0x22 uint16_t next_x; // 0x24 uint16_t next_y; // 0x26 @@ -595,7 +571,6 @@ struct rct_peep uint8_t photo2_ride_ref; // 0x5C uint8_t photo3_ride_ref; // 0x5D uint8_t photo4_ride_ref; // 0x5E - uint8_t pad_5F[0x09]; // 0x5F uint8_t current_ride; // 0x68 uint8_t current_ride_station; // 0x69 uint8_t current_train; // 0x6A @@ -628,8 +603,6 @@ struct rct_peep uint16_t mechanic_time_since_call; // time getting to ride to fix uint16_t next_in_queue; // 0x74 }; - uint8_t pad_76; // Previously this was set to 0 but never used. - uint8_t pad_77; union { uint8_t maze_last_edge; // 0x78 @@ -710,7 +683,6 @@ struct rct_peep uint8_t hat_colour; // 0xF8 uint8_t favourite_ride; // 0xF9 uint8_t favourite_ride_rating; // 0xFA - uint8_t pad_FB; uint32_t item_standard_flags; // 0xFC public: // Peep @@ -850,8 +822,6 @@ private: Ride* FindBestRideToGoOn(); std::bitset FindRidesToGoOn(); }; -assert_struct_size(rct_peep, 0x100); -#pragma pack(pop) struct rct_sprite_bounds { diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 233246cb0f..02b3e54135 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -2549,7 +2549,7 @@ bool rct_peep::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride) while (true) { - if (vehicle->is_child == 0) + if (!vehicle->IsChild()) { break; } diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 7c2886c75a..b399843a43 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1150,7 +1150,7 @@ private: ImportVehicle(vehicle, srcVehicle); // If vehicle is the first car on a train add to train list - if (!vehicle->is_child) + if (!vehicle->IsChild()) { move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_TRAIN * 2); } @@ -1174,7 +1174,7 @@ private: dst->ride_subtype = ride->subtype; dst->vehicle_type = vehicleEntryIndex; - dst->is_child = src->type; + dst->type = src->type; dst->var_44 = src->var_44; dst->remaining_distance = src->remaining_distance; diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index dd47cff56c..2610156087 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -39,7 +39,7 @@ rct_vehicle* cable_lift_segment_create( move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_TRAIN * 2); ride->cable_lift = current->sprite_index; } - current->is_child = head ? 0 : 1; + current->type = head ? 0 : 1; current->var_44 = var_44; current->remaining_distance = remaining_distance; current->sprite_width = 10; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index c0d481b2ee..a42468c4d7 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4840,7 +4840,7 @@ static rct_vehicle* vehicle_create_car( vehicle->ride_subtype = ride->subtype; vehicle->vehicle_type = vehicleEntryIndex; - vehicle->is_child = carIndex == 0 ? 0 : 1; + vehicle->type = carIndex == 0 ? 0 : 1; vehicle->var_44 = ror32(vehicleEntry->spacing, 10) & 0xFFFF; edx = vehicleEntry->spacing >> 1; *remainingDistance -= edx; @@ -4941,7 +4941,7 @@ static rct_vehicle* vehicle_create_car( } if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_4) { - if (!vehicle->is_child) + if (!vehicle->IsChild()) { dl = 15; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 31f5f78468..5cc4b9a56a 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3526,7 +3526,7 @@ static void vehicle_update_collision_setup(rct_vehicle* vehicle) if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->is_child != 0) + while (frontVehicle->IsChild() != 0) frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); @@ -5267,7 +5267,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->is_child != 0) + while (frontVehicle->IsChild() != 0) frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); @@ -5286,7 +5286,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED; ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - if (vehicle->is_child == 0) + if (vehicle->IsChild() == 0) { vehicle_kill_all_passengers(vehicle); } @@ -5324,7 +5324,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->is_child != 0) + while (frontVehicle->IsChild() != 0) frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); @@ -5343,7 +5343,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED; ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - if (vehicle->is_child == 0) + if (vehicle->IsChild() == 0) { vehicle_kill_all_passengers(vehicle); } @@ -6202,7 +6202,7 @@ void vehicle_set_map_toolbar(const rct_vehicle* vehicle) ride = get_ride(vehicle->ride); - while (vehicle->is_child) + while (vehicle->IsChild()) { vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); } @@ -7570,7 +7570,7 @@ static void vehicle_update_handle_water_splash(rct_vehicle* vehicle) { if (rideEntry->flags & RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND_SLIDE) { - if (!vehicle->is_child) + if (!vehicle->IsChild()) { if (track_element_is_covered(trackType)) { @@ -7597,7 +7597,7 @@ static void vehicle_update_handle_water_splash(rct_vehicle* vehicle) } } } - if (!vehicle->is_child) + if (!vehicle->IsChild()) { if (trackType == TRACK_ELEM_WATER_SPLASH) { @@ -8037,7 +8037,7 @@ loc_6DB358: if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_LEFT_REVERSER || tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_RIGHT_REVERSER) { - if (!vehicle->is_child && vehicle->velocity <= 0x30000) + if (!vehicle->IsChild() && vehicle->velocity <= 0x30000) { vehicle->velocity = 0; } @@ -8201,7 +8201,7 @@ loc_6DAEB9: } if (trackType == TRACK_ELEM_BRAKE_FOR_DROP) { - if (!vehicle->is_child) + if (!vehicle->IsChild()) { if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP)) { @@ -8770,7 +8770,7 @@ loc_6DC476: if (vehicle->mini_golf_flags & (1 << 0)) { - regs.di = vehicle->is_child ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; + regs.di = vehicle->IsChild() ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; rct_vehicle* vEDI = GET_VEHICLE(regs.di); if (!(vEDI->mini_golf_flags & (1 << 0)) || (vEDI->mini_golf_flags & (1 << 2))) { @@ -8786,7 +8786,7 @@ loc_6DC476: if (vehicle->mini_golf_flags & (1 << 1)) { - regs.di = vehicle->is_child ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; + regs.di = vehicle->IsChild() ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; rct_vehicle* vEDI = GET_VEHICLE(regs.di); if (!(vEDI->mini_golf_flags & (1 << 1)) || (vEDI->mini_golf_flags & (1 << 2))) { @@ -8811,7 +8811,7 @@ loc_6DC476: { break; } - if (!vEDI->is_child) + if (!vEDI->IsChild()) continue; if (!(vEDI->mini_golf_flags & (1 << 4))) continue; @@ -8892,7 +8892,7 @@ loc_6DC476: vehicle->track_y = y; vehicle->track_z = z; - if (vehicle->is_child) + if (vehicle->IsChild()) { rct_vehicle* prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); regs.al = prevVehicle->var_CD; @@ -8910,7 +8910,7 @@ loc_6DC476: loc_6DC743: vehicle->track_progress = regs.ax; - if (vehicle->is_child) + if (vehicle->IsChild()) { vehicle->animation_frame++; if (vehicle->animation_frame >= 6) @@ -8929,7 +8929,7 @@ loc_6DC743: switch (moveInfo->y) { case 0: // loc_6DC7B4 - if (vehicle->is_child) + if (vehicle->IsChild()) { vehicle->mini_golf_flags |= (1 << 3); } @@ -9811,7 +9811,7 @@ int32_t vehicle_update_track_motion(rct_vehicle* vehicle, int32_t* outStation) if (rideEntry->flags & RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND_SLIDE) { - if (!vehicle->is_child) + if (!vehicle->IsChild()) { if (track_element_is_covered(vehicle->track_type >> 2)) { diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 158dad0c7d..2626af0668 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -13,6 +13,7 @@ #include "../common.h" #include "../ride/RideTypes.h" #include "../world/Location.hpp" +#include "../world/SpriteBase.h" #include #include @@ -104,39 +105,16 @@ static_assert(sizeof(rct_ride_entry_vehicle) % 4 == 0, "Invalid struct size"); static_assert(sizeof(rct_ride_entry_vehicle) % 8 == 0, "Invalid struct size"); #endif -struct rct_vehicle +struct rct_vehicle : rct_sprite_common { - uint8_t sprite_identifier; // 0x00 - uint8_t is_child; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // 0x1E - uint8_t vehicle_sprite_type; // 0x1F - uint8_t bank_rotation; // 0x20 - uint8_t pad_21[3]; - int32_t remaining_distance; // 0x24 - int32_t velocity; // 0x28 - int32_t acceleration; // 0x2C - ride_id_t ride; // 0x30 - uint8_t vehicle_type; // 0x31 - rct_vehicle_colour colours; // 0x32 + uint8_t vehicle_sprite_type; // 0x1F + uint8_t bank_rotation; // 0x20 + int32_t remaining_distance; // 0x24 + int32_t velocity; // 0x28 + int32_t acceleration; // 0x2C + ride_id_t ride; // 0x30 + uint8_t vehicle_type; // 0x31 + rct_vehicle_colour colours; // 0x32 union { uint16_t track_progress; // 0x34 @@ -242,6 +220,8 @@ struct rct_vehicle uint8_t colours_extended; // 0xD7 uint8_t seat_rotation; // 0xD8 uint8_t target_seat_rotation; // 0xD9 + + constexpr bool IsChild() const { return type != 0; } }; struct train_ref diff --git a/src/openrct2/ride/water/SplashBoats.cpp b/src/openrct2/ride/water/SplashBoats.cpp index 458906741a..caa91f0d87 100644 --- a/src/openrct2/ride/water/SplashBoats.cpp +++ b/src/openrct2/ride/water/SplashBoats.cpp @@ -1250,7 +1250,7 @@ void vehicle_visual_splash_boats_or_water_coaster( paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const rct_vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicle->is_child) + if (vehicle->IsChild()) { vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); } diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 27c5e8d14f..92f8b5e7ca 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -366,7 +366,6 @@ rct_sprite* create_sprite(uint8_t bl) sprite->x = LOCATION_NULL; sprite->y = LOCATION_NULL; sprite->z = 0; - sprite->name_string_idx = 0; sprite->sprite_width = 0x10; sprite->sprite_height_negative = 0x14; sprite->sprite_height_positive = 0x8; @@ -672,8 +671,13 @@ void sprite_set_coordinates(int16_t x, int16_t y, int16_t z, rct_sprite* sprite) */ void sprite_remove(rct_sprite* sprite) { + auto peep = sprite->AsPeep(); + if (peep != nullptr) + { + user_string_free(peep->name_string_idx); + } + move_sprite_to_list(sprite, SPRITE_LIST_NULL * 2); - user_string_free(sprite->generic.name_string_idx); sprite->generic.sprite_identifier = SPRITE_IDENTIFIER_NULL; _spriteFlashingList[sprite->generic.sprite_index] = false; diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 8b6cfd6ec4..ffc33977b0 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -13,6 +13,7 @@ #include "../common.h" #include "../peep/Peep.h" #include "../ride/Vehicle.h" +#include "SpriteBase.h" #define SPRITE_INDEX_NULL 0xFFFF #define MAX_SPRITES 10000 @@ -37,72 +38,32 @@ enum SPRITE_LIST SPRITE_LIST_UNKNOWN, }; -#pragma pack(push, 1) -struct rct_sprite_common -{ - uint8_t sprite_identifier; // 0x00 - uint8_t type; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // 0x1e - uint8_t pad_1F[3]; - rct_string_id name_string_idx; // 0x22 -}; - struct rct_sprite_generic : rct_sprite_common { - uint16_t pad_24; - uint16_t frame; // 0x26 + uint16_t frame; }; -assert_struct_size(rct_sprite_generic, 0x28); // 9 bytes struct rct_litter : rct_sprite_common { - uint32_t creationTick; // 0x24 + uint32_t creationTick; }; -assert_struct_size(rct_litter, 0x28); -struct rct_balloon : rct_sprite_common +struct rct_balloon : rct_sprite_generic { - uint16_t popped; // 0x24 - uint8_t time_to_move; // 0x26 - - uint8_t frame; // 0x27 - uint8_t pad_28[4]; - uint8_t colour; // 0x2C + uint16_t popped; + uint8_t time_to_move; + uint8_t colour; void Update(); void Pop(); void Press(); }; -assert_struct_size(rct_balloon, 0x2D); -struct rct_duck : rct_sprite_common +struct rct_duck : rct_sprite_generic { - uint8_t pad_1F[0x2]; - uint16_t frame; - uint8_t pad_28[0x8]; - int16_t target_x; // 0x30 - int16_t target_y; // 0x32 - uint8_t pad_34[0x14]; - uint8_t state; // 0x48 + int16_t target_x; + int16_t target_y; + uint8_t state; void UpdateFlyToWater(); void UpdateSwim(); @@ -114,65 +75,49 @@ struct rct_duck : rct_sprite_common void Remove(); void MoveTo(int16_t x, int16_t y, int16_t z); }; -assert_struct_size(rct_duck, 0x49); -struct rct_jumping_fountain : rct_sprite_common +struct rct_jumping_fountain : rct_sprite_generic { - uint8_t pad_1F[0x2]; - uint8_t num_ticks_alive; // 0x26 - uint8_t frame; // 0x27 - uint8_t pad_28[0x7]; // 0x28 Originally var_2E was set to direction but it was unused. - uint8_t fountain_flags; // 0x2F - int16_t target_x; // 0x30 - int16_t target_y; // 0x32 - uint8_t pad_34[0x12]; - uint16_t iteration; // 0x46 + uint8_t num_ticks_alive; + uint8_t fountain_flags; + int16_t target_x; + int16_t target_y; + uint16_t iteration; }; -assert_struct_size(rct_jumping_fountain, 0x48); struct rct_money_effect : rct_sprite_common { - uint16_t move_delay; // 0x24 - uint8_t num_movements; // 0x26 + uint16_t move_delay; + uint8_t num_movements; uint8_t vertical; - money32 value; // 0x28 - uint8_t pad_2C[0x18]; - int16_t offset_x; // 0x44 - uint16_t wiggle; // 0x46 + money32 value; + int16_t offset_x; + uint16_t wiggle; }; -assert_struct_size(rct_money_effect, 0x48); -struct rct_crashed_vehicle_particle : rct_sprite_common +struct rct_crashed_vehicle_particle : rct_sprite_generic { - uint16_t time_to_live; // 0x24 - uint16_t frame; // 0x26 - uint8_t pad_28[4]; + uint16_t time_to_live; uint8_t colour[2]; - uint16_t crashed_sprite_base; // 0x2E - int16_t velocity_x; // 0x30 - int16_t velocity_y; // 0x32 - int16_t velocity_z; // 0x34 - uint16_t pad_36; - int32_t acceleration_x; // 0x38 - int32_t acceleration_y; // 0x3C - int32_t acceleration_z; // 0x40 + uint16_t crashed_sprite_base; + int16_t velocity_x; + int16_t velocity_y; + int16_t velocity_z; + int32_t acceleration_x; + int32_t acceleration_y; + int32_t acceleration_z; }; -assert_struct_size(rct_crashed_vehicle_particle, 0x44); -struct rct_crash_splash : rct_sprite_common +struct rct_crash_splash : rct_sprite_generic { - uint16_t pad_24; - uint16_t frame; // 0x26 }; -assert_struct_size(rct_crash_splash, 0x28); -struct rct_steam_particle : rct_sprite_common +struct rct_steam_particle : rct_sprite_generic { - uint16_t time_to_move; // 0x24 Moves +1 z every 3 ticks after intitial 4 ticks - uint16_t frame; // 0x26 + uint16_t time_to_move; }; -assert_struct_size(rct_steam_particle, 0x28); +#pragma pack(push, 1) /** * Sprite structure. * size: 0x0100 diff --git a/src/openrct2/world/SpriteBase.h b/src/openrct2/world/SpriteBase.h new file mode 100644 index 0000000000..d6ec5f0079 --- /dev/null +++ b/src/openrct2/world/SpriteBase.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../common.h" + +struct rct_sprite_common +{ + uint8_t sprite_identifier; + uint8_t type; + uint16_t next_in_quadrant; + uint16_t next; + uint16_t previous; + // Valid values are SPRITE_LINKEDLIST_OFFSET_... + uint8_t linked_list_type_offset; + // Height from centre of sprite to bottom + uint8_t sprite_height_negative; + uint16_t sprite_index; + uint16_t flags; + int16_t x; + int16_t y; + int16_t z; + // Width from centre of sprite to edge + uint8_t sprite_width; + // Height from centre of sprite to top + uint8_t sprite_height_positive; + int16_t sprite_left; + int16_t sprite_top; + int16_t sprite_right; + int16_t sprite_bottom; + uint8_t sprite_direction; +}; From ca807c5ed4fcfef95bc5db77eff116faae0f8e06 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 25 Feb 2019 17:51:25 +0000 Subject: [PATCH 2/5] Refactor some IsChild references to GetHead --- src/openrct2/ride/Vehicle.cpp | 25 +++++++++++++------------ src/openrct2/ride/Vehicle.h | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 5cc4b9a56a..e34a1364bf 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -3525,10 +3525,7 @@ static void vehicle_update_collision_setup(rct_vehicle* vehicle) Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { - rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->IsChild() != 0) - frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); - + auto frontVehicle = vehicle->GetHead(); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); if (trainIndex == VEHICLE_INVALID_ID) { @@ -5266,10 +5263,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { - rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->IsChild() != 0) - frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); - + auto frontVehicle = vehicle->GetHead(); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); if (trainIndex == VEHICLE_INVALID_ID) { @@ -5323,10 +5317,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) Ride* ride = get_ride(vehicle->ride); if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) { - rct_vehicle* frontVehicle = vehicle; - while (frontVehicle->IsChild() != 0) - frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride); - + auto frontVehicle = vehicle->GetHead(); int trainIndex = ride_get_train_index_from_vehicle(ride, frontVehicle->sprite_index); if (trainIndex == VEHICLE_INVALID_ID) { @@ -10016,3 +10007,13 @@ void vehicle_claxon(const rct_vehicle* vehicle) break; } } + +rct_vehicle* rct_vehicle::GetHead() +{ + auto v = this; + while (v != nullptr && v->IsChild()) + { + v = GET_VEHICLE(v->prev_vehicle_on_ride); + } + return v; +} diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 2626af0668..909258dc28 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -222,6 +222,7 @@ struct rct_vehicle : rct_sprite_common uint8_t target_seat_rotation; // 0xD9 constexpr bool IsChild() const { return type != 0; } + rct_vehicle* GetHead(); }; struct train_ref From bac3168a23cbea7f776ae2c9222ce7c41ab0b329 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 25 Feb 2019 17:58:22 +0000 Subject: [PATCH 3/5] Refactor IsChild to IsHead --- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/peep/Staff.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/Vehicle.cpp | 40 ++++++++++++------------- src/openrct2/ride/Vehicle.h | 3 +- src/openrct2/ride/water/SplashBoats.cpp | 6 ++-- 7 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index fb1a6f3184..51e7d9fdf7 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -4044,7 +4044,7 @@ void rct_peep::UpdateRideLeaveVehicle() if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_16)) { - for (; vehicle->IsChild(); vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)) + for (; !vehicle->IsHead(); vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)) { uint16_t trackType = vehicle->track_type >> 2; if (trackType == TRACK_ELEM_FLAT || trackType > TRACK_ELEM_MIDDLE_STATION) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 02b3e54135..02b2f4175f 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -2549,7 +2549,7 @@ bool rct_peep::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride) while (true) { - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { break; } diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index b399843a43..26889027af 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1150,7 +1150,7 @@ private: ImportVehicle(vehicle, srcVehicle); // If vehicle is the first car on a train add to train list - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_TRAIN * 2); } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index a42468c4d7..39cc51a48c 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4941,7 +4941,7 @@ static rct_vehicle* vehicle_create_car( } if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_4) { - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { dl = 15; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index e34a1364bf..6f63a16b6c 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -5280,7 +5280,7 @@ static void vehicle_crash_on_land(rct_vehicle* vehicle) ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED; ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - if (vehicle->IsChild() == 0) + if (vehicle->IsHead()) { vehicle_kill_all_passengers(vehicle); } @@ -5334,7 +5334,7 @@ static void vehicle_crash_on_water(rct_vehicle* vehicle) ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED; ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - if (vehicle->IsChild() == 0) + if (vehicle->IsHead()) { vehicle_kill_all_passengers(vehicle); } @@ -6192,12 +6192,7 @@ void vehicle_set_map_toolbar(const rct_vehicle* vehicle) int32_t vehicleIndex; ride = get_ride(vehicle->ride); - - while (vehicle->IsChild()) - { - vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); - } - + vehicle = vehicle->GetHead(); for (vehicleIndex = 0; vehicleIndex < 32; vehicleIndex++) if (ride->vehicles[vehicleIndex] == vehicle->sprite_index) break; @@ -7561,7 +7556,7 @@ static void vehicle_update_handle_water_splash(rct_vehicle* vehicle) { if (rideEntry->flags & RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND_SLIDE) { - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { if (track_element_is_covered(trackType)) { @@ -7588,7 +7583,7 @@ static void vehicle_update_handle_water_splash(rct_vehicle* vehicle) } } } - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { if (trackType == TRACK_ELEM_WATER_SPLASH) { @@ -8028,7 +8023,7 @@ loc_6DB358: if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_LEFT_REVERSER || tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_RIGHT_REVERSER) { - if (!vehicle->IsChild() && vehicle->velocity <= 0x30000) + if (vehicle->IsHead() && vehicle->velocity <= 0x30000) { vehicle->velocity = 0; } @@ -8192,7 +8187,7 @@ loc_6DAEB9: } if (trackType == TRACK_ELEM_BRAKE_FOR_DROP) { - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP)) { @@ -8761,7 +8756,7 @@ loc_6DC476: if (vehicle->mini_golf_flags & (1 << 0)) { - regs.di = vehicle->IsChild() ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; + regs.di = vehicle->IsHead() ? vehicle->next_vehicle_on_ride : vehicle->prev_vehicle_on_ride; rct_vehicle* vEDI = GET_VEHICLE(regs.di); if (!(vEDI->mini_golf_flags & (1 << 0)) || (vEDI->mini_golf_flags & (1 << 2))) { @@ -8777,7 +8772,7 @@ loc_6DC476: if (vehicle->mini_golf_flags & (1 << 1)) { - regs.di = vehicle->IsChild() ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride; + regs.di = vehicle->IsHead() ? vehicle->next_vehicle_on_ride : vehicle->prev_vehicle_on_ride; rct_vehicle* vEDI = GET_VEHICLE(regs.di); if (!(vEDI->mini_golf_flags & (1 << 1)) || (vEDI->mini_golf_flags & (1 << 2))) { @@ -8802,7 +8797,7 @@ loc_6DC476: { break; } - if (!vEDI->IsChild()) + if (vEDI->IsHead()) continue; if (!(vEDI->mini_golf_flags & (1 << 4))) continue; @@ -8883,7 +8878,7 @@ loc_6DC476: vehicle->track_y = y; vehicle->track_z = z; - if (vehicle->IsChild()) + if (!vehicle->IsHead()) { rct_vehicle* prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); regs.al = prevVehicle->var_CD; @@ -8901,7 +8896,7 @@ loc_6DC476: loc_6DC743: vehicle->track_progress = regs.ax; - if (vehicle->IsChild()) + if (!vehicle->IsHead()) { vehicle->animation_frame++; if (vehicle->animation_frame >= 6) @@ -8920,7 +8915,7 @@ loc_6DC743: switch (moveInfo->y) { case 0: // loc_6DC7B4 - if (vehicle->IsChild()) + if (!vehicle->IsHead()) { vehicle->mini_golf_flags |= (1 << 3); } @@ -9802,7 +9797,7 @@ int32_t vehicle_update_track_motion(rct_vehicle* vehicle, int32_t* outStation) if (rideEntry->flags & RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND_SLIDE) { - if (!vehicle->IsChild()) + if (vehicle->IsHead()) { if (track_element_is_covered(vehicle->track_type >> 2)) { @@ -10011,9 +10006,14 @@ void vehicle_claxon(const rct_vehicle* vehicle) rct_vehicle* rct_vehicle::GetHead() { auto v = this; - while (v != nullptr && v->IsChild()) + while (v != nullptr && !v->IsHead()) { v = GET_VEHICLE(v->prev_vehicle_on_ride); } return v; } + +const rct_vehicle* rct_vehicle::GetHead() const +{ + return ((rct_vehicle*)this)->GetHead(); +} diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 909258dc28..69cee8379d 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -221,8 +221,9 @@ struct rct_vehicle : rct_sprite_common uint8_t seat_rotation; // 0xD8 uint8_t target_seat_rotation; // 0xD9 - constexpr bool IsChild() const { return type != 0; } + constexpr bool IsHead() const { return type == 0; } rct_vehicle* GetHead(); + const rct_vehicle* GetHead() const; }; struct train_ref diff --git a/src/openrct2/ride/water/SplashBoats.cpp b/src/openrct2/ride/water/SplashBoats.cpp index caa91f0d87..ddbf89e0e9 100644 --- a/src/openrct2/ride/water/SplashBoats.cpp +++ b/src/openrct2/ride/water/SplashBoats.cpp @@ -1250,13 +1250,13 @@ void vehicle_visual_splash_boats_or_water_coaster( paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const rct_vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicle->IsChild()) + if (vehicle->IsHead()) { - vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_ride); } else { - vehicle = GET_VEHICLE(vehicle->next_vehicle_on_ride); + vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); } session->CurrentlyDrawnItem = vehicle; imageDirection = ((session->CurrentRotation * 8) + vehicle->sprite_direction) & 0x1F; From a3af56f28584827c8447766649fe60735fdafed3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 25 Feb 2019 22:31:14 +0000 Subject: [PATCH 4/5] Fix formatting --- src/openrct2/peep/Peep.h | 2 +- src/openrct2/ride/Vehicle.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 8395315f3c..10a1bb140e 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -683,7 +683,7 @@ struct rct_peep : rct_sprite_common uint8_t hat_colour; // 0xF8 uint8_t favourite_ride; // 0xF9 uint8_t favourite_ride_rating; // 0xFA - uint32_t item_standard_flags; // 0xFC + uint32_t item_standard_flags; // 0xFC public: // Peep void Update(); diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index 69cee8379d..c56d827cb7 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -221,7 +221,10 @@ struct rct_vehicle : rct_sprite_common uint8_t seat_rotation; // 0xD8 uint8_t target_seat_rotation; // 0xD9 - constexpr bool IsHead() const { return type == 0; } + constexpr bool IsHead() const + { + return type == 0; + } rct_vehicle* GetHead(); const rct_vehicle* GetHead() const; }; From aa7d181070080d8e63f4c70b90fa8d0d16ccffb9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 26 Feb 2019 16:49:29 +0000 Subject: [PATCH 5/5] Define constants for vehicle type --- src/openrct2/ride/CableLift.cpp | 2 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/Vehicle.h | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 2610156087..3474ef89e2 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -39,7 +39,7 @@ rct_vehicle* cable_lift_segment_create( move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_TRAIN * 2); ride->cable_lift = current->sprite_index; } - current->type = head ? 0 : 1; + current->type = head ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL; current->var_44 = var_44; current->remaining_distance = remaining_distance; current->sprite_width = 10; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 39cc51a48c..9a117dde36 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4840,7 +4840,7 @@ static rct_vehicle* vehicle_create_car( vehicle->ride_subtype = ride->subtype; vehicle->vehicle_type = vehicleEntryIndex; - vehicle->type = carIndex == 0 ? 0 : 1; + vehicle->type = carIndex == 0 ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL; vehicle->var_44 = ror32(vehicleEntry->spacing, 10) & 0xFFFF; edx = vehicleEntry->spacing >> 1; *remainingDistance -= edx; diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index c56d827cb7..e82ab5a15e 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -105,6 +105,12 @@ static_assert(sizeof(rct_ride_entry_vehicle) % 4 == 0, "Invalid struct size"); static_assert(sizeof(rct_ride_entry_vehicle) % 8 == 0, "Invalid struct size"); #endif +enum VEHICLE_TYPE : uint8_t +{ + VEHICLE_TYPE_HEAD = 0, + VEHICLE_TYPE_TAIL = 1, +}; + struct rct_vehicle : rct_sprite_common { uint8_t vehicle_sprite_type; // 0x1F @@ -223,7 +229,7 @@ struct rct_vehicle : rct_sprite_common constexpr bool IsHead() const { - return type == 0; + return type == VEHICLE_TYPE_HEAD; } rct_vehicle* GetHead(); const rct_vehicle* GetHead() const;