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 1/4] 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]; From 9de2520a8a810fcfc27ff5f74f3fb72a4afb1269 Mon Sep 17 00:00:00 2001 From: Tom van der Kleij Date: Fri, 5 Sep 2014 23:47:18 +0200 Subject: [PATCH 2/4] Fixing some travis compilation errors due to compiler used there being more strict than visual studio 2013 --- src/sprite.c | 4 ++-- src/sprite.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sprite.c b/src/sprite.c index 53d6549eea..c7836cda65 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -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; - move_sprite_to_list(sprite, linkedListTypeOffset); + move_sprite_to_list((rct_sprite *)sprite, linkedListTypeOffset); sprite->x = SPRITE_LOCATION_NULL; sprite->y = SPRITE_LOCATION_NULL; @@ -159,7 +159,7 @@ rct_sprite *create_sprite(uint8 bl) */ void move_sprite_to_list(rct_sprite *sprite, uint8 cl) { - rct_unk_sprite *unkSprite = sprite; + rct_unk_sprite *unkSprite = &sprite->unknown; // No need to move if the sprite is already in the desired list if (unkSprite->linked_list_type_offset == cl) diff --git a/src/sprite.h b/src/sprite.h index 73e7d48c64..3bd33e641b 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -100,6 +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); +void move_sprite_to_list(rct_sprite *sprite, uint8 cl); #endif From 87667b78d416e16d1586b2d51302153a4f82ff9f Mon Sep 17 00:00:00 2001 From: Tom van der Kleij Date: Sat, 6 Sep 2014 09:11:04 +0200 Subject: [PATCH 3/4] Implemented suggestions from comments on pull request --- src/sprite.c | 4 ++-- src/sprite.h | 2 +- src/staff.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sprite.c b/src/sprite.c index c7836cda65..45e3989038 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -112,7 +112,7 @@ void reset_0x69EBE4(){ */ rct_sprite *create_sprite(uint8 bl) { - int linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_UNKNOWN; // cl + enum SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_UNKNOWN; // cl if ((bl & 2) != 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; - move_sprite_to_list((rct_sprite *)sprite, linkedListTypeOffset); + move_sprite_to_list((rct_sprite *)sprite, (uint8)linkedListTypeOffset); sprite->x = SPRITE_LOCATION_NULL; sprite->y = SPRITE_LOCATION_NULL; diff --git a/src/sprite.h b/src/sprite.h index 3bd33e641b..957e97360c 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -36,7 +36,7 @@ enum SPRITE_IDENTIFIER{ SPRITE_IDENTIFIER_LITTER = 3, }; -enum { +enum SPRITE_LINKEDLIST_OFFSET { SPRITE_LINKEDLIST_OFFSET_VEHICLE = 2, SPRITE_LINKEDLIST_OFFSET_PEEP = 4, SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT = 6, diff --git a/src/staff.c b/src/staff.c index 099148b4a2..65290986a9 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 { - move_sprite_to_list(newPeep, 4); + move_sprite_to_list(newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); newPeep->sprite_identifier = 1; newPeep->var_09 = 0x0F; From 7058756d9c67f64ac0c292de547d34fcc7f2fc86 Mon Sep 17 00:00:00 2001 From: Tom van der Kleij Date: Sat, 6 Sep 2014 23:46:45 +0200 Subject: [PATCH 4/4] Incorporated suggested change by @qcz and fixed an enum member name and a compiler warning --- src/sprite.c | 2 +- src/sprite.h | 6 +++--- src/staff.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sprite.c b/src/sprite.c index 45e3989038..e6d589f5b1 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -112,7 +112,7 @@ void reset_0x69EBE4(){ */ rct_sprite *create_sprite(uint8 bl) { - enum SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_UNKNOWN; // cl + SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_UNKNOWN; // cl if ((bl & 2) != 0) { diff --git a/src/sprite.h b/src/sprite.h index 957e97360c..567c64af44 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -36,13 +36,13 @@ enum SPRITE_IDENTIFIER{ SPRITE_IDENTIFIER_LITTER = 3, }; -enum SPRITE_LINKEDLIST_OFFSET { +typedef 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 -}; + SPRITE_LINKEDLIST_OFFSET_UNKNOWN = 10 +} SPRITE_LINKEDLIST_OFFSET; typedef struct { uint8 sprite_identifier; // 0x00 diff --git a/src/staff.c b/src/staff.c index 65290986a9..ce46f47525 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 { - move_sprite_to_list(newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); + move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); newPeep->sprite_identifier = 1; newPeep->var_09 = 0x0F;