1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Fixup the disjoint null sprites

This commit is contained in:
Michał Janiszewski
2017-07-07 00:12:54 +02:00
parent ab95988c66
commit 12500dd802
4 changed files with 57 additions and 0 deletions

View File

@@ -154,8 +154,14 @@ void S6Exporter::Export()
{
sint32 spatial_cycle = check_for_spatial_index_cycles(false);
sint32 regular_cycle = check_for_sprite_list_cycles(false);
sint32 disjoint_sprites_count = fix_disjoint_sprites();
openrct2_assert(spatial_cycle == -1, "Sprite cycle exists in spatial list %d", spatial_cycle);
openrct2_assert(regular_cycle == -1, "Sprite cycle exists in regular list %d", regular_cycle);
// This one is less harmful, no need to assert for it ~janisozaur
if (disjoint_sprites_count > 0)
{
log_error("Found %d disjoint null sprites", disjoint_sprites_count);
}
_s6.info = gS6Info;
uint32 researchedTrackPiecesA[128];
uint32 researchedTrackPiecesB[128];

View File

@@ -417,6 +417,12 @@ public:
// We try to fix the cycles on import, hence the 'true' parameter
check_for_sprite_list_cycles(true);
check_for_spatial_index_cycles(true);
sint32 disjoint_sprites_count = fix_disjoint_sprites();
// This one is less harmful, no need to assert for it ~janisozaur
if (disjoint_sprites_count > 0)
{
log_error("Found %d disjoint null sprites", disjoint_sprites_count);
}
}
void Initialise()

View File

@@ -951,6 +951,50 @@ sint32 check_for_sprite_list_cycles(bool fix)
return -1;
}
/**
* Finds and fixes null sprites that are not reachable via SPRITE_LIST_NULL list.
*
* @return count of disjoint sprites found
*/
sint32 fix_disjoint_sprites()
{
// Find reachable sprites
bool reachable[MAX_SPRITES] = {};
uint16 sprite_idx = gSpriteListHead[SPRITE_LIST_NULL];
rct_sprite * null_list_tail = NULL;
while (sprite_idx != SPRITE_INDEX_NULL)
{
reachable[sprite_idx] = true;
// cache the tail, so we don't have to walk the list twice
null_list_tail = get_sprite(sprite_idx);
sprite_idx = null_list_tail->unknown.next;
}
sint32 count = 0;
// Find all null sprites
for (sprite_idx = 0; sprite_idx < MAX_SPRITES; sprite_idx++)
{
rct_sprite * spr = get_sprite(sprite_idx);
if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_NULL)
{
openrct2_assert(null_list_tail != NULL, "Null list is empty, yet found null sprites");
spr->unknown.sprite_index = sprite_idx;
if (!reachable[sprite_idx])
{
// Add the sprite directly to the list
null_list_tail->unknown.next = sprite_idx;
spr->unknown.next = SPRITE_INDEX_NULL;
spr->unknown.previous = null_list_tail->unknown.sprite_index;
null_list_tail = spr;
count++;
reachable[sprite_idx] = true;
}
}
}
return count;
}
sint32 check_for_spatial_index_cycles(bool fix)
{
for (sint32 i = 0; i < SPATIAL_INDEX_LOCATION_NULL; i++) {

View File

@@ -479,5 +479,6 @@ void sprite_set_flashing(rct_sprite *sprite, bool flashing);
bool sprite_get_flashing(rct_sprite *sprite);
sint32 check_for_sprite_list_cycles(bool fix);
sint32 check_for_spatial_index_cycles(bool fix);
sint32 fix_disjoint_sprites();
#endif