refactor sprite heads and counts

This commit is contained in:
Ted John 2016-05-09 00:08:03 +01:00
parent 5ccfd83dea
commit d2c5501eea
21 changed files with 131 additions and 160 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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