Refactor create_sprite and remove unnecessary move_sprite_to_list

This commit is contained in:
Matt 2019-06-19 17:10:57 +02:00
parent 837879018f
commit 98a17fe8d9
No known key found for this signature in database
GPG Key ID: 6D4C24A61C93E208
14 changed files with 61 additions and 46 deletions

View File

@ -1097,7 +1097,7 @@ static void window_map_paint_train_overlay(rct_drawpixelinfo* dpi)
rct_vehicle *train, *vehicle; rct_vehicle *train, *vehicle;
uint16_t train_index, vehicle_index; uint16_t train_index, vehicle_index;
for (train_index = gSpriteListHead[SPRITE_LIST_TRAIN]; train_index != SPRITE_INDEX_NULL; train_index = train->next) for (train_index = gSpriteListHead[SPRITE_LIST_VEHICLE_HEAD]; train_index != SPRITE_INDEX_NULL; train_index = train->next)
{ {
train = GET_VEHICLE(train_index); train = GET_VEHICLE(train_index);
for (vehicle_index = train_index; vehicle_index != SPRITE_INDEX_NULL; vehicle_index = vehicle->next_vehicle_on_train) for (vehicle_index = train_index; vehicle_index != SPRITE_INDEX_NULL; vehicle_index = vehicle->next_vehicle_on_train)

View File

@ -150,7 +150,7 @@ private:
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_STAFF_IN_GAME); return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_STAFF_IN_GAME);
} }
Peep* newPeep = &(create_sprite(GetFlags())->peep); Peep* newPeep = &(create_sprite(SPRITE_IDENTIFIER_PEEP)->peep);
if (newPeep == nullptr) if (newPeep == nullptr)
{ {
// Too many peeps exist already. // Too many peeps exist already.

View File

@ -751,7 +751,7 @@ uint32_t lightfx_get_light_polution()
void lightfx_add_lights_magic_vehicles() void lightfx_add_lights_magic_vehicles()
{ {
uint16_t spriteIndex = gSpriteListHead[SPRITE_LIST_TRAIN]; uint16_t spriteIndex = gSpriteListHead[SPRITE_LIST_VEHICLE_HEAD];
while (spriteIndex != SPRITE_INDEX_NULL) while (spriteIndex != SPRITE_INDEX_NULL)
{ {
rct_vehicle* vehicle = &(get_sprite(spriteIndex)->vehicle); rct_vehicle* vehicle = &(get_sprite(spriteIndex)->vehicle);

View File

@ -1640,10 +1640,7 @@ Peep* Peep::Generate(const CoordsXYZ coords)
if (gSpriteListCount[SPRITE_LIST_FREE] < 400) if (gSpriteListCount[SPRITE_LIST_FREE] < 400)
return nullptr; return nullptr;
Peep* peep = (Peep*)create_sprite(1); Peep* peep = &create_sprite(SPRITE_IDENTIFIER_PEEP)->peep;
move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP);
peep->sprite_identifier = SPRITE_IDENTIFIER_PEEP; peep->sprite_identifier = SPRITE_IDENTIFIER_PEEP;
peep->sprite_type = PEEP_SPRITE_TYPE_NORMAL; peep->sprite_type = PEEP_SPRITE_TYPE_NORMAL;
peep->outside_of_park = 1; peep->outside_of_park = 1;

View File

@ -1165,7 +1165,7 @@ private:
// If vehicle is the first car on a train add to train list // If vehicle is the first car on a train add to train list
if (vehicle->IsHead()) if (vehicle->IsHead())
{ {
move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_TRAIN); move_sprite_to_list((rct_sprite*)vehicle, SPRITE_LIST_VEHICLE_HEAD);
} }
} }
} }
@ -1362,7 +1362,6 @@ private:
{ {
rct1_peep* srcPeep = &_s4.sprites[i].peep; rct1_peep* srcPeep = &_s4.sprites[i].peep;
Peep* peep = (Peep*)create_sprite(SPRITE_IDENTIFIER_PEEP); Peep* peep = (Peep*)create_sprite(SPRITE_IDENTIFIER_PEEP);
move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP);
spriteIndexMap[i] = peep->sprite_index; spriteIndexMap[i] = peep->sprite_index;
ImportPeep(peep, srcPeep); ImportPeep(peep, srcPeep);
@ -1678,8 +1677,6 @@ private:
const auto* srcLitter = &sprite.litter; const auto* srcLitter = &sprite.litter;
rct_litter* litter = (rct_litter*)create_sprite(SPRITE_IDENTIFIER_LITTER); rct_litter* litter = (rct_litter*)create_sprite(SPRITE_IDENTIFIER_LITTER);
move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER);
litter->sprite_identifier = srcLitter->sprite_identifier; litter->sprite_identifier = srcLitter->sprite_identifier;
litter->type = srcLitter->type; litter->type = srcLitter->type;
@ -1705,8 +1702,6 @@ private:
{ {
rct1_unk_sprite* src = &sprite.unknown; rct1_unk_sprite* src = &sprite.unknown;
rct_sprite_generic* dst = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC); rct_sprite_generic* dst = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC);
move_sprite_to_list((rct_sprite*)dst, SPRITE_LIST_MISC);
dst->sprite_identifier = src->sprite_identifier; dst->sprite_identifier = src->sprite_identifier;
dst->type = src->type; dst->type = src->type;
dst->flags = src->flags; dst->flags = src->flags;

