From 1a857edc21861d9039b19229ee80f4c6ebe71c44 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 4 Nov 2014 22:23:57 +0000 Subject: [PATCH 1/5] Playing about with viewport setup --- src/drawing/drawing.c | 17 ++++++++++++++++- src/game.c | 2 +- src/interface/viewport.c | 9 ++++++++- src/windows/viewport.c | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index a6ddf2073d..e937c6fd8e 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -338,7 +338,7 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) rct_drawpixelinfo *windowDPI = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_DPI, rct_drawpixelinfo); // Unsure what this does - RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0); + //RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0); windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top); windowDPI->x = left; @@ -348,6 +348,21 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right; for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) { + if (w->viewport != NULL && w != g_window_list){ + windowDPI->bits = screenDPI->bits + w->viewport->x + ((screenDPI->width + screenDPI->pitch)* w->viewport->y); + windowDPI->x = w->viewport->x; + windowDPI->y = w->viewport->y; + windowDPI->width = w->viewport->width; + windowDPI->height = w->viewport->height; + windowDPI->pitch = screenDPI->width + screenDPI->pitch - w->viewport->width; + window_draw(w, w->viewport->x, w->viewport->y, w->viewport->x + w->viewport->width, w->viewport->y + w->viewport->height); + windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top); + windowDPI->x = left; + windowDPI->y = top; + windowDPI->width = right - left; + windowDPI->height = bottom - top; + windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right; + } if (w->flags & WF_TRANSPARENT) continue; if (right <= w->x || bottom <= w->y) diff --git a/src/game.c b/src/game.c index cd2ebfa732..0111ccc5f8 100644 --- a/src/game.c +++ b/src/game.c @@ -290,7 +290,7 @@ void game_logic_update() // stop viewports from failing. Remove this when real bug cause has been // found. // *********** - gfx_invalidate_screen(); + //gfx_invalidate_screen(); // *********** sub_68B089(); diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 6b7e57cb23..3a998957e6 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -402,6 +402,8 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i if (left >= viewport->x + viewport->width )return; if (top >= viewport->y + viewport->height )return; + int l = left, t = top, r = right, b = bottom; + left = max(left - viewport->x, 0); right = min(right - viewport->x, viewport->width); top = max(top - viewport->y, 0); @@ -424,7 +426,12 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i top += 384; } //Paint - viewport_paint(viewport, dpi, left, top, right, bottom); + viewport_paint(viewport, dpi, left, top, right, bottom); + + if (viewport != g_viewport_list){ + gfx_fill_rect_inset(dpi, l, t, r-1, b-1, 0x2, 0x30); + return; + } } /** diff --git a/src/windows/viewport.c b/src/windows/viewport.c index 37c7c3fd0c..b340128525 100644 --- a/src/windows/viewport.c +++ b/src/windows/viewport.c @@ -208,7 +208,7 @@ static void window_viewport_update(rct_window *w) } // Not sure how to invalidate part of the viewport that has changed, this will have to do for now - widget_invalidate(w, WIDX_VIEWPORT); + //widget_invalidate(w, WIDX_VIEWPORT); } static void window_viewport_invalidate() From 3003419160f75df1de3a40be1fd960908ba49bbb Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 5 Nov 2014 20:43:06 +0000 Subject: [PATCH 2/5] Add debug flag to dirty box draw --- src/drawing/drawing.c | 17 +---------------- src/interface/viewport.c | 4 ++++ 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index e937c6fd8e..a6ddf2073d 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -338,7 +338,7 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) rct_drawpixelinfo *windowDPI = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_DPI, rct_drawpixelinfo); // Unsure what this does - //RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0); + RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0); windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top); windowDPI->x = left; @@ -348,21 +348,6 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right; for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) { - if (w->viewport != NULL && w != g_window_list){ - windowDPI->bits = screenDPI->bits + w->viewport->x + ((screenDPI->width + screenDPI->pitch)* w->viewport->y); - windowDPI->x = w->viewport->x; - windowDPI->y = w->viewport->y; - windowDPI->width = w->viewport->width; - windowDPI->height = w->viewport->height; - windowDPI->pitch = screenDPI->width + screenDPI->pitch - w->viewport->width; - window_draw(w, w->viewport->x, w->viewport->y, w->viewport->x + w->viewport->width, w->viewport->y + w->viewport->height); - windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top); - windowDPI->x = left; - windowDPI->y = top; - windowDPI->width = right - left; - windowDPI->height = bottom - top; - windowDPI->pitch = screenDPI->width + screenDPI->pitch + left - right; - } if (w->flags & WF_TRANSPARENT) continue; if (right <= w->x || bottom <= w->y) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 3a998957e6..2bcc342357 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -33,6 +33,8 @@ #define RCT2_LAST_VIEWPORT (RCT2_GLOBAL(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*) - 1) #define RCT2_NEW_VIEWPORT (RCT2_GLOBAL(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*)) +#define DEBUG_SHOW_DIRTY_BOX + rct_viewport* g_viewport_list = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_LIST, rct_viewport); typedef struct paint_struct paint_struct; @@ -428,10 +430,12 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i //Paint viewport_paint(viewport, dpi, left, top, right, bottom); +#ifdef DEBUG_SHOW_DIRTY_BOX if (viewport != g_viewport_list){ gfx_fill_rect_inset(dpi, l, t, r-1, b-1, 0x2, 0x30); return; } +#endif } /** From 21dd6f227d3a6a848e194331707bb08a81d020d2 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 5 Nov 2014 22:12:22 +0000 Subject: [PATCH 3/5] Added some more viewport functions --- src/interface/viewport.c | 109 ++++++++++++++++++++++++++++++++++++++- src/interface/window.h | 1 + 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 2bcc342357..3e9cb8cc20 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -266,6 +266,109 @@ void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){ *z = height; } +void sub_6E7F34(rct_window* w, rct_viewport* viewport){ + //RCT2_CALLPROC_X(0x6E7F34, 0, 0, 0, 0, (int)viewport, (int)w, 0); + for (; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++){ + if (!w->flags&WF_TRANSPARENT) continue; + if (w->viewport == viewport) continue; + + if (viewport->x + viewport->width <= w->x)continue; + if (w->x + w->width <= viewport->x) continue; + + if (viewport->y + viewport->height <= w->y)continue; + if (w->y + w->height <= viewport->y) continue; + + int left = w->x; + int right = w->x + w->width; + int top = w->y; + int bottom = w->y + w->height; + + if (left >= viewport->x)left = viewport->x; + if (right >= viewport->x + viewport->width) right = viewport->x + viewport->width; + + if (top >= viewport->y)top = viewport->y; + if (bottom >= viewport->y + viewport->height) bottom = viewport->y + viewport->height; + + if (left >= right) continue; + if (top >= bottom) continue; + + gfx_redraw_screen_rect(left, top, right, bottom); + } + + RCT2_CALLPROC_X(0x6E7FF3, 0, 0, 0, 0, viewport, w, 0); +} + +void sub_6E7DE1(sint16 x, sint16 y, rct_window* w, rct_viewport* viewport){ + //RCT2_CALLPROC_X(0x6E7DE1, x, y, 0, 0, w, viewport, 0); + //return; + uint8 zoom = (1 << viewport->zoom); + + sint16 previous_x = viewport->view_x / zoom; + sint16 previous_y = viewport->view_y / zoom; + + viewport->view_x = x; + viewport->view_y = y; + + if (((x / zoom) == previous_x) && ((y / zoom) == previous_y)) return; + + if (w->flags & WF_7){ + int left = max(viewport->x, 0); + int top = max(viewport->y, 0); + int right = min(viewport->x + viewport->width, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16)); + int bottom = min(viewport->y + viewport->height, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16)); + + if (left >= right) return; + if (top >= bottom) return; + + gfx_redraw_screen_rect(left, top, right, bottom); + return; + } + + rct_viewport view_copy; + memcpy(&view_copy, viewport, sizeof(rct_viewport)); + + if (viewport->x < 0){ + viewport->width += viewport->x; + viewport->view_width += viewport->x * zoom; + viewport->view_x -= viewport->x * zoom; + viewport->x = 0; + } + + int eax = viewport->x + viewport->width - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16); + if (eax > 0){ + viewport->width -= eax; + viewport->view_width -= eax * zoom; + } + + if (viewport->width <= 0){ + memcpy( viewport, &view_copy,sizeof(rct_viewport)); + return; + } + + if (viewport->y < 0){ + viewport->height += viewport->y; + viewport->view_height += viewport->y * zoom; + viewport->view_y -= viewport->y * zoom; + viewport->y = 0; + } + + eax = viewport->y + viewport->height - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16); + if (eax > 0){ + viewport->height -= eax; + viewport->view_height -= eax * zoom; + } + + if (viewport->height <= 0){ + memcpy(viewport, &view_copy, sizeof(rct_viewport)); + return; + } + + sub_6E7F34(w, viewport); + //RCT2_CALLPROC_X(0x6E7F34, 0, 0, 0, 0, (int)viewport, (int)w, 0); + + memcpy(viewport, &view_copy, sizeof(rct_viewport)); +} + /** * * rct2: 0x006E7A3A @@ -290,7 +393,8 @@ void viewport_update_position(rct_window *window) int center_x, center_y; center_2d_coordinates(sprite->unknown.x, sprite->unknown.y, sprite->unknown.z, ¢er_x, ¢er_y, window->viewport); - RCT2_CALLPROC_X(0x6E7DE1, center_x, center_y, 0, 0, (int)window, (int)viewport, 0); + sub_6E7DE1(center_x, center_y, window, viewport); + //RCT2_CALLPROC_X(0x6E7DE1, center_x, center_y, 0, 0, (int)window, (int)viewport, 0); return; } @@ -382,7 +486,8 @@ void viewport_update_position(rct_window *window) y += viewport->view_y; } - RCT2_CALLPROC_X(0x6E7DE1, x, y, 0, 0, (int)window, (int)viewport, 0); + sub_6E7DE1(x, y, window, viewport); + //RCT2_CALLPROC_X(0x6E7DE1, x, y, 0, 0, (int)window, (int)viewport, 0); } void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, int top, int right, int bottom); diff --git a/src/interface/window.h b/src/interface/window.h index 80ac18adeb..69f89bebed 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -295,6 +295,7 @@ typedef enum { WF_SCROLLING_TO_LOCATION = (1 << 3), WF_TRANSPARENT = (1 << 4), WF_5 = (1 << 5), + WF_7 = (1 << 7), WF_RESIZABLE = (1 << 8), WF_9 = (1 << 9), WF_10 = (1 << 10), From f3da25622aef74b9cae3df8a550dd6ca39657740 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 6 Nov 2014 17:27:10 +0000 Subject: [PATCH 4/5] Added start of new function --- src/interface/viewport.c | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 3e9cb8cc20..9a26119f5b 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -266,8 +266,45 @@ void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){ *z = height; } +// This function also needs edx, ebp +void sub_6E7FF3(rct_window* w, rct_viewport* viewport, int x, int y){ + int zoom = 1 << viewport->zoom; + if (w >= RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*)){ + if (viewport != w->viewport){ + if ((viewport->x + viewport->width > w->x) && + (w->x + w->width > viewport->x) && + (viewport->y + viewport->height > w->y) && + (w->y + w->height > viewport->y)){ + if (viewport->x < w->x){ + rct_viewport viewport_bkup; + memcpy(&viewport_bkup, viewport, sizeof(rct_viewport)); + + viewport->width = w->x - viewport->x; + viewport->view_width = (w->x - viewport->x) * zoom; + + sub_6E7FF3(w, viewport, x, y); + + viewport->x += viewport->width; + viewport->view_x += viewport->width*zoom; + viewport->view_width = (viewport_bkup.width - viewport->width) * zoom; + viewport->width = viewport_bkup.width - viewport->width; + + sub_6E7FF3(w, viewport, x, y); + + memcpy(viewport, &viewport_bkup, sizeof(rct_viewport)); + return; + }//x6E80C4 + }//0x6E824a + } // 0x6e824a + }//x6e8255 + +} + void sub_6E7F34(rct_window* w, rct_viewport* viewport){ //RCT2_CALLPROC_X(0x6E7F34, 0, 0, 0, 0, (int)viewport, (int)w, 0); + rct_window* orignal_w = w; + int left = 0, right = 0, top = 0, bottom = 0; + for (; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++){ if (!w->flags&WF_TRANSPARENT) continue; if (w->viewport == viewport) continue; @@ -278,10 +315,10 @@ void sub_6E7F34(rct_window* w, rct_viewport* viewport){ if (viewport->y + viewport->height <= w->y)continue; if (w->y + w->height <= viewport->y) continue; - int left = w->x; - int right = w->x + w->width; - int top = w->y; - int bottom = w->y + w->height; + left = w->x; + right = w->x + w->width; + top = w->y; + bottom = w->y + w->height; if (left >= viewport->x)left = viewport->x; if (right >= viewport->x + viewport->width) right = viewport->x + viewport->width; @@ -295,7 +332,8 @@ void sub_6E7F34(rct_window* w, rct_viewport* viewport){ gfx_redraw_screen_rect(left, top, right, bottom); } - RCT2_CALLPROC_X(0x6E7FF3, 0, 0, 0, 0, viewport, w, 0); + w = orignal_w; + RCT2_CALLPROC_X(0x6E7FF3, 0, 0, 0, right, viewport, w, bottom); } void sub_6E7DE1(sint16 x, sint16 y, rct_window* w, rct_viewport* viewport){ From 2ddbc8f19067a04731b943694ada0d146346af07 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 6 Nov 2014 21:42:18 +0000 Subject: [PATCH 5/5] Found cause of viewport issue. Added invalidate_sprite function. --- src/game.c | 7 ---- src/interface/viewport.c | 74 +++++++++++++++++------------------ src/peep/peep.c | 84 ++++++++++++++++++++++++++++++---------- 3 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/game.c b/src/game.c index 0111ccc5f8..a194780414 100644 --- a/src/game.c +++ b/src/game.c @@ -286,13 +286,6 @@ void game_logic_update() if (RCT2_GLOBAL(0x009DEA66, sint16) == 0) RCT2_GLOBAL(0x009DEA66, sint16)--; - // This is a hack for now to force a complete rerender of the screen to - // stop viewports from failing. Remove this when real bug cause has been - // found. - // *********** - //gfx_invalidate_screen(); - // *********** - sub_68B089(); scenario_update(); climate_update(); diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 9a26119f5b..5bddfcbf2a 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -33,7 +33,7 @@ #define RCT2_LAST_VIEWPORT (RCT2_GLOBAL(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*) - 1) #define RCT2_NEW_VIEWPORT (RCT2_GLOBAL(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*)) -#define DEBUG_SHOW_DIRTY_BOX +//#define DEBUG_SHOW_DIRTY_BOX rct_viewport* g_viewport_list = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_LIST, rct_viewport); @@ -214,8 +214,9 @@ void viewport_update_pointers() rct_viewport *viewport; rct_viewport **vp = RCT2_ADDRESS(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*); - if (*vp == NULL) *vp = g_viewport_list; - for (viewport = g_viewport_list; viewport <= RCT2_NEW_VIEWPORT; viewport++) + // The last possible viewport entry is 1 before what is the new_viewport_ptr + // This is why it is rct_viewport and not rct_viewport*. + for (viewport = g_viewport_list; viewport < RCT2_ADDRESS(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport); viewport++) if (viewport->width != 0) *vp++ = viewport; @@ -266,39 +267,38 @@ void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){ *z = height; } -// This function also needs edx, ebp -void sub_6E7FF3(rct_window* w, rct_viewport* viewport, int x, int y){ - int zoom = 1 << viewport->zoom; - if (w >= RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*)){ - if (viewport != w->viewport){ - if ((viewport->x + viewport->width > w->x) && - (w->x + w->width > viewport->x) && - (viewport->y + viewport->height > w->y) && - (w->y + w->height > viewport->y)){ - if (viewport->x < w->x){ - rct_viewport viewport_bkup; - memcpy(&viewport_bkup, viewport, sizeof(rct_viewport)); - - viewport->width = w->x - viewport->x; - viewport->view_width = (w->x - viewport->x) * zoom; - - sub_6E7FF3(w, viewport, x, y); - - viewport->x += viewport->width; - viewport->view_x += viewport->width*zoom; - viewport->view_width = (viewport_bkup.width - viewport->width) * zoom; - viewport->width = viewport_bkup.width - viewport->width; - - sub_6E7FF3(w, viewport, x, y); - - memcpy(viewport, &viewport_bkup, sizeof(rct_viewport)); - return; - }//x6E80C4 - }//0x6E824a - } // 0x6e824a - }//x6e8255 - -} +//void sub_6E7FF3(rct_window* w, rct_viewport* viewport, int x, int y){ +// int zoom = 1 << viewport->zoom; +// if (w >= RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*)){ +// if (viewport != w->viewport){ +// if ((viewport->x + viewport->width > w->x) && +// (w->x + w->width > viewport->x) && +// (viewport->y + viewport->height > w->y) && +// (w->y + w->height > viewport->y)){ +// if (viewport->x < w->x){ +// rct_viewport viewport_bkup; +// memcpy(&viewport_bkup, viewport, sizeof(rct_viewport)); +// +// viewport->width = w->x - viewport->x; +// viewport->view_width = (w->x - viewport->x) * zoom; +// +// sub_6E7FF3(w, viewport, x, y); +// +// viewport->x += viewport->width; +// viewport->view_x += viewport->width*zoom; +// viewport->view_width = (viewport_bkup.width - viewport->width) * zoom; +// viewport->width = viewport_bkup.width - viewport->width; +// +// sub_6E7FF3(w, viewport, x, y); +// +// memcpy(viewport, &viewport_bkup, sizeof(rct_viewport)); +// return; +// }//x6E80C4 +// }//0x6E824a +// } // 0x6e824a +// }//x6e8255 +// +//} void sub_6E7F34(rct_window* w, rct_viewport* viewport){ //RCT2_CALLPROC_X(0x6E7F34, 0, 0, 0, 0, (int)viewport, (int)w, 0); @@ -333,7 +333,7 @@ void sub_6E7F34(rct_window* w, rct_viewport* viewport){ } w = orignal_w; - RCT2_CALLPROC_X(0x6E7FF3, 0, 0, 0, right, viewport, w, bottom); + RCT2_CALLPROC_X(0x6E7FF3, 0, 0, 0, right, (int)viewport, (int)w, bottom); } void sub_6E7DE1(sint16 x, sint16 y, rct_window* w, rct_viewport* viewport){ diff --git a/src/peep/peep.c b/src/peep/peep.c index 0571b422a5..13691c1585 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -107,6 +107,48 @@ void peep_update_all() } } +/* rct2: 0x006EC473 */ +void invalidate_sprite(rct_peep* peep){ + if (peep->var_16 == (sint16)0x8000) return; + + // Note this function is different to original perhaps change back (part of viewport testing) + for (rct_viewport* viewport = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_LIST, rct_viewport); viewport < RCT2_ADDRESS(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport) && viewport->width; viewport++){ + 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; @@ -163,14 +205,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep); *x = peep->x; *y = peep->y; return 1; } peep->var_70 = ebx; if (peep->var_71 != 8 || peep->var_71 != 15){ - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep); *x = peep->x; *y = peep->y; return 1; @@ -192,7 +234,7 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ sound_play_panned(sound_id, 0x8001, peep->x, peep->y, peep->z); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; *x = peep->x; *y = peep->y; return 1; @@ -310,7 +352,7 @@ void peep_update_falling(rct_peep* peep){ if (height - 4 >= peep->z && height < peep->z + 20){ // Looks like we are drowning! - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; sub_69E9D3(peep->x, peep->y, height, (rct_sprite*)peep); // Drop balloon if held if (peep->item_standard_flags & PEEP_ITEM_BALLOON){ @@ -330,7 +372,7 @@ void peep_update_falling(rct_peep* peep){ peep->var_70 = 0; RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; peep_window_state_update(peep); return; } @@ -345,20 +387,20 @@ void peep_update_falling(rct_peep* peep){ // This will be null if peep is falling if (saved_map == NULL){ - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; return; } - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; sub_69E9D3(peep->x, peep->y, saved_height, (rct_sprite*)peep); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; peep->next_x = peep->x & 0xFFE0; peep->next_y = peep->y & 0xFFE0; @@ -412,11 +454,11 @@ void peep_update_sitting(rct_peep* peep){ int y = peep->y & 0xFFE0 + RCT2_ADDRESS(0x981F2E, uint16)[ebx * 2]; int z = peep->z; - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; sub_69E9D3(x, y, z, (rct_sprite*)peep); peep->sprite_direction = ((peep->var_37 + 2) & 3) * 8; - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; peep->var_71 = 254; peep->var_6F = 7; RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0); @@ -466,7 +508,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; return; } @@ -491,7 +533,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; return; } } @@ -525,7 +567,7 @@ void peep_update_queuing(rct_peep* peep){ } //Give up queueing for the ride peep->sprite_direction ^= (1 << 4); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; @@ -541,7 +583,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; } if (peep->var_7A >= 3500 && (0xFFFF & scenario_rand()) <= 93) { @@ -579,7 +621,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; break; } } @@ -589,7 +631,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; @@ -622,9 +664,9 @@ static void peep_update_entering_park(rct_peep* peep){ } sint16 x = 0, y = 0; if (sub_6939EB(&x, &y, peep)){ - RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep); sub_69E9D3(x, y, peep->z, (rct_sprite*)peep); - RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep); return; } peep_decrement_num_riders(peep); @@ -1048,7 +1090,7 @@ void peep_applause() peep->var_72 = 0; peep->var_70 = 0; RCT2_CALLPROC_X(0x00693B58, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep); } } @@ -1432,7 +1474,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); - RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite(peep);; } for (int i = 0; i < PEEP_MAX_THOUGHTS; ++i){