From 185d64e157075f0ebe2f9d99f07aaadcf9c7e373 Mon Sep 17 00:00:00 2001 From: Tom van der Kleij Date: Fri, 5 Sep 2014 19:31:25 +0200 Subject: [PATCH] Decompilation of move_sprite_to_list (0x0069ED0B) --- src/peep.c | 2 +- src/peep.h | 2 +- src/ride.c | 2 +- src/sprite.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++----- src/sprite.h | 13 +++++++++-- src/staff.c | 2 +- src/vehicle.h | 2 +- 7 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/peep.c b/src/peep.c index da7c594544..aa2d252b6a 100644 --- a/src/peep.c +++ b/src/peep.c @@ -65,7 +65,7 @@ void peep_update_all() peep_update(peep); } else { RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, (int)peep, 0, 0); - if (peep->var_08 == 4) + if (peep->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP) peep_update(peep); } diff --git a/src/peep.h b/src/peep.h index 3f18e5d587..30a34cb7bb 100644 --- a/src/peep.h +++ b/src/peep.h @@ -308,7 +308,7 @@ typedef struct { uint16 var_02; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 var_09; // 0x09 uint16 sprite_index; // 0x0A uint16 var_0C; diff --git a/src/ride.c b/src/ride.c index 7637de70fb..7478d4cccc 100644 --- a/src/ride.c +++ b/src/ride.c @@ -184,7 +184,7 @@ void ride_update_favourited_stat() ride->guests_favourite = 0; FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->var_08 != 4) + if (peep->linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP) return; if (peep->favourite_ride != 0xff) { ride = &g_ride_list[peep->favourite_ride]; diff --git a/src/sprite.c b/src/sprite.c index ec511dfaeb..53d6549eea 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -53,7 +53,7 @@ void reset_sprite_list(){ spr->unknown.sprite_identifier = 0xFF; spr->unknown.sprite_index = i; spr->unknown.next = SPRITE_INDEX_NULL; - spr->unknown.var_08 = 0; + spr->unknown.linked_list_type_offset = 0; if (previous_spr != (rct_sprite*)SPRITE_INDEX_NULL){ spr->unknown.previous = previous_spr->unknown.sprite_index; @@ -108,11 +108,11 @@ void reset_0x69EBE4(){ /* * rct2: 0x0069EC6B -* bl: unclear what this does +* bl: if bl & 2 > 0, the sprite ends up in the FLOATING_TEXT linked list. */ rct_sprite *create_sprite(uint8 bl) { - int ecx = 0xA; + int linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_UNKNOWN; // cl if ((bl & 2) != 0) { @@ -123,7 +123,7 @@ rct_sprite *create_sprite(uint8 bl) return NULL; } - ecx = 6; + linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT; } else if (RCT2_GLOBAL(0x13573C8, uint16) <= 0) { @@ -132,7 +132,7 @@ rct_sprite *create_sprite(uint8 bl) rct_unk_sprite *sprite = &(g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)]).unknown; - RCT2_CALLPROC_X(0x0069ED0B, 0, 0, ecx, 0, (int)sprite, 0, 0); + move_sprite_to_list(sprite, linkedListTypeOffset); sprite->x = SPRITE_LOCATION_NULL; sprite->y = SPRITE_LOCATION_NULL; @@ -148,4 +148,56 @@ rct_sprite *create_sprite(uint8 bl) RCT2_GLOBAL(0xF3EF60, uint16) = sprite->sprite_index; return (rct_sprite*)sprite; +} + +/* +* 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) +{ + rct_unk_sprite *unkSprite = sprite; + + // No need to move if the sprite is already in the desired list + if (unkSprite->linked_list_type_offset == cl) + 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 + { + // 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) + { + 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->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 + + if (unkSprite->next != SPRITE_INDEX_NULL) + { + // Fix the chain by settings sprite->next->previous to sprite_index + g_sprite_list[unkSprite->next].unknown.previous = unkSprite->sprite_index; + } + + // 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)); } \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index 81f6955956..73e7d48c64 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -36,13 +36,21 @@ enum SPRITE_IDENTIFIER{ SPRITE_IDENTIFIER_LITTER = 3, }; +enum { + SPRITE_LINKEDLIST_OFFSET_VEHICLE = 2, + SPRITE_LINKEDLIST_OFFSET_PEEP = 4, + SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT = 6, + SPRITE_LINKEDLIST_OFFSET_FLOATING_LITTER = 8, + SPRITE_LINKEDLIST_OFFSET_FLOATING_UNKNOWN = 10 +}; + typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01; uint16 var_02; uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0C[2]; @@ -66,7 +74,7 @@ typedef struct { uint16 var_02; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0B[0x19]; @@ -92,5 +100,6 @@ void create_balloon(int x, int y, int z, int colour); rct_sprite *create_sprite(uint8 bl); void reset_sprite_list(); void reset_0x69EBE4(); +void move_sprite_to_list(rct_sprite *sprite, int ecx); #endif diff --git a/src/staff.c b/src/staff.c index cead4581e3..099148b4a2 100644 --- a/src/staff.c +++ b/src/staff.c @@ -127,7 +127,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, RCT2_CALLPROC_X(0x0069EDB6, 0, 0, _ecx, 0, (int)newPeep, 0, 0); } else { - RCT2_CALLPROC_X(0x0069ED0B, 0, 0, 4, 0, (int)newPeep, 0, 0); + move_sprite_to_list(newPeep, 4); newPeep->sprite_identifier = 1; newPeep->var_09 = 0x0F; diff --git a/src/vehicle.h b/src/vehicle.h index 046d719a34..c80aec3ddf 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -36,7 +36,7 @@ typedef struct { uint8 pad_01[0x03]; uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0C[2];