Merge pull request #8772 from IntelOrca/refactor/sprite-import-export-2

Refactor in-game sprite structs
This commit is contained in:
Michael Steenbeek 2019-02-27 13:29:13 +01:00 committed by GitHub
commit 6d3200aacc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 144 additions and 200 deletions

View File

@ -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();

View File

@ -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->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)

View File

@ -15,6 +15,7 @@
#include "../ride/Ride.h"
#include "../ride/RideTypes.h"
#include "../world/Location.hpp"
#include "../world/SpriteBase.h"
#include <bitset>
@ -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,8 +683,7 @@ 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
uint32_t item_standard_flags; // 0xFC
public: // Peep
void Update();
@ -850,8 +822,6 @@ private:
Ride* FindBestRideToGoOn();
std::bitset<MAX_RIDES> FindRidesToGoOn();
};
assert_struct_size(rct_peep, 0x100);
#pragma pack(pop)
struct rct_sprite_bounds
{

View File

@ -2549,7 +2549,7 @@ bool rct_peep::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride)
while (true)
{
if (vehicle->is_child == 0)
if (vehicle->IsHead())
{
break;
}

View File

@ -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->IsHead())
{
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;

View File

@ -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 ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL;
current->var_44 = var_44;
current->remaining_distance = remaining_distance;
current->sprite_width = 10;

View File

@ -4612,7 +4612,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 ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL;
vehicle->var_44 = ror32(vehicleEntry->spacing, 10) & 0xFFFF;
edx = vehicleEntry->spacing >> 1;
*remainingDistance -= edx;
@ -4713,7 +4713,7 @@ static rct_vehicle* vehicle_create_car(
}
if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_4)
{
if (!vehicle->is_child)
if (vehicle->IsHead())
{
dl = 15;
}

View File

@ -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->is_child != 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->is_child != 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)
{
@ -5286,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->is_child == 0)
if (vehicle->IsHead())
{
vehicle_kill_all_passengers(vehicle);
}
@ -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->is_child != 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)
{
@ -5343,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->is_child == 0)
if (vehicle->IsHead())
{
vehicle_kill_all_passengers(vehicle);
}
@ -6201,12 +6192,7 @@ void vehicle_set_map_toolbar(const rct_vehicle* vehicle)
int32_t vehicleIndex;
ride = get_ride(vehicle->ride);
while (vehicle->is_child)
{
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;
@ -7570,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->is_child)
if (vehicle->IsHead())
{
if (track_element_is_covered(trackType))
{
@ -7597,7 +7583,7 @@ static void vehicle_update_handle_water_splash(rct_vehicle* vehicle)
}
}
}
if (!vehicle->is_child)
if (vehicle->IsHead())
{
if (trackType == TRACK_ELEM_WATER_SPLASH)
{
@ -8037,7 +8023,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->IsHead() && vehicle->velocity <= 0x30000)
{
vehicle->velocity = 0;
}
@ -8201,7 +8187,7 @@ loc_6DAEB9:
}
if (trackType == TRACK_ELEM_BRAKE_FOR_DROP)
{
if (!vehicle->is_child)
if (vehicle->IsHead())
{
if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP))
{
@ -8770,7 +8756,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->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)))
{
@ -8786,7 +8772,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->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)))
{
@ -8811,7 +8797,7 @@ loc_6DC476:
{
break;
}
if (!vEDI->is_child)
if (vEDI->IsHead())
continue;
if (!(vEDI->mini_golf_flags & (1 << 4)))
continue;
@ -8892,7 +8878,7 @@ loc_6DC476:
vehicle->track_y = y;
vehicle->track_z = z;
if (vehicle->is_child)
if (!vehicle->IsHead())
{
rct_vehicle* prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
regs.al = prevVehicle->var_CD;
@ -8910,7 +8896,7 @@ loc_6DC476:
loc_6DC743:
vehicle->track_progress = regs.ax;
if (vehicle->is_child)
if (!vehicle->IsHead())
{
vehicle->animation_frame++;
if (vehicle->animation_frame >= 6)
@ -8929,7 +8915,7 @@ loc_6DC743:
switch (moveInfo->y)
{
case 0: // loc_6DC7B4
if (vehicle->is_child)
if (!vehicle->IsHead())
{
vehicle->mini_golf_flags |= (1 << 3);
}
@ -9811,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->is_child)
if (vehicle->IsHead())
{
if (track_element_is_covered(vehicle->track_type >> 2))
{
@ -10016,3 +10002,18 @@ void vehicle_claxon(const rct_vehicle* vehicle)
break;
}
}
rct_vehicle* rct_vehicle::GetHead()
{
auto v = this;
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();
}

View File

@ -13,6 +13,7 @@
#include "../common.h"
#include "../ride/RideTypes.h"
#include "../world/Location.hpp"
#include "../world/SpriteBase.h"
#include <array>
#include <cstddef>
@ -104,39 +105,22 @@ 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
enum VEHICLE_TYPE : uint8_t
{
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
VEHICLE_TYPE_HEAD = 0,
VEHICLE_TYPE_TAIL = 1,
};
struct rct_vehicle : rct_sprite_common
{
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 +226,13 @@ struct rct_vehicle
uint8_t colours_extended; // 0xD7
uint8_t seat_rotation; // 0xD8
uint8_t target_seat_rotation; // 0xD9
constexpr bool IsHead() const
{
return type == VEHICLE_TYPE_HEAD;
}
rct_vehicle* GetHead();
const rct_vehicle* GetHead() const;
};
struct train_ref

View File

@ -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->is_child)
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;

View File

@ -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;

View File

@ -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

View File

@ -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;
};