From 502b4c4cbd8b21d1d341ff97a3e330d84c738357 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 10 Nov 2014 17:23:13 +0000 Subject: [PATCH] Fix peeps walking on water after entering. Added some known offsets. --- src/interface/viewport.c | 8 +- src/interface/viewport_interaction.c | 6 +- src/peep/peep.c | 108 ++++++++------------------- src/peep/peep.h | 8 +- src/ride/vehicle.c | 10 +-- src/ride/vehicle.h | 12 +-- src/world/sprite.c | 55 ++++++++++++-- src/world/sprite.h | 9 ++- 8 files changed, 109 insertions(+), 107 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 88a0e57a1e..dd756181ae 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -782,10 +782,10 @@ void sub_0x69E8B0(uint32 eax, uint32 ecx){ spr = &g_sprite_list[sprite_idx]; dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); - if (dpi->y + dpi->height <= spr->unknown.var_18) continue; - if (spr->unknown.var_1C <= dpi->y)continue; - if (dpi->x + dpi->width <= spr->unknown.var_16)continue; - if (spr->unknown.var_1A <= dpi->x)continue; + if (dpi->y + dpi->height <= spr->unknown.sprite_top) continue; + if (spr->unknown.sprite_bottom <= dpi->y)continue; + if (dpi->x + dpi->width <= spr->unknown.sprite_left)continue; + if (spr->unknown.sprite_right <= dpi->x)continue; int ebx = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); RCT2_GLOBAL(0x9DE578, uint32) = (uint32)spr; diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 205b76d59b..0c545260e8 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -515,12 +515,12 @@ static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDist closestPeep = NULL; closestDistance = 0xFFFF; FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->var_16 == 0x8000) + if (peep->sprite_left == 0x8000) continue; distance = - abs(((peep->var_16 + peep->var_1A) / 2) - x) + - abs(((peep->var_18 + peep->var_1C) / 2) - y); + abs(((peep->sprite_left + peep->sprite_right) / 2) - x) + + abs(((peep->sprite_top + peep->sprite_bottom) / 2) - y); if (distance > maxDistance) continue; diff --git a/src/peep/peep.c b/src/peep/peep.c index 20ea706a15..19b9ebd49a 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -107,48 +107,6 @@ void peep_update_all() } } -/* rct2: 0x006EC473 */ -void invalidate_sprite(rct_peep* peep){ - if (peep->var_16 == (sint16)0x8000) return; - - for (rct_viewport** viewport_p = RCT2_ADDRESS(RCT2_ADDRESS_ACTIVE_VIEWPORT_PTR_ARRAY, rct_viewport*); *viewport_p!= NULL; viewport_p++){ - rct_viewport* viewport = *viewport_p; - int left, right, top, bottom; - left = peep->var_16; - right = peep->var_1A; - top = peep->var_18; - bottom = peep->var_1C; - - if (viewport->zoom >= 3)continue; - if (right <= viewport->view_x)continue; - if (bottom <= viewport->view_y) continue; - - int viewport_right = viewport->view_x + viewport->view_width; - int viewport_bottom = viewport->view_y + viewport->view_height; - - if (left >= viewport_right)continue; - if (top >= viewport_bottom)continue; - - left = max(left, viewport->view_x); - right = min(right, viewport_right); - top = max(top, viewport->view_y); - bottom = min(bottom, viewport_bottom); - - left -= viewport->view_x; - top -= viewport->view_y; - right -= viewport->view_x; - bottom -= viewport->view_y; - - int zoom = 1 << viewport->zoom; - left /= zoom; - top /= zoom; - right /= zoom; - bottom /= zoom; - - gfx_set_dirty_blocks(left + viewport->x, top + viewport->y, right + viewport->x, bottom + viewport->y); - } -} - /* rct2: 0x6939EB */ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ RCT2_GLOBAL(0xF1AEF0, uint8) = peep->var_70; @@ -170,25 +128,25 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ return 0; } int direction = 0; - if (ebx <= edx){ + if (ebx < edx){ direction = 8; - if (*y > 0){ + if (*y >= 0){ direction = 24; } } else{ direction = 16; - if (*x > 0){ + if (*x >= 0){ direction = 0; } } peep->sprite_direction = direction; - *x = peep->x + RCT2_ADDRESS(0x981D7C, uint16)[direction / 2]; - *y = peep->y + RCT2_ADDRESS(0x981D7E, uint16)[direction / 2]; + *x = peep->x + RCT2_ADDRESS(0x981D7C, uint16)[direction / 4]; + *y = peep->y + RCT2_ADDRESS(0x981D7E, uint16)[direction / 4]; ebx = peep->var_E0 + 1; uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]; uint8* _edi = (uint8*)(edi[peep->var_6E * 2 + 1]); - if (ebx > *_edi){ + if (ebx >= *_edi){ ebx = 0; } peep->var_E0 = ebx; @@ -205,14 +163,14 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ peep->var_70 = 0; peep->var_71 = 0xFF; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep); + invalidate_sprite((rct_sprite*)peep); *x = peep->x; *y = peep->y; return 1; } peep->var_70 = ebx; if (peep->var_71 != 8 || peep->var_71 != 15){ - invalidate_sprite(peep); + invalidate_sprite((rct_sprite*)peep); *x = peep->x; *y = peep->y; return 1; @@ -234,7 +192,7 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ sound_play_panned(sound_id, 0x8001, peep->x, peep->y, peep->z); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); *x = peep->x; *y = peep->y; return 1; @@ -352,7 +310,7 @@ void peep_update_falling(rct_peep* peep){ if (height - 4 >= peep->z && height < peep->z + 20){ // Looks like we are drowning! - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); sub_69E9D3(peep->x, peep->y, height, (rct_sprite*)peep); // Drop balloon if held if (peep->item_standard_flags & PEEP_ITEM_BALLOON){ @@ -372,7 +330,7 @@ void peep_update_falling(rct_peep* peep){ peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); peep_window_state_update(peep); return; } @@ -387,20 +345,20 @@ void peep_update_falling(rct_peep* peep){ // This will be null if peep is falling if (saved_map == NULL){ - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); if (peep->z <= 1){ // Remove peep if it has gone to the void peep_remove(peep); return; } sub_69E9D3(peep->x, peep->y, peep->z - 2, (rct_sprite*)peep); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); return; } - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); sub_69E9D3(peep->x, peep->y, saved_height, (rct_sprite*)peep); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); peep->next_x = peep->x & 0xFFE0; peep->next_y = peep->y & 0xFFE0; @@ -454,11 +412,11 @@ void peep_update_sitting(rct_peep* peep){ int y = peep->y & 0xFFE0 + RCT2_ADDRESS(0x981F2E, uint16)[ebx * 2]; int z = peep->z; - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); sub_69E9D3(x, y, z, (rct_sprite*)peep); peep->sprite_direction = ((peep->var_37 + 2) & 3) * 8; - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); peep->var_71 = 254; peep->var_6F = 7; RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0); @@ -508,7 +466,7 @@ void peep_update_sitting(rct_peep* peep){ peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); return; } @@ -533,7 +491,7 @@ void peep_update_sitting(rct_peep* peep){ peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); return; } } @@ -567,7 +525,7 @@ void peep_update_queuing(rct_peep* peep){ } //Give up queueing for the ride peep->sprite_direction ^= (1 << 4); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; @@ -583,7 +541,7 @@ void peep_update_queuing(rct_peep* peep){ peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); } if (peep->var_7A >= 3500 && (0xFFFF & scenario_rand()) <= 93) { @@ -621,7 +579,7 @@ void peep_update_queuing(rct_peep* peep){ peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); break; } } @@ -631,7 +589,7 @@ void peep_update_queuing(rct_peep* peep){ if (peep->happiness <= 65 && (0xFFFF & scenario_rand()) < 2184){ //Give up queueing for the ride peep->sprite_direction ^= (1 << 4); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; @@ -664,9 +622,9 @@ static void peep_update_entering_park(rct_peep* peep){ } sint16 x = 0, y = 0; if (sub_6939EB(&x, &y, peep)){ - invalidate_sprite(peep); + invalidate_sprite((rct_sprite*)peep); sub_69E9D3(x, y, peep->z, (rct_sprite*)peep); - invalidate_sprite(peep); + invalidate_sprite((rct_sprite*)peep); return; } peep_decrement_num_riders(peep); @@ -675,7 +633,7 @@ static void peep_update_entering_park(rct_peep* peep){ peep->var_2A = 0; peep->time_in_park = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, sint32); - RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16); + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)++; RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--; RCT2_GLOBAL(0x9A9804, uint16) |= (1 << 2); window_invalidate_by_class(WC_GUEST_LIST); @@ -992,15 +950,15 @@ void peep_update_crowd_noise() visiblePeeps = 0; FOR_ALL_GUESTS(spriteIndex, peep) { - if (peep->var_16 == (sint16)0x8000) + if (peep->sprite_left == (sint16)0x8000) continue; - if (viewport->view_x > peep->var_1A) + if (viewport->view_x > peep->sprite_right) continue; - if (viewport->view_x + viewport->view_width < peep->var_16) + if (viewport->view_x + viewport->view_width < peep->sprite_left) continue; - if (viewport->view_y > peep->var_1C) + if (viewport->view_y > peep->sprite_bottom) continue; - if (viewport->view_y + viewport->view_height < peep->var_18) + if (viewport->view_y + viewport->view_height < peep->sprite_top) continue; visiblePeeps += peep->state == PEEP_STATE_QUEUING ? 1 : 2; @@ -1090,7 +1048,7 @@ void peep_applause() peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x00693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep); + invalidate_sprite((rct_sprite*)peep); } } @@ -1474,7 +1432,7 @@ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_a peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - invalidate_sprite(peep);; + invalidate_sprite((rct_sprite*)peep); } for (int i = 0; i < PEEP_MAX_THOUGHTS; ++i){ diff --git a/src/peep/peep.h b/src/peep/peep.h index 8141e32af2..9f5b63afe8 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -319,10 +319,10 @@ typedef struct { sint16 z; // 0x12 uint8 var_14; // 0x14 uint8 var_15; // 0x15 - sint16 var_16; - sint16 var_18; - sint16 var_1A; - sint16 var_1C; + sint16 sprite_left; // 0x16 + sint16 sprite_top; // 0x18 + sint16 sprite_right; // 0x1A + sint16 sprite_bottom; // 0x1C uint8 sprite_direction; // 0x1E uint8 pad_1F[3]; uint16 name_string_idx; // 0x22 diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index ee34c474f6..a66327253f 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -37,11 +37,11 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) { if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) && (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 4) || RCT2_GLOBAL(0x0141F570, uint8) == 6)) { if (vehicle->sound1_id != (uint8)-1 || vehicle->sound2_id != (uint8)-1) { - if (vehicle->var_16 != 0x8000) { - RCT2_GLOBAL(0x009AF5A0, sint16) = vehicle->var_16; - RCT2_GLOBAL(0x009AF5A2, sint16) = vehicle->var_18; - RCT2_GLOBAL(0x009AF5A4, sint16) = vehicle->var_1A; - RCT2_GLOBAL(0x009AF5A6, sint16) = vehicle->var_1C; + if (vehicle->sprite_left != 0x8000) { + RCT2_GLOBAL(0x009AF5A0, sint16) = vehicle->sprite_left; + RCT2_GLOBAL(0x009AF5A2, sint16) = vehicle->sprite_top; + RCT2_GLOBAL(0x009AF5A4, sint16) = vehicle->sprite_right; + RCT2_GLOBAL(0x009AF5A6, sint16) = vehicle->sprite_bottom; sint16 v4 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x; sint16 v5 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y; sint16 v6 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width / 4; diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 7272a7efbe..969197661c 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -37,12 +37,12 @@ typedef struct { sint16 y; // 0x10 sint16 z; // 0x12 uint8 pad_14[0x02]; - sint16 var_16; - sint16 var_18; - sint16 var_1A; - sint16 var_1C; - uint16 var_1E; - uint8 pad_20[0x08]; + sint16 sprite_left; // 0x16 + sint16 sprite_top; // 0x18 + sint16 sprite_right; // 0x1A + sint16 sprite_bottom; // 0x1C + uint8 sprite_direction; // 0x1E + uint8 pad_1F[0x09]; sint32 velocity; // 0x28 uint8 pad_2C[0x04]; uint8 ride; // 0x30 diff --git a/src/world/sprite.c b/src/world/sprite.c index ee6bb9f82c..a20e8c6bf4 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -21,6 +21,7 @@ #include #include "../addresses.h" #include "sprite.h" +#include "../interface/viewport.h" rct_sprite* g_sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); @@ -33,6 +34,48 @@ void create_balloon(int x, int y, int z, int colour) RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0); } +/* rct2: 0x006EC473 */ +void invalidate_sprite(rct_sprite* sprite){ + if (sprite->unknown.sprite_left == (sint16)0x8000) return; + + for (rct_viewport** viewport_p = RCT2_ADDRESS(RCT2_ADDRESS_ACTIVE_VIEWPORT_PTR_ARRAY, rct_viewport*); *viewport_p != NULL; viewport_p++){ + rct_viewport* viewport = *viewport_p; + int left, right, top, bottom; + left = sprite->unknown.sprite_left; + right = sprite->unknown.sprite_right; + top = sprite->unknown.sprite_top; + bottom = sprite->unknown.sprite_bottom; + + if (viewport->zoom >= 3)continue; + if (right <= viewport->view_x)continue; + if (bottom <= viewport->view_y) continue; + + int viewport_right = viewport->view_x + viewport->view_width; + int viewport_bottom = viewport->view_y + viewport->view_height; + + if (left >= viewport_right)continue; + if (top >= viewport_bottom)continue; + + left = max(left, viewport->view_x); + right = min(right, viewport_right); + top = max(top, viewport->view_y); + bottom = min(bottom, viewport_bottom); + + left -= viewport->view_x; + top -= viewport->view_y; + right -= viewport->view_x; + bottom -= viewport->view_y; + + int zoom = 1 << viewport->zoom; + left /= zoom; + top /= zoom; + right /= zoom; + bottom /= zoom; + + gfx_set_dirty_blocks(left + viewport->x, top + viewport->y, right + viewport->x, bottom + viewport->y); + } +} + /* * * rct2: 0x0069EB13 @@ -142,7 +185,7 @@ rct_sprite *create_sprite(uint8 bl) sprite->pad_09 = 0x14; sprite->var_15 = 0x8; sprite->pad_0C[0] = 0x0; - sprite->var_16 = SPRITE_LOCATION_NULL; + sprite->sprite_left = SPRITE_LOCATION_NULL; sprite->var_02 = RCT2_GLOBAL(0xF3EF60, uint16); RCT2_GLOBAL(0xF3EF60, uint16) = sprite->sprite_index; @@ -247,7 +290,7 @@ void sub_69E9D3(int x, int y, int z, rct_sprite* sprite){ } if (x == 0x8000){ - sprite->unknown.var_16 = 0x8000; + sprite->unknown.sprite_left = 0x8000; sprite->unknown.x = x; sprite->unknown.y = y; sprite->unknown.z = z; @@ -273,10 +316,10 @@ void sub_69E9D3(int x, int y, int z, rct_sprite* sprite){ break; } - sprite->unknown.var_16 = new_x - sprite->unknown.var_14; - sprite->unknown.var_1A = new_x + sprite->unknown.var_14; - sprite->unknown.var_18 = new_y - sprite->unknown.pad_09; - sprite->unknown.var_1C = new_y + sprite->unknown.var_15; + sprite->unknown.sprite_left = new_x - sprite->unknown.var_14; + sprite->unknown.sprite_right = new_x + sprite->unknown.var_14; + sprite->unknown.sprite_top = new_y - sprite->unknown.pad_09; + sprite->unknown.sprite_bottom = new_y + sprite->unknown.var_15; sprite->unknown.x = x; sprite->unknown.y = y; sprite->unknown.z = z; diff --git a/src/world/sprite.h b/src/world/sprite.h index 39a4511d87..c39f4fa43a 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -59,10 +59,10 @@ typedef struct { sint16 z; // 0x12 uint8 var_14; // 0x14 uint8 var_15; // 0x15 - sint16 var_16; //x related - sint16 var_18; //y related - sint16 var_1A; //x related - sint16 var_1C; //y related + sint16 sprite_left; // 0x16 + sint16 sprite_top; // 0x18 + sint16 sprite_right; // 0x1A + sint16 sprite_bottom; // 0x1C uint8 sprite_direction; //direction of sprite? 0x1e uint8 pad_1F[3]; // 0x1f uint16 name_string_idx; // 0x22 @@ -104,5 +104,6 @@ void move_sprite_to_list(rct_sprite *sprite, uint8 cl); void texteffect_update_all(); void sub_69E9D3(int x, int y, int z, rct_sprite* sprite); void balloon_pop(rct_sprite *sprite); +void invalidate_sprite(rct_sprite* sprite); #endif