From d2c5501eeae36be7808f6dabad45764693d45a5d Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 9 May 2016 00:08:03 +0100 Subject: [PATCH] refactor sprite heads and counts --- src/addresses.h | 13 +--- src/cheats.c | 4 +- src/game.c | 7 +- src/openrct2.c | 11 ++- src/peep/peep.c | 25 ++++--- src/peep/peep.h | 2 +- src/peep/staff.c | 8 +- src/rct2/S6Exporter.cpp | 17 ++--- src/rct2/S6Importer.cpp | 17 ++--- src/ride/cable_lift.c | 2 +- src/ride/ride.c | 10 +-- src/ride/vehicle.c | 4 +- src/scenario.h | 14 +--- src/windows/editor_bottom_toolbar.c | 7 +- src/windows/map.c | 2 +- src/world/duck.c | 2 +- src/world/footpath.c | 4 +- src/world/map_animation.c | 2 +- src/world/park.c | 2 +- src/world/sprite.c | 111 ++++++++++++++-------------- src/world/sprite.h | 27 ++++--- 21 files changed, 131 insertions(+), 160 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 9a1e366171..7fcc2723fd 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -276,17 +276,8 @@ #define RCT2_ADDRESS_MAP_ELEMENTS_END 0x010E53B8 #define RCT2_ADDRESS_SPRITE_LIST 0x010E63BC -#define RCT2_ADDRESS_SPRITES_NEXT_INDEX 0x013573BC -#define RCT2_ADDRESS_SPRITES_START_VEHICLE 0x013573BE -#define RCT2_ADDRESS_SPRITES_START_PEEP 0x013573C0 -#define RCT2_ADDRESS_SPRITES_START_MISC 0x013573C2 -#define RCT2_ADDRESS_SPRITES_START_LITTER 0x013573C4 - -#define RCT2_ADDRESS_SPRITES_COUNT_VEHICLE 0x013573CA -#define RCT2_ADDRESS_SPRITES_COUNT_PEEP 0x013573CC -#define RCT2_ADDRESS_SPRITES_COUNT_MISC 0x013573CE -#define RCT2_ADDRESS_SPRITES_COUNT_LITTER 0x013573D0 - +#define RCT2_ADDRESS_SPRITE_LISTS_HEAD 0x013573BC +#define RCT2_ADDRESS_SPRITE_LISTS_COUNT 0x013573C8 #define RCT2_ADDRESS_PARK_NAME 0x013573D4 #define RCT2_ADDRESS_PARK_NAME_ARGS 0x013573D8 #define RCT2_ADDRESS_INITIAL_CASH 0x013573DC diff --git a/src/cheats.c b/src/cheats.c index 43cd09bc79..ea983c47e2 100644 --- a/src/cheats.c +++ b/src/cheats.c @@ -107,7 +107,7 @@ static void cheat_remove_litter() rct_litter* litter; uint16 spriteIndex, nextSpriteIndex; - for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { + for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { litter = &(g_sprite_list[spriteIndex].litter); nextSpriteIndex = litter->next; sprite_remove((rct_sprite*)litter); @@ -318,7 +318,7 @@ static void cheat_remove_all_guests() rct_peep *peep; uint16 spriteIndex, nextSpriteIndex; - for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { + for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { peep = &(g_sprite_list[spriteIndex].peep); nextSpriteIndex = peep->next; if (peep->type == PEEP_TYPE_GUEST) { diff --git a/src/game.c b/src/game.c index b0434c7efb..b73922eff6 100644 --- a/src/game.c +++ b/src/game.c @@ -869,9 +869,12 @@ void game_load_init() */ void reset_all_sprite_quadrant_placements() { - for (rct_sprite* spr = g_sprite_list; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; spr++) - if (spr->unknown.sprite_identifier != 0xFF) + for (size_t i = 0; i < MAX_SPRITES; i++) { + rct_sprite *spr = &g_sprite_list[i]; + if (spr->unknown.sprite_identifier != SPRITE_IDENTIFIER_NULL) { sprite_move(spr->unknown.x, spr->unknown.y, spr->unknown.z, spr); + } + } } void save_game() diff --git a/src/openrct2.c b/src/openrct2.c index 2137ac24bc..21bad9ecb4 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -340,13 +340,12 @@ void openrct2_dispose() */ static bool sprite_should_tween(rct_sprite *sprite) { - if (sprite->unknown.linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_VEHICLE) + switch (sprite->unknown.linked_list_type_offset >> 1) { + case SPRITE_LIST_VEHICLE: + case SPRITE_LIST_PEEP: + case SPRITE_LIST_UNKNOWN: return true; - if (sprite->unknown.linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP) - return true; - if (sprite->unknown.linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_UNKNOWN) - return true; - + } return false; } diff --git a/src/peep/peep.c b/src/peep/peep.c index 86c69610fc..36e87d0ab9 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -168,7 +168,7 @@ void peep_update_all() if (gScreenFlags & 0x0E) return; - spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); + spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; i = 0; while (spriteIndex != SPRITE_INDEX_NULL) { peep = &(g_sprite_list[spriteIndex].peep); @@ -178,8 +178,9 @@ void peep_update_all() peep_update(peep); } else { sub_68F41A(peep, i); - if (peep->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP) + if (peep->linked_list_type_offset == SPRITE_LIST_PEEP * 2) { peep_update(peep); + } } i++; @@ -260,7 +261,7 @@ static uint8 peep_assess_surroundings(sint16 center_x, sint16 center_y, sint16 c } rct_litter* litter; - for (uint16 sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = litter->next) { + for (uint16 sprite_idx = gSpriteListHead[SPRITE_LIST_LITTER]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = litter->next) { litter = &(g_sprite_list[sprite_idx].litter); sint16 dist_x = abs(litter->x - center_x); @@ -4537,7 +4538,7 @@ static int peep_update_walking_find_bench(rct_peep* peep){ for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.next_in_quadrant){ sprite = &g_sprite_list[sprite_id]; - if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP)continue; + if (sprite->unknown.linked_list_type_offset != SPRITE_LIST_PEEP * 2) continue; if (sprite->peep.state != PEEP_STATE_SITTING)continue; @@ -5323,7 +5324,7 @@ static int peep_update_patrolling_find_sweeping(rct_peep* peep){ sprite = &g_sprite_list[sprite_id]; - if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_LITTER)continue; + if (sprite->unknown.linked_list_type_offset != SPRITE_LIST_LITTER * 2) continue; uint16 z_diff = abs(peep->z - sprite->litter.z); @@ -5565,7 +5566,7 @@ static void peep_update_walking(rct_peep* peep){ for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.next_in_quadrant){ sprite = &g_sprite_list[sprite_id]; - if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP)continue; + if (sprite->unknown.linked_list_type_offset != SPRITE_LIST_PEEP * 2) continue; if (sprite->peep.state != PEEP_STATE_WATCHING)continue; @@ -6051,12 +6052,12 @@ void peep_update_days_in_queue() */ rct_peep *peep_generate(int x, int y, int z) { - if (RCT2_GLOBAL(0x13573C8, uint16) < 400) + if (gSpriteListCount[SPRITE_LIST_NULL] < 400) return NULL; rct_peep* peep = (rct_peep*)create_sprite(1); - move_sprite_to_list((rct_sprite*)peep, SPRITE_LINKEDLIST_OFFSET_PEEP); + move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP * 2); peep->sprite_identifier = 1; peep->sprite_type = PEEP_SPRITE_TYPE_NORMAL; @@ -10316,7 +10317,7 @@ void peep_update_name_sort(rct_peep *peep) rct_peep *prevPeep = GET_PEEP(prevSpriteIndex); prevPeep->next = nextSpriteIndex; } else { - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16) = nextSpriteIndex; + gSpriteListHead[SPRITE_LIST_PEEP] = nextSpriteIndex; } if (nextSpriteIndex != SPRITE_INDEX_NULL) { @@ -10350,8 +10351,8 @@ void peep_update_name_sort(rct_peep *peep) peep->next = prevPeep->next; prevPeep->next = peep->sprite_index; } else { - peep->next = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16) = peep->sprite_index; + peep->next = gSpriteListHead[SPRITE_LIST_PEEP]; + gSpriteListHead[SPRITE_LIST_PEEP] = peep->sprite_index; } goto finish_peep_sort; } @@ -10366,7 +10367,7 @@ void peep_update_name_sort(rct_peep *peep) } } - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16) = peep->sprite_index; + gSpriteListHead[SPRITE_LIST_PEEP] = peep->sprite_index; peep->next = SPRITE_INDEX_NULL; peep->previous = SPRITE_INDEX_NULL; diff --git a/src/peep/peep.h b/src/peep/peep.h index 159bce7909..11920001c3 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -584,7 +584,7 @@ enum { * applied in tautology if statements. */ #define FOR_ALL_PEEPS(sprite_index, peep) \ - for (sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next) \ + for (sprite_index = gSpriteListHead[SPRITE_LIST_PEEP]; sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next) \ if ((peep = GET_PEEP(sprite_index)) || 1) #define FOR_ALL_GUESTS(sprite_index, peep) \ diff --git a/src/peep/staff.c b/src/peep/staff.c index fda4553eac..680fe7ca78 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -88,7 +88,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, gCommandPosition.y = _cx; gCommandPosition.z = _dx; - if (RCT2_GLOBAL(0x13573C8, uint16) < 0x190) { + if (gSpriteListCount[SPRITE_LIST_NULL] < 400) { *ebx = MONEY32_UNDEFINED; gGameCommandErrorText = STR_TOO_MANY_PEOPLE_IN_GAME; return; @@ -124,7 +124,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, if (_bl == 0) { sprite_remove((rct_sprite*)newPeep); } else { - move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); + move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LIST_PEEP * 2); newPeep->sprite_identifier = 1; newPeep->window_invalidate_flags = 0; @@ -445,7 +445,7 @@ void staff_update_greyed_patrol_areas() for (int i = 0; i < 128; ++i) RCT2_ADDRESS(RCT2_ADDRESS_STAFF_PATROL_AREAS + ((staff_type + STAFF_MAX_COUNT) * 512), uint32)[i] = 0; - for (uint16 sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next) + for (uint16 sprite_index = gSpriteListHead[SPRITE_LIST_PEEP]; sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next) { peep = GET_PEEP(sprite_index); @@ -567,7 +567,7 @@ static uint8 staff_handyman_direction_to_nearest_litter(rct_peep* peep){ rct_litter* nearestLitter = NULL; rct_litter* litter = NULL; - for(uint16 litterIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); litterIndex != 0xFFFF; litterIndex = litter->next){ + for (uint16 litterIndex = gSpriteListHead[SPRITE_LIST_LITTER]; litterIndex != 0xFFFF; litterIndex = litter->next){ litter = &g_sprite_list[litterIndex].litter; uint16 distance = diff --git a/src/rct2/S6Exporter.cpp b/src/rct2/S6Exporter.cpp index 29b137485f..6db7bd215d 100644 --- a/src/rct2/S6Exporter.cpp +++ b/src/rct2/S6Exporter.cpp @@ -253,18 +253,11 @@ void S6Exporter::Export() _s6.dword_010E63B8 = RCT2_GLOBAL(0x0010E63B8, uint32); memcpy(_s6.sprites, g_sprite_list, sizeof(_s6.sprites)); - _s6.sprites_next_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16); - _s6.sprites_start_vehicle = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); - _s6.sprites_start_peep = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - _s6.sprites_start_textfx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_MISC, uint16); - _s6.sprites_start_litter = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); - // pad_013573C6 - _s6.word_013573C8 = RCT2_GLOBAL(0x13573C8, uint16); - _s6.sprites_next_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_VEHICLE, uint16); - _s6.sprites_count_peep = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_PEEP, uint16); - _s6.sprites_count_misc = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_MISC, uint16); - _s6.sprites_count_litter = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_LITTER, uint16); - // pad_013573D2 + for (int i = 0; i < NUM_SPRITE_LISTS; i++) + { + _s6.sprite_lists_head[i] = gSpriteListHead[i]; + _s6.sprite_lists_count[i] = gSpriteListCount[i]; + } _s6.park_name = gParkName; // pad_013573D6 _s6.park_name_args = gParkNameArgs; diff --git a/src/rct2/S6Importer.cpp b/src/rct2/S6Importer.cpp index 6cba83d28d..4a884a37e1 100644 --- a/src/rct2/S6Importer.cpp +++ b/src/rct2/S6Importer.cpp @@ -185,18 +185,11 @@ void S6Importer::Import() RCT2_GLOBAL(0x0010E63B8, uint32) = _s6.dword_010E63B8; memcpy(g_sprite_list, _s6.sprites, sizeof(_s6.sprites)); - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16) = _s6.sprites_next_index; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16) = _s6.sprites_start_vehicle; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16) = _s6.sprites_start_peep; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_MISC, uint16) = _s6.sprites_start_textfx; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16) = _s6.sprites_start_litter; - // pad_013573C6 - RCT2_GLOBAL(0x13573C8, uint16) = _s6.word_013573C8; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_VEHICLE, uint16) = _s6.sprites_next_index; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_PEEP, uint16) = _s6.sprites_count_peep; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_MISC, uint16) = _s6.sprites_count_misc; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_LITTER, uint16) = _s6.sprites_count_litter; - // pad_013573D2 + for (int i = 0; i < NUM_SPRITE_LISTS; i++) + { + gSpriteListHead[i] = _s6.sprite_lists_head[i]; + gSpriteListCount[i] = _s6.sprite_lists_count[i]; + } gParkName = _s6.park_name; // pad_013573D6 gParkNameArgs = _s6.park_name_args; diff --git a/src/ride/cable_lift.c b/src/ride/cable_lift.c index 94f8aafb58..522cba8c2f 100644 --- a/src/ride/cable_lift.c +++ b/src/ride/cable_lift.c @@ -34,7 +34,7 @@ rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int d current->ride = rideIndex; current->ride_subtype = 0xFF; if (head) { - move_sprite_to_list((rct_sprite*)current, SPRITE_LINKEDLIST_OFFSET_VEHICLE); + move_sprite_to_list((rct_sprite*)current, SPRITE_LIST_VEHICLE * 2); ride->cable_lift = current->sprite_index; } current->is_child = head ? 0 : 1; diff --git a/src/ride/ride.c b/src/ride/ride.c index d30f9f3288..8bca60adbd 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -303,7 +303,7 @@ void ride_update_favourited_stat() ride->guests_favourite = 0; FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP) + if (peep->linked_list_type_offset != SPRITE_LIST_PEEP * 2) return; if (peep->favourite_ride != 0xff) { ride = &gRideList[peep->favourite_ride]; @@ -4376,9 +4376,9 @@ void ride_set_start_finish_points(int rideIndex, rct_xy_element *startElement) */ static int sub_69ED9E() { - int miscSpriteCount = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_MISC, uint16); - int unkCount = RCT2_GLOBAL(0x013573C8, uint16); - return max(0, miscSpriteCount + unkCount - 300); + int miscSpriteCount = gSpriteListCount[SPRITE_LIST_MISC]; + int remainingSpriteCount = gSpriteListCount[SPRITE_LIST_NULL]; + return max(0, miscSpriteCount + remainingSpriteCount - 300); } const rct_xy16 word_9A3AB4[4] = { @@ -4624,7 +4624,7 @@ void vehicle_create_trains(int rideIndex, int x, int y, int z, rct_map_element * lastTrain = train; // Add train to ride vehicle list - move_sprite_to_list((rct_sprite*)train.head, SPRITE_LINKEDLIST_OFFSET_VEHICLE); + move_sprite_to_list((rct_sprite*)train.head, SPRITE_LIST_VEHICLE * 2); for (int i = 0; i < 32; i++) { if (ride->vehicles[i] == SPRITE_INDEX_NULL) { ride->vehicles[i] = train.head->sprite_index; diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index d4308210da..659c75e34c 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -377,7 +377,7 @@ void vehicle_sounds_update() } } gVehicleSoundParamsListEnd = &gVehicleSoundParamsList[0]; - for (uint16 i = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); i != SPRITE_INDEX_NULL; i = g_sprite_list[i].vehicle.next) { + for (uint16 i = gSpriteListHead[SPRITE_LIST_VEHICLE]; i != SPRITE_INDEX_NULL; i = g_sprite_list[i].vehicle.next) { vehicle_update_sound_params(&g_sprite_list[i].vehicle); } for(int i = 0; i < countof(gVehicleSoundList); i++){ @@ -626,7 +626,7 @@ void vehicle_update_all() return; - sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); + sprite_index = gSpriteListHead[SPRITE_LIST_VEHICLE]; while (sprite_index != SPRITE_INDEX_NULL) { vehicle = &(g_sprite_list[sprite_index].vehicle); sprite_index = vehicle->next; diff --git a/src/scenario.h b/src/scenario.h index 94055f9a44..e2785137e5 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -137,18 +137,8 @@ typedef struct { // SC6[6] uint32 dword_010E63B8; rct_sprite sprites[10000]; - uint16 sprites_next_index; - uint16 sprites_start_vehicle; - uint16 sprites_start_peep; - uint16 sprites_start_textfx; - uint16 sprites_start_litter; - uint8 pad_013573C6[2]; - uint16 word_013573C8; - uint16 sprites_count_vehicle; - uint16 sprites_count_peep; - uint16 sprites_count_misc; - uint16 sprites_count_litter; - uint8 pad_013573D2[2]; + uint16 sprite_lists_head[6]; + uint16 sprite_lists_count[6]; rct_string_id park_name; uint8 pad_013573D6[2]; uint32 park_name_args; diff --git a/src/windows/editor_bottom_toolbar.c b/src/windows/editor_bottom_toolbar.c index a28313e683..540652f340 100644 --- a/src/windows/editor_bottom_toolbar.c +++ b/src/windows/editor_bottom_toolbar.c @@ -341,7 +341,8 @@ static void window_editor_bottom_toolbar_mouseup(rct_window *w, int widgetIndex) { if (widgetIndex == WIDX_PREVIOUS_STEP_BUTTON) { if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) || - (RCT2_GLOBAL(0x13573C8, uint16) == 0x2710 && !(gParkFlags & PARK_FLAGS_18))) { + (gSpriteListCount[SPRITE_LIST_NULL] == MAX_SPRITES && !(gParkFlags & PARK_FLAGS_18)) + ) { previous_button_mouseup_events[g_editor_step](); } } else if (widgetIndex == WIDX_NEXT_STEP_BUTTON) { @@ -387,7 +388,7 @@ void window_editor_bottom_toolbar_invalidate(rct_window *w) } else if (g_editor_step == EDITOR_STEP_ROLLERCOASTER_DESIGNER) { hide_next_step_button(); } else if (!(gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)) { - if (RCT2_GLOBAL(0x13573C8, uint16) != 0x2710 || gParkFlags & PARK_FLAGS_18) { + if (gSpriteListCount[SPRITE_LIST_NULL] != MAX_SPRITES || gParkFlags & PARK_FLAGS_18) { hide_previous_step_button(); } } @@ -409,7 +410,7 @@ void window_editor_bottom_toolbar_paint(rct_window *w, rct_drawpixelinfo *dpi) else if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) { drawPreviousButton = true; } - else if (RCT2_GLOBAL(0x13573C8, uint16) != 0x2710) { + else if (gSpriteListCount[SPRITE_LIST_NULL] != MAX_SPRITES) { drawNextButton = true; } else if (gParkFlags & PARK_FLAGS_18) { diff --git a/src/windows/map.c b/src/windows/map.c index 67b626c6c0..d511cd0dab 100644 --- a/src/windows/map.c +++ b/src/windows/map.c @@ -1057,7 +1057,7 @@ static void window_map_paint_train_overlay(rct_drawpixelinfo *dpi) sint16 left, top, right, bottom; - for (train_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); train_index != SPRITE_INDEX_NULL; train_index = train->next) { + for (train_index = gSpriteListHead[SPRITE_LIST_VEHICLE]; 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) { vehicle = GET_VEHICLE(vehicle_index); diff --git a/src/world/duck.c b/src/world/duck.c index bc6f5fd6f1..a30f2d3beb 100644 --- a/src/world/duck.c +++ b/src/world/duck.c @@ -317,7 +317,7 @@ void duck_remove_all() rct_unk_sprite* sprite; uint16 spriteIndex, nextSpriteIndex; - for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_MISC, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { + for (spriteIndex = gSpriteListHead[SPRITE_LIST_MISC]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { sprite = &(g_sprite_list[spriteIndex].unknown); nextSpriteIndex = sprite->next; if (sprite->misc_identifier == SPRITE_MISC_DUCK) diff --git a/src/world/footpath.c b/src/world/footpath.c index c77399a00d..891a09a099 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -782,7 +782,7 @@ void footpath_remove_litter(int x, int y, int z) while (spriteIndex != SPRITE_INDEX_NULL) { sprite = &g_sprite_list[spriteIndex].litter; nextSpriteIndex = sprite->next_in_quadrant; - if (sprite->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_LITTER) { + if (sprite->linked_list_type_offset == SPRITE_LIST_LITTER * 2) { int distanceZ = abs(sprite->z - z); if (distanceZ <= 32) { invalidate_sprite_0((rct_sprite*)sprite); @@ -808,7 +808,7 @@ void footpath_interrupt_peeps(int x, int y, int z) while (spriteIndex != SPRITE_INDEX_NULL) { peep = &g_sprite_list[spriteIndex].peep; nextSpriteIndex = peep->next_in_quadrant; - if (peep->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP) { + if (peep->linked_list_type_offset == SPRITE_LIST_PEEP * 2) { if (peep->state == PEEP_STATE_SITTING || peep->state == PEEP_STATE_WATCHING) { if (peep->z == z) { peep_decrement_num_riders(peep); diff --git a/src/world/map_animation.c b/src/world/map_animation.c index f7058e499b..630b06a395 100644 --- a/src/world/map_animation.c +++ b/src/world/map_animation.c @@ -199,7 +199,7 @@ static bool map_animation_invalidate_small_scenery(int x, int y, int baseZ) uint16 spriteIdx = RCT2_ADDRESS(0x00F1EF60, uint16)[((x2 & 0x1FE0) << 3) | (y2 >> 5)]; for (; spriteIdx != 0xFFFF; spriteIdx = sprite->unknown.next_in_quadrant) { sprite = &g_sprite_list[spriteIdx]; - if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP) + if (sprite->unknown.linked_list_type_offset != SPRITE_LIST_PEEP * 2) continue; peep = &sprite->peep; diff --git a/src/world/park.c b/src/world/park.c index a17b3b2b77..8e9ecb4ffc 100644 --- a/src/world/park.c +++ b/src/world/park.c @@ -278,7 +278,7 @@ int calculate_park_rating() short num_litter; num_litter = 0; - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = litter->next) { + for (sprite_idx = gSpriteListHead[SPRITE_LIST_LITTER]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = litter->next) { litter = &(g_sprite_list[sprite_idx].litter); // Ignore recently dropped litter diff --git a/src/world/sprite.c b/src/world/sprite.c index 13a3f55be6..4c280cf877 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -28,6 +28,9 @@ rct_sprite* g_sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); rct_sprite_entry* g_sprite_entries = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_ENTRIES, rct_sprite_entry); +uint16 *gSpriteListHead = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LISTS_HEAD, uint16); +uint16 *gSpriteListCount = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LISTS_COUNT, uint16); + uint16 sprite_get_first_in_quadrant(int x, int y) { int offset = ((x & 0x1FE0) << 3) | (y >> 5); @@ -85,13 +88,14 @@ void invalidate_sprite_2(rct_sprite *sprite) * * rct2: 0x0069EB13 */ -void reset_sprite_list(){ +void reset_sprite_list() +{ RCT2_GLOBAL(RCT2_ADDRESS_SAVED_AGE, uint16) = 0; memset(g_sprite_list, 0, sizeof(rct_sprite) * MAX_SPRITES); - for (int i = 0; i < 6; ++i){ - RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[i] = -1; - RCT2_ADDRESS(0x13573C8, uint16)[i] = 0; + for (int i = 0; i < NUM_SPRITE_LISTS; i++) { + gSpriteListHead[i] = SPRITE_INDEX_NULL; + gSpriteListCount[i] = 0; } rct_sprite* previous_spr = (rct_sprite*)SPRITE_INDEX_NULL; @@ -109,13 +113,13 @@ void reset_sprite_list(){ } else{ spr->unknown.previous = SPRITE_INDEX_NULL; - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16) = i; + gSpriteListHead[SPRITE_LIST_NULL] = i; } previous_spr = spr; spr++; } - RCT2_GLOBAL(0x13573C8, uint16) = MAX_SPRITES; + gSpriteListCount[SPRITE_LIST_NULL] = MAX_SPRITES; reset_0x69EBE4(); } @@ -126,15 +130,15 @@ void reset_sprite_list(){ * This function looks as though it sets some sort of order for sprites. * Sprites can share thier position if this is the case. */ -void reset_0x69EBE4(){ +void reset_0x69EBE4() +{ memset((uint16*)0xF1EF60, -1, 0x10001*2); - rct_sprite* spr = g_sprite_list; - for (; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; spr++){ - - if (spr->unknown.sprite_identifier != SPRITE_IDENTIFIER_NULL){ + for (size_t i = 0; i < MAX_SPRITES; i++) { + rct_sprite *spr = &g_sprite_list[i]; + if (spr->unknown.sprite_identifier != SPRITE_IDENTIFIER_NULL) { uint32 edi = spr->unknown.x; - if (spr->unknown.x == SPRITE_LOCATION_NULL){ + if (spr->unknown.x == SPRITE_LOCATION_NULL) { edi = 0x10000; } else { int ecx = spr->unknown.y; @@ -143,8 +147,8 @@ void reset_0x69EBE4(){ edi <<= 3; edi |= ecx; } - uint16 ax = RCT2_ADDRESS(0xF1EF60,uint16)[edi]; - RCT2_ADDRESS(0xF1EF60,uint16)[edi] = spr->unknown.sprite_index; + uint16 ax = RCT2_ADDRESS(0xF1EF60, uint16)[edi]; + RCT2_ADDRESS(0xF1EF60, uint16)[edi] = spr->unknown.sprite_index; spr->unknown.next_in_quadrant = ax; } } @@ -159,7 +163,7 @@ void sprite_clear_all_unused() rct_unk_sprite *sprite; uint16 spriteIndex, nextSpriteIndex, previousSpriteIndex; - spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16); + spriteIndex = gSpriteListHead[SPRITE_LIST_NULL]; while (spriteIndex != SPRITE_INDEX_NULL) { sprite = &g_sprite_list[spriteIndex].unknown; nextSpriteIndex = sprite->next; @@ -168,7 +172,7 @@ void sprite_clear_all_unused() sprite->sprite_identifier = SPRITE_IDENTIFIER_NULL; sprite->next = nextSpriteIndex; sprite->previous = previousSpriteIndex; - sprite->linked_list_type_offset = SPRITE_LINKEDLIST_OFFSET_NULL; + sprite->linked_list_type_offset = SPRITE_LIST_NULL * 2; sprite->sprite_index = spriteIndex; spriteIndex = nextSpriteIndex; } @@ -180,25 +184,19 @@ void sprite_clear_all_unused() */ rct_sprite *create_sprite(uint8 bl) { - SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_UNKNOWN; // cl - - if ((bl & 2) != 0) - { + size_t linkedListTypeOffset = SPRITE_LIST_UNKNOWN * 2; + if ((bl & 2) != 0) { // 69EC96; - sint16 cx = 0x12C - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_MISC, uint16); - if (cx >= RCT2_GLOBAL(0x13573C8, uint16)) - { + sint16 cx = 0x12C - gSpriteListCount[SPRITE_LIST_MISC]; + if (cx >= gSpriteListCount[SPRITE_LIST_NULL]) { return NULL; } - - linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_MISC; - } - else if (RCT2_GLOBAL(0x13573C8, uint16) <= 0) - { + linkedListTypeOffset = SPRITE_LIST_MISC * 2; + } else if (gSpriteListCount[SPRITE_LIST_NULL] == 0) { return NULL; } - rct_unk_sprite *sprite = &(g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)]).unknown; + rct_unk_sprite *sprite = &(g_sprite_list[gSpriteListHead[SPRITE_LIST_NULL]]).unknown; move_sprite_to_list((rct_sprite *)sprite, (uint8)linkedListTypeOffset); @@ -219,44 +217,43 @@ rct_sprite *create_sprite(uint8 bl) } /* -* rct2: 0x0069ED0B -* This function moves a sprite to the specified sprite linked list. -* There are 5/6 of those, and cl specifies a pointer offset -* of the desired linked list in a uint16 array. Known valid values are -* 2, 4, 6, 8 or 10 (SPRITE_LINKEDLIST_OFFSET_...) -*/ -void move_sprite_to_list(rct_sprite *sprite, uint8 cl) + * rct2: 0x0069ED0B + * This function moves a sprite to the specified sprite linked list. + * There are 5/6 of those, and cl specifies a pointer offset + * of the desired linked list in a uint16 array. Known valid values are + * 2, 4, 6, 8 or 10 (SPRITE_LIST_... * 2) + */ +void move_sprite_to_list(rct_sprite *sprite, uint8 newListOffset) { rct_unk_sprite *unkSprite = &sprite->unknown; + uint8 oldListOffset = unkSprite->linked_list_type_offset; + int oldList = oldListOffset >> 1; + int newList = newListOffset >> 1; // No need to move if the sprite is already in the desired list - if (unkSprite->linked_list_type_offset == cl) + if (oldListOffset == newListOffset) { return; + } // If the sprite is currently the head of the list, the // sprite following this one becomes the new head of the list. - if (unkSprite->previous == SPRITE_INDEX_NULL) - { - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + unkSprite->linked_list_type_offset, uint16) = unkSprite->next; - } - else - { + if (unkSprite->previous == SPRITE_INDEX_NULL) { + gSpriteListHead[oldList] = unkSprite->next; + } else { // Hook up sprite->previous->next to sprite->next, removing the sprite from its old list g_sprite_list[unkSprite->previous].unknown.next = unkSprite->next; } // Similarly, hook up sprite->next->previous to sprite->previous - if (unkSprite->next != SPRITE_INDEX_NULL) - { + if (unkSprite->next != SPRITE_INDEX_NULL) { g_sprite_list[unkSprite->next].unknown.previous = unkSprite->previous; } - int oldListTypeOffset = unkSprite->linked_list_type_offset; unkSprite->previous = SPRITE_INDEX_NULL; // We become the new head of the target list, so there's no previous sprite - unkSprite->linked_list_type_offset = cl; + unkSprite->linked_list_type_offset = newListOffset; - unkSprite->next = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16); // This sprite's next sprite is the old head, since we're the new head - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16) = unkSprite->sprite_index; // Store this sprite's index as head of its new list + unkSprite->next = gSpriteListHead[newList]; // This sprite's next sprite is the old head, since we're the new head + gSpriteListHead[newList] = unkSprite->sprite_index; // Store this sprite's index as head of its new list if (unkSprite->next != SPRITE_INDEX_NULL) { @@ -266,8 +263,8 @@ void move_sprite_to_list(rct_sprite *sprite, uint8 cl) // These globals are probably counters for each sprite list? // Decrement old list counter, increment new list counter. - --(RCT2_GLOBAL(0x13573C8 + oldListTypeOffset, uint16)); - ++(RCT2_GLOBAL(0x13573C8 + cl, uint16)); + gSpriteListCount[oldList]--; + gSpriteListCount[newList]++; } /** @@ -403,7 +400,7 @@ void sprite_misc_update_all() rct_sprite *sprite; uint16 spriteIndex; - spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_MISC, uint16); + spriteIndex = gSpriteListHead[SPRITE_LIST_MISC]; while (spriteIndex != SPRITE_INDEX_NULL) { sprite = &g_sprite_list[spriteIndex]; spriteIndex = sprite->unknown.next; @@ -494,7 +491,7 @@ void sprite_move(sint16 x, sint16 y, sint16 z, rct_sprite* sprite){ */ void sprite_remove(rct_sprite *sprite) { - move_sprite_to_list(sprite, SPRITE_LINKEDLIST_OFFSET_NULL); + move_sprite_to_list(sprite, SPRITE_LIST_NULL * 2); user_string_free(sprite->unknown.name_string_idx); sprite->unknown.sprite_identifier = SPRITE_IDENTIFIER_NULL; @@ -556,10 +553,10 @@ void litter_create(int x, int y, int z, int direction, int type) uint16 spriteIndex, nextSpriteIndex; uint32 newestLitterCreationTick; - if (RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_COUNT_LITTER, uint16) >= 500) { + if (gSpriteListCount[SPRITE_LIST_LITTER] >= 500) { newestLitter = NULL; newestLitterCreationTick = 0; - for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { + for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) { litter = &(g_sprite_list[spriteIndex].litter); nextSpriteIndex = litter->next; if (newestLitterCreationTick <= litter->creationTick) { @@ -578,7 +575,7 @@ void litter_create(int x, int y, int z, int direction, int type) if (litter == NULL) return; - move_sprite_to_list((rct_sprite*)litter, SPRITE_LINKEDLIST_OFFSET_LITTER); + move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER * 2); litter->sprite_direction = direction; litter->sprite_width = 6; litter->sprite_height_negative = 6; @@ -600,7 +597,7 @@ void litter_remove_at(int x, int y, int z) while (spriteIndex != SPRITE_INDEX_NULL) { rct_sprite *sprite = &g_sprite_list[spriteIndex]; uint16 nextSpriteIndex = sprite->unknown.next_in_quadrant; - if (sprite->unknown.linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_LITTER) { + if (sprite->unknown.linked_list_type_offset == SPRITE_LIST_LITTER * 2) { rct_litter *litter = &sprite->litter; if (abs(litter->z - z) <= 16) { diff --git a/src/world/sprite.h b/src/world/sprite.h index aa406c00f2..aaaf23b188 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -21,11 +21,12 @@ #include "../peep/peep.h" #include "../ride/vehicle.h" -#define SPRITE_INDEX_NULL 0xFFFF -#define SPRITE_LOCATION_NULL ((sint16)0x8000) -#define MAX_SPRITES 10000 +#define SPRITE_INDEX_NULL 0xFFFF +#define SPRITE_LOCATION_NULL ((sint16)0x8000) +#define MAX_SPRITES 10000 +#define NUM_SPRITE_LISTS 6 -enum SPRITE_IDENTIFIER{ +enum SPRITE_IDENTIFIER { SPRITE_IDENTIFIER_VEHICLE = 0, SPRITE_IDENTIFIER_PEEP = 1, SPRITE_IDENTIFIER_MISC = 2, @@ -33,14 +34,14 @@ enum SPRITE_IDENTIFIER{ SPRITE_IDENTIFIER_NULL = 255 }; -typedef enum { - SPRITE_LINKEDLIST_OFFSET_NULL = 0, - SPRITE_LINKEDLIST_OFFSET_VEHICLE = 2, - SPRITE_LINKEDLIST_OFFSET_PEEP = 4, - SPRITE_LINKEDLIST_OFFSET_MISC = 6, - SPRITE_LINKEDLIST_OFFSET_LITTER = 8, - SPRITE_LINKEDLIST_OFFSET_UNKNOWN = 10 -} SPRITE_LINKEDLIST_OFFSET; +enum SPRITE_LIST { + SPRITE_LIST_NULL, + SPRITE_LIST_VEHICLE, + SPRITE_LIST_PEEP, + SPRITE_LIST_MISC, + SPRITE_LIST_LITTER, + SPRITE_LIST_UNKNOWN, +}; typedef struct { uint8 sprite_identifier; // 0x00 @@ -370,6 +371,8 @@ extern rct_sprite* g_sprite_list; // rct2: 0x00982708 extern rct_sprite_entry* g_sprite_entries; +extern uint16 *gSpriteListHead; +extern uint16 *gSpriteListCount; rct_sprite *create_sprite(uint8 bl); void reset_sprite_list();