View File

@ -31,13 +31,13 @@ rct_vehicle* cable_lift_segment_create(
bool head) bool head)
{ {
Ride* ride = get_ride(rideIndex); Ride* ride = get_ride(rideIndex);
rct_vehicle* current = &(create_sprite(1)->vehicle); rct_vehicle* current = &(create_sprite(SPRITE_IDENTIFIER_VEHICLE)->vehicle);
current->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE; current->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE;
current->ride = rideIndex; current->ride = rideIndex;
current->ride_subtype = RIDE_ENTRY_INDEX_NULL; current->ride_subtype = RIDE_ENTRY_INDEX_NULL;
if (head) if (head)
{ {
move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_TRAIN); move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_VEHICLE_HEAD);
ride->cable_lift = current->sprite_index; ride->cable_lift = current->sprite_index;
} }
current->type = head ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL; current->type = head ? VEHICLE_TYPE_HEAD : VEHICLE_TYPE_TAIL;

View File

@ -4482,7 +4482,7 @@ static rct_vehicle* vehicle_create_car(
rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[vehicleEntryIndex]; rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[vehicleEntryIndex];
int32_t edx; int32_t edx;
rct_vehicle* vehicle = (rct_vehicle*)create_sprite(1); rct_vehicle* vehicle = &create_sprite(SPRITE_IDENTIFIER_VEHICLE)->vehicle;
vehicle->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE; vehicle->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE;
vehicle->ride = rideIndex; vehicle->ride = rideIndex;
vehicle->ride_subtype = ride->subtype; vehicle->ride_subtype = ride->subtype;
@ -4721,7 +4721,7 @@ static void vehicle_create_trains(ride_id_t rideIndex, int32_t x, int32_t y, int
lastTrain = train; lastTrain = train;
// Add train to ride vehicle list // Add train to ride vehicle list
move_sprite_to_list((rct_sprite*)train.head, SPRITE_LIST_TRAIN); move_sprite_to_list((rct_sprite*)train.head, SPRITE_LIST_VEHICLE_HEAD);
for (int32_t i = 0; i < MAX_VEHICLES_PER_RIDE; i++) for (int32_t i = 0; i < MAX_VEHICLES_PER_RIDE; i++)
{ {
if (ride->vehicles[i] == SPRITE_INDEX_NULL) if (ride->vehicles[i] == SPRITE_INDEX_NULL)

View File

@ -1255,7 +1255,7 @@ void vehicle_sounds_update()
vehicle_sounds_update_window_setup(); vehicle_sounds_update_window_setup();
gVehicleSoundParamsListEnd = &gVehicleSoundParamsList[0]; gVehicleSoundParamsListEnd = &gVehicleSoundParamsList[0];
for (uint16_t i = gSpriteListHead[SPRITE_LIST_TRAIN]; i != SPRITE_INDEX_NULL; i = get_sprite(i)->vehicle.next) for (uint16_t i = gSpriteListHead[SPRITE_LIST_VEHICLE_HEAD]; i != SPRITE_INDEX_NULL; i = get_sprite(i)->vehicle.next)
{ {
vehicle_update_sound_params(&get_sprite(i)->vehicle); vehicle_update_sound_params(&get_sprite(i)->vehicle);
} }
@ -1338,7 +1338,7 @@ void vehicle_update_all()
if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) && gS6Info.editor_step != EDITOR_STEP_ROLLERCOASTER_DESIGNER) if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) && gS6Info.editor_step != EDITOR_STEP_ROLLERCOASTER_DESIGNER)
return; return;
sprite_index = gSpriteListHead[SPRITE_LIST_TRAIN]; sprite_index = gSpriteListHead[SPRITE_LIST_VEHICLE_HEAD];
while (sprite_index != SPRITE_INDEX_NULL) while (sprite_index != SPRITE_INDEX_NULL)
{ {
vehicle = GET_VEHICLE(sprite_index); vehicle = GET_VEHICLE(sprite_index);
@ -7153,7 +7153,7 @@ static void steam_particle_create(int16_t x, int16_t y, int16_t z)
TileElement* tileElement = map_get_surface_element_at({ x, y }); TileElement* tileElement = map_get_surface_element_at({ x, y });
if (tileElement != nullptr && z > tileElement->base_height * 8) if (tileElement != nullptr && z > tileElement->base_height * 8)
{ {
rct_steam_particle* steam = (rct_steam_particle*)create_sprite(2); rct_steam_particle* steam = (rct_steam_particle*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (steam == nullptr) if (steam == nullptr)
return; return;

View File

@ -86,7 +86,7 @@ void rct_balloon::Pop()
void create_balloon(int32_t x, int32_t y, int32_t z, int32_t colour, bool isPopped) void create_balloon(int32_t x, int32_t y, int32_t z, int32_t colour, bool isPopped)
{ {
rct_sprite* sprite = create_sprite(2); rct_sprite* sprite = create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->balloon.sprite_width = 13; sprite->balloon.sprite_width = 13;

View File

@ -307,7 +307,7 @@ uint32_t rct_duck::GetFrameImage(int32_t direction) const
void create_duck(int32_t targetX, int32_t targetY) void create_duck(int32_t targetX, int32_t targetY)
{ {
rct_sprite* sprite = create_sprite(2); rct_sprite* sprite = create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->duck.sprite_identifier = SPRITE_IDENTIFIER_MISC; sprite->duck.sprite_identifier = SPRITE_IDENTIFIER_MISC;

View File

@ -43,7 +43,7 @@ void rct_money_effect::CreateAt(money32 value, int32_t x, int32_t y, int32_t z,
if (value == MONEY(0, 00)) if (value == MONEY(0, 00))
return; return;
rct_money_effect* moneyEffect = (rct_money_effect*)create_sprite(2); rct_money_effect* moneyEffect = (rct_money_effect*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (moneyEffect == nullptr) if (moneyEffect == nullptr)
return; return;

View File

@ -20,7 +20,7 @@
*/ */
void crashed_vehicle_particle_create(rct_vehicle_colour colours, int32_t x, int32_t y, int32_t z) void crashed_vehicle_particle_create(rct_vehicle_colour colours, int32_t x, int32_t y, int32_t z)
{ {
rct_crashed_vehicle_particle* sprite = (rct_crashed_vehicle_particle*)create_sprite(2); rct_crashed_vehicle_particle* sprite = (rct_crashed_vehicle_particle*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->colour[0] = colours.body_colour; sprite->colour[0] = colours.body_colour;
@ -114,7 +114,7 @@ void crashed_vehicle_particle_update(rct_crashed_vehicle_particle* particle)
*/ */
void crash_splash_create(int32_t x, int32_t y, int32_t z) void crash_splash_create(int32_t x, int32_t y, int32_t z)
{ {
rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(2); rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->sprite_width = 33; sprite->sprite_width = 33;

View File

@ -344,27 +344,51 @@ void sprite_clear_all_unused()
* rct2: 0x0069EC6B * rct2: 0x0069EC6B
* bl: if bl & 2 > 0, the sprite ends up in the MISC linked list. * bl: if bl & 2 > 0, the sprite ends up in the MISC linked list.
*/ */
rct_sprite* create_sprite(uint8_t bl) static constexpr uint16_t MAX_MISC_SPRITES = 300;
rct_sprite* create_sprite(SPRITE_IDENTIFIER spriteIdentifier)
{ {
SPRITE_LIST linkedListTypeOffset = SPRITE_LIST_UNKNOWN; if (gSpriteListCount[SPRITE_LIST_FREE] == 0)
if ((bl & 2) != 0)
{ {
// 69EC96; // No free sprites.
uint16_t cx = 0x12C - gSpriteListCount[SPRITE_LIST_MISC]; return nullptr;
if (cx >= gSpriteListCount[SPRITE_LIST_FREE]) }
SPRITE_LIST linkedListIndex;
switch (spriteIdentifier)
{
case SPRITE_IDENTIFIER_VEHICLE:
linkedListIndex = SPRITE_LIST_VEHICLE;
break;
case SPRITE_IDENTIFIER_PEEP:
linkedListIndex = SPRITE_LIST_PEEP;
break;
case SPRITE_IDENTIFIER_MISC:
linkedListIndex = SPRITE_LIST_MISC;
break;
case SPRITE_IDENTIFIER_LITTER:
linkedListIndex = SPRITE_LIST_LITTER;
break;
default:
Guard::Assert(false, "Invalid sprite identifier: 0x%02X", spriteIdentifier);
return nullptr;
}
if (linkedListIndex == SPRITE_LIST_MISC)
{
// Misc sprites are commonly used for effects, if there are less than MAX_MISC_SPRITES
// free it will fail to keep slots for more relevant sprites.
// Also there can't be more than MAX_MISC_SPRITES sprites in this list.
uint16_t miscSlotsRemaining = MAX_MISC_SPRITES - gSpriteListCount[SPRITE_LIST_MISC];
if (miscSlotsRemaining >= gSpriteListCount[SPRITE_LIST_FREE])
{ {
return nullptr; return nullptr;
} }
linkedListTypeOffset = SPRITE_LIST_MISC;
}
else if (gSpriteListCount[SPRITE_LIST_FREE] == 0)
{
return nullptr;
} }
rct_sprite_generic* sprite = &(get_sprite(gSpriteListHead[SPRITE_LIST_FREE]))->generic; rct_sprite_generic* sprite = &(get_sprite(gSpriteListHead[SPRITE_LIST_FREE]))->generic;
move_sprite_to_list((rct_sprite*)sprite, linkedListTypeOffset); move_sprite_to_list((rct_sprite*)sprite, linkedListIndex);
// Need to reset all sprite data, as the uninitialised values // Need to reset all sprite data, as the uninitialised values
// may contain garbage and cause a desync later on. // may contain garbage and cause a desync later on.
@ -465,7 +489,7 @@ static void sprite_steam_particle_update(rct_steam_particle* steam)
*/ */
void sprite_misc_explosion_cloud_create(int32_t x, int32_t y, int32_t z) void sprite_misc_explosion_cloud_create(int32_t x, int32_t y, int32_t z)
{ {
rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(2); rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->sprite_width = 44; sprite->sprite_width = 44;
@ -498,7 +522,7 @@ static void sprite_misc_explosion_cloud_update(rct_sprite* sprite)
*/ */
void sprite_misc_explosion_flare_create(int32_t x, int32_t y, int32_t z) void sprite_misc_explosion_flare_create(int32_t x, int32_t y, int32_t z)
{ {
rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(2); rct_sprite_generic* sprite = (rct_sprite_generic*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr) if (sprite != nullptr)
{ {
sprite->sprite_width = 25; sprite->sprite_width = 25;
@ -736,11 +760,10 @@ void litter_create(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t t
} }
} }
rct_litter* litter = (rct_litter*)create_sprite(1); rct_litter* litter = (rct_litter*)create_sprite(SPRITE_IDENTIFIER_LITTER);
if (litter == nullptr) if (litter == nullptr)
return; return;
move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER);
litter->sprite_direction = direction; litter->sprite_direction = direction;
litter->sprite_width = 6; litter->sprite_width = 6;
litter->sprite_height_negative = 6; litter->sprite_height_negative = 6;
@ -787,9 +810,9 @@ static bool sprite_should_tween(rct_sprite* sprite)
{ {
switch (sprite->generic.linked_list_index) switch (sprite->generic.linked_list_index)
{ {
case SPRITE_LIST_TRAIN:
case SPRITE_LIST_PEEP: case SPRITE_LIST_PEEP:
case SPRITE_LIST_UNKNOWN: case SPRITE_LIST_VEHICLE_HEAD:
case SPRITE_LIST_VEHICLE:
return true; return true;
} }
return false; return false;

View File

@ -32,11 +32,11 @@ enum SPRITE_IDENTIFIER
enum SPRITE_LIST enum SPRITE_LIST
{ {
SPRITE_LIST_FREE, SPRITE_LIST_FREE,
SPRITE_LIST_TRAIN, SPRITE_LIST_VEHICLE_HEAD,
SPRITE_LIST_PEEP, SPRITE_LIST_PEEP,
SPRITE_LIST_MISC, SPRITE_LIST_MISC,
SPRITE_LIST_LITTER, SPRITE_LIST_LITTER,
SPRITE_LIST_UNKNOWN, SPRITE_LIST_VEHICLE,
}; };
struct rct_litter : rct_sprite_common struct rct_litter : rct_sprite_common
@ -195,7 +195,7 @@ extern uint16_t gSpriteSpatialIndex[0x10001];
extern const rct_string_id litterNames[12]; extern const rct_string_id litterNames[12];
rct_sprite* create_sprite(uint8_t bl); rct_sprite* create_sprite(SPRITE_IDENTIFIER spriteIdentifier);
void reset_sprite_list(); void reset_sprite_list();
void reset_sprite_spatial_index(); void reset_sprite_spatial_index();
void sprite_clear_all_unused(); void sprite_clear_all_unused();