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;
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);
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);
}
Peep* newPeep = &(create_sprite(GetFlags())->peep);
Peep* newPeep = &(create_sprite(SPRITE_IDENTIFIER_PEEP)->peep);
if (newPeep == nullptr)
{
// Too many peeps exist already.

View File

@ -751,7 +751,7 @@ uint32_t lightfx_get_light_polution()
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)
{
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)
return nullptr;
Peep* peep = (Peep*)create_sprite(1);
move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP);
Peep* peep = &create_sprite(SPRITE_IDENTIFIER_PEEP)->peep;
peep->sprite_identifier = SPRITE_IDENTIFIER_PEEP;
peep->sprite_type = PEEP_SPRITE_TYPE_NORMAL;
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->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;
Peep* peep = (Peep*)create_sprite(SPRITE_IDENTIFIER_PEEP);
move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP);
spriteIndexMap[i] = peep->sprite_index;
ImportPeep(peep, srcPeep);
@ -1678,8 +1677,6 @@ private:
const auto* srcLitter = &sprite.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->type = srcLitter->type;
@ -1705,8 +1702,6 @@ private:
{
rct1_unk_sprite* src = &sprite.unknown;
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->type = src->type;
dst->flags = src->flags;

View File

@ -31,13 +31,13 @@ rct_vehicle* cable_lift_segment_create(
bool head)
{
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->ride = rideIndex;
current->ride_subtype = RIDE_ENTRY_INDEX_NULL;
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;
}
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];
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->ride = rideIndex;
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;
// 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++)
{
if (ride->vehicles[i] == SPRITE_INDEX_NULL)

View File

@ -1255,7 +1255,7 @@ void vehicle_sounds_update()
vehicle_sounds_update_window_setup();
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);
}
@ -1338,7 +1338,7 @@ void vehicle_update_all()
if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) && gS6Info.editor_step != EDITOR_STEP_ROLLERCOASTER_DESIGNER)
return;
sprite_index = gSpriteListHead[SPRITE_LIST_TRAIN];
sprite_index = gSpriteListHead[SPRITE_LIST_VEHICLE_HEAD];
while (sprite_index != SPRITE_INDEX_NULL)
{
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 });
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)
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)
{
rct_sprite* sprite = create_sprite(2);
rct_sprite* sprite = create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr)
{
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)
{
rct_sprite* sprite = create_sprite(2);
rct_sprite* sprite = create_sprite(SPRITE_IDENTIFIER_MISC);
if (sprite != nullptr)
{
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))
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)
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)
{
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)
{
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)
{
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)
{
sprite->sprite_width = 33;

View File

@ -344,27 +344,51 @@ void sprite_clear_all_unused()
* rct2: 0x0069EC6B
* 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 ((bl & 2) != 0)
if (gSpriteListCount[SPRITE_LIST_FREE] == 0)
{
// 69EC96;
uint16_t cx = 0x12C - gSpriteListCount[SPRITE_LIST_MISC];
if (cx >= gSpriteListCount[SPRITE_LIST_FREE])
// No free sprites.
return nullptr;
}
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;
}
linkedListTypeOffset = SPRITE_LIST_MISC;
}
else if (gSpriteListCount[SPRITE_LIST_FREE] == 0)
{
return nullptr;
}
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
// 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)
{
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)
{
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)
{
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)
{
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)
return;
move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER);
litter->sprite_direction = direction;
litter->sprite_width = 6;
litter->sprite_height_negative = 6;
@ -787,9 +810,9 @@ static bool sprite_should_tween(rct_sprite* sprite)
{
switch (sprite->generic.linked_list_index)
{
case SPRITE_LIST_TRAIN:
case SPRITE_LIST_PEEP:
case SPRITE_LIST_UNKNOWN:
case SPRITE_LIST_VEHICLE_HEAD:
case SPRITE_LIST_VEHICLE:
return true;
}
return false;

View File

@ -32,11 +32,11 @@ enum SPRITE_IDENTIFIER
enum SPRITE_LIST
{
SPRITE_LIST_FREE,
SPRITE_LIST_TRAIN,
SPRITE_LIST_VEHICLE_HEAD,
SPRITE_LIST_PEEP,
SPRITE_LIST_MISC,
SPRITE_LIST_LITTER,
SPRITE_LIST_UNKNOWN,
SPRITE_LIST_VEHICLE,
};
struct rct_litter : rct_sprite_common
@ -195,7 +195,7 @@ extern uint16_t gSpriteSpatialIndex[0x10001];
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_spatial_index();
void sprite_clear_all_unused();