diff --git a/src/drawing/Rain.h b/src/drawing/Rain.h index 4f78a002b4..89d6194bec 100644 --- a/src/drawing/Rain.h +++ b/src/drawing/Rain.h @@ -20,4 +20,4 @@ interface IRainDrawer; -void DrawRain(IRainDrawer * rainDrawer); +void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer); diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index f79ad298fa..4d911275f7 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -28,7 +28,6 @@ int gLastDrawStringX; int gLastDrawStringY; rct_drawpixelinfo gScreenDPI; -rct_drawpixelinfo gWindowDPI; uint8 gGamePalette[256 * 4]; uint32 gPaletteEffectFrame; @@ -181,23 +180,22 @@ void gfx_invalidate_screen() void gfx_redraw_screen_rect(short left, short top, short right, short bottom) { rct_drawpixelinfo *screenDPI = &gScreenDPI; - rct_drawpixelinfo *windowDPI = &gWindowDPI; - 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; + rct_drawpixelinfo windowDPI; + 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; + windowDPI.zoom_level = 0; for (rct_window *w = g_window_list; w < gWindowNextSlot; w++) { - if (w->flags & WF_TRANSPARENT) - continue; - if (right <= w->x || bottom <= w->y) - continue; - if (left >= w->x + w->width || top >= w->y + w->height) - continue; - window_draw(w, left, top, right, bottom); + if (w->flags & WF_TRANSPARENT) continue; + if (right <= w->x || bottom <= w->y) continue; + if (left >= w->x + w->width || top >= w->y + w->height) continue; + + window_draw(&windowDPI, w, left, top, right, bottom); } } diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 41e5b9f86c..c81e487a35 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -114,7 +114,6 @@ extern rct_g1_element *g1Elements; extern rct_gx g2; extern rct_drawpixelinfo gScreenDPI; -extern rct_drawpixelinfo gWindowDPI; // bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int x, int y, int width, int height); @@ -187,6 +186,8 @@ void ttf_dispose(); void scrolling_text_initialise_bitmaps(); int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode); +void rct2_draw(rct_drawpixelinfo *dpi); + #include "NewDrawing.h" #endif diff --git a/src/drawing/engines/OpenGLDrawingEngine.cpp b/src/drawing/engines/OpenGLDrawingEngine.cpp index b54503a00b..b47ea9cbb3 100644 --- a/src/drawing/engines/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/OpenGLDrawingEngine.cpp @@ -181,7 +181,7 @@ public: gfx_draw_pickedup_peep(&_bitsDPI); - rct2_draw(); + rct2_draw(&_bitsDPI); Display(); } diff --git a/src/drawing/engines/SoftwareDrawingEngine.cpp b/src/drawing/engines/SoftwareDrawingEngine.cpp index 74a34fdc39..ffabb4cd8c 100644 --- a/src/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/drawing/engines/SoftwareDrawingEngine.cpp @@ -304,9 +304,9 @@ public: gfx_draw_pickedup_peep(&_bitsDPI); gfx_invalidate_pickedup_peep(); - DrawRain(&_rainDrawer); + DrawRain(&_bitsDPI, &_rainDrawer); - rct2_draw(); + rct2_draw(&_bitsDPI); Display(); } diff --git a/src/drawing/rain.cpp b/src/drawing/rain.cpp index 23afdc0b23..92384c76e4 100644 --- a/src/drawing/rain.cpp +++ b/src/drawing/rain.cpp @@ -152,13 +152,12 @@ static void DrawRainWindow(IRainDrawer * rainDrawer, * * rct2: 0x00684266 */ -static void DrawRainAnimation(IRainDrawer * rainDrawer, uint32 rainType) +static void DrawRainAnimation(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer, uint32 rainType) { - rct_drawpixelinfo * screenDPI = &gScreenDPI; - sint32 left = screenDPI->x; - sint32 right = left + screenDPI->width; - sint32 top = screenDPI->y; - sint32 bottom = top + screenDPI->height; + sint32 left = dpi->x; + sint32 right = left + dpi->width; + sint32 top = dpi->y; + sint32 bottom = top + dpi->height; rct_window * newWindow = gWindowNextSlot; for (rct_window * w = g_window_list; w < newWindow; w++) @@ -171,13 +170,13 @@ static void DrawRainAnimation(IRainDrawer * rainDrawer, uint32 rainType) * * rct2: 0x00684218 */ -void DrawRain(IRainDrawer * rainDrawer) +void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer) { // Get rain draw function and draw rain uint32 rainType = gClimateCurrentRainLevel; if (rainType > 0 && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1)) { - DrawRainAnimation(rainDrawer, rainType); + DrawRainAnimation(dpi, rainDrawer, rainType); } } diff --git a/src/interface/chat.c b/src/interface/chat.c index 1461b3d9ec..a39e400f91 100644 --- a/src/interface/chat.c +++ b/src/interface/chat.c @@ -74,13 +74,12 @@ void chat_update() _chatCaretTicks = (_chatCaretTicks + 1) % 30; } -void chat_draw() +void chat_draw(rct_drawpixelinfo * dpi) { if (network_get_mode() == NETWORK_MODE_NONE || network_get_status() != NETWORK_STATUS_CONNECTED || network_get_authstatus() != NETWORK_AUTH_OK) { gChatOpen = false; return; } - rct_drawpixelinfo *dpi = &gScreenDPI; _chatLeft = 10; _chatTop = gScreenHeight - 40 - ((CHAT_HISTORY_SIZE + 1) * 10); _chatRight = gScreenWidth - 10; diff --git a/src/interface/chat.h b/src/interface/chat.h index f89175ac1b..90e9b261a3 100644 --- a/src/interface/chat.h +++ b/src/interface/chat.h @@ -28,7 +28,7 @@ void chat_toggle(); void chat_init(); void chat_update(); -void chat_draw(); +void chat_draw(rct_drawpixelinfo * dpi); void chat_history_add(const char *src); void chat_input(int c); diff --git a/src/interface/window.c b/src/interface/window.c index 20805f1d6f..74e7b3e6bd 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -73,7 +73,8 @@ float window_scroll_locations[][2] = { static bool sub_6EA95D(int x, int y, int width, int height); static void window_all_wheel_input(); -static int window_draw_split(rct_window *w, int left, int top, int right, int bottom); +static int window_draw_split(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom); +static void window_draw_single(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom); int window_get_widget_index(rct_window *w, rct_widget *widget) { @@ -1461,14 +1462,10 @@ void window_zoom_out(rct_window *w) * right (dx) * bottom (bp) */ -void window_draw(rct_window *w, int left, int top, int right, int bottom) +void window_draw(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom) { - rct_window* v; - rct_drawpixelinfo *dpi, copy; - int overflow; - // Split window into only the regions that require drawing - if (window_draw_split(w, left, top, right, bottom)) + if (window_draw_split(dpi, w, left, top, right, bottom)) return; // Clamp region @@ -1476,71 +1473,15 @@ void window_draw(rct_window *w, int left, int top, int right, int bottom) top = max(top, w->y); right = min(right, w->x + w->width); bottom = min(bottom, w->y + w->height); - if (left >= right) - return; - if (top >= bottom) - return; + if (left >= right) return; + if (top >= bottom) return; // Draw the window in this region - for (v = w; v < RCT2_NEW_WINDOW; v++) { + for (rct_window *v = w; v < RCT2_NEW_WINDOW; v++) { // Don't draw overlapping opaque windows, they won't have changed - if (w != v && !(v->flags & WF_TRANSPARENT)) - continue; - - copy = gWindowDPI; - dpi = © - - // Clamp left to 0 - overflow = left - dpi->x; - if (overflow > 0) { - dpi->x += overflow; - dpi->width -= overflow; - if (dpi->width <= 0) - continue; - dpi->pitch += overflow; - dpi->bits += overflow; + if (w == v || (v->flags & WF_TRANSPARENT)) { + window_draw_single(dpi, v, left, top, right, bottom); } - - // Clamp width to right - overflow = dpi->x + dpi->width - right; - if (overflow > 0) { - dpi->width -= overflow; - if (dpi->width <= 0) - continue; - dpi->pitch += overflow; - } - - // Clamp top to 0 - overflow = top - dpi->y; - if (overflow > 0) { - dpi->y += overflow; - dpi->height -= overflow; - if (dpi->height <= 0) - continue; - dpi->bits += (dpi->width + dpi->pitch) * overflow; - } - - // Clamp height to bottom - overflow = dpi->y + dpi->height - bottom; - if (overflow > 0) { - dpi->height -= overflow; - if (dpi->height <= 0) - continue; - } - - RCT2_GLOBAL(0x01420070, sint32) = v->x; - - // Invalidate modifies the window colours so first get the correct - // colour before setting the global variables for the string painting - window_event_invalidate_call(v); - - // Text colouring - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1, uint8) = v->colours[0] & 0x7F; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2, uint8) = v->colours[1] & 0x7F; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3, uint8) = v->colours[2] & 0x7F; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4, uint8) = v->colours[3] & 0x7F; - - window_event_paint_call(v, dpi); } } @@ -1548,7 +1489,7 @@ void window_draw(rct_window *w, int left, int top, int right, int bottom) * Splits a drawing of a window into regions that can be seen and are not hidden * by other opaque overlapping windows. */ -static int window_draw_split(rct_window *w, int left, int top, int right, int bottom) +static int window_draw_split(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom) { rct_window* topwindow; @@ -1565,20 +1506,20 @@ static int window_draw_split(rct_window *w, int left, int top, int right, int bo // A window overlaps w, split up the draw into two regions where the window starts to overlap if (topwindow->x > left) { // Split draw at topwindow.left - window_draw(w, left, top, topwindow->x, bottom); - window_draw(w, topwindow->x, top, right, bottom); + window_draw(dpi, w, left, top, topwindow->x, bottom); + window_draw(dpi, w, topwindow->x, top, right, bottom); } else if (topwindow->x + topwindow->width < right) { // Split draw at topwindow.right - window_draw(w, left, top, topwindow->x + topwindow->width, bottom); - window_draw(w, topwindow->x + topwindow->width, top, right, bottom); + window_draw(dpi, w, left, top, topwindow->x + topwindow->width, bottom); + window_draw(dpi, w, topwindow->x + topwindow->width, top, right, bottom); } else if (topwindow->y > top) { // Split draw at topwindow.top - window_draw(w, left, top, right, topwindow->y); - window_draw(w, left, topwindow->y, right, bottom); + window_draw(dpi, w, left, top, right, topwindow->y); + window_draw(dpi, w, left, topwindow->y, right, bottom); } else if (topwindow->y + topwindow->height < bottom) { // Split draw at topwindow.bottom - window_draw(w, left, top, right, topwindow->y + topwindow->height); - window_draw(w, left, topwindow->y + topwindow->height, right, bottom); + window_draw(dpi, w, left, top, right, topwindow->y + topwindow->height); + window_draw(dpi, w, left, topwindow->y + topwindow->height, right, bottom); } // Drawing for this region should be done now, exit @@ -1589,6 +1530,65 @@ static int window_draw_split(rct_window *w, int left, int top, int right, int bo return 0; } +static void window_draw_single(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom) +{ + // Copy dpi so we can crop it + rct_drawpixelinfo copy = *dpi; + dpi = © + + // Clamp left to 0 + int overflow = left - dpi->x; + if (overflow > 0) { + dpi->x += overflow; + dpi->width -= overflow; + if (dpi->width <= 0) + return; + dpi->pitch += overflow; + dpi->bits += overflow; + } + + // Clamp width to right + overflow = dpi->x + dpi->width - right; + if (overflow > 0) { + dpi->width -= overflow; + if (dpi->width <= 0) + return; + dpi->pitch += overflow; + } + + // Clamp top to 0 + overflow = top - dpi->y; + if (overflow > 0) { + dpi->y += overflow; + dpi->height -= overflow; + if (dpi->height <= 0) + return; + dpi->bits += (dpi->width + dpi->pitch) * overflow; + } + + // Clamp height to bottom + overflow = dpi->y + dpi->height - bottom; + if (overflow > 0) { + dpi->height -= overflow; + if (dpi->height <= 0) + return; + } + + RCT2_GLOBAL(0x01420070, sint32) = w->x; + + // Invalidate modifies the window colours so first get the correct + // colour before setting the global variables for the string painting + window_event_invalidate_call(w); + + // Text colouring + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1, uint8) = w->colours[0] & 0x7F; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2, uint8) = w->colours[1] & 0x7F; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3, uint8) = w->colours[2] & 0x7F; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4, uint8) = w->colours[3] & 0x7F; + + window_event_paint_call(w, dpi); +} + /** * * rct2: 0x006EB15C diff --git a/src/interface/window.h b/src/interface/window.h index 7a4dc8cc78..162a05bc6c 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -560,7 +560,7 @@ void window_zoom_out(rct_window *w); void window_show_textinput(rct_window *w, int widgetIndex, uint16 title, uint16 text, int value); void window_text_input_key(rct_window* w, int key); -void window_draw(rct_window *w, int left, int top, int right, int bottom); +void window_draw(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom); void window_draw_widgets(rct_window *w, rct_drawpixelinfo *dpi); void window_draw_viewport(rct_drawpixelinfo *dpi, rct_window *w); diff --git a/src/openrct2.c b/src/openrct2.c index 98da7704fc..bf698d6732 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -418,7 +418,6 @@ static void openrct2_loop() } if ((SDL_GetWindowFlags(gWindow) & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_HIDDEN)) == 0) { - // rct2_draw(); platform_draw(); } @@ -454,7 +453,6 @@ static void openrct2_loop() rct2_update(); if ((SDL_GetWindowFlags(gWindow) & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_HIDDEN)) == 0) { - rct2_draw(); platform_draw(); } } @@ -591,11 +589,6 @@ bool openrct2_setup_rct2_segment() */ static void openrct2_setup_rct2_hooks() { - addhook(0x006E732D, (int)gfx_set_dirty_blocks, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0, 0); // remove when all callers are decompiled - addhook(0x006E7499, (int)gfx_redraw_screen_rect, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0, 0); // remove when 0x6E7FF3 is decompiled - addhook(0x006B752C, (int)ride_crash, 0, (int[]){ EDX, EBX, END }, 0, 0); // remove when all callers are decompiled - addhook(0x0069A42F, (int)peep_window_state_update, 0, (int[]){ ESI, END }, 0, 0); // remove when all callers are decompiled - addhook(0x006BB76E, (int)audio_play_sound_panned, 0, (int[]){EAX, EBX, ECX, EDX, EBP, END}, 0, EAX); // remove when all callers are decompiled addhook(0x006C42D9, (int)scrolling_text_setup, 0, (int[]){EAX, ECX, EBP, END}, 0, EBX); // remove when all callers are decompiled addhook(0x006C2321, (int)gfx_get_string_width, 0, (int[]){ESI, END}, 0, ECX); // remove when all callers are decompiled addhook(0x006C2555, (int)format_string, 0, (int[]){EDI, EAX, ECX, END}, 0, 0); // remove when all callers are decompiled diff --git a/src/rct2.c b/src/rct2.c index 6be1916319..b4268ca440 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -121,7 +121,7 @@ void print_launch_information(); int rct2_init_directories(); int rct2_startup_checks(); -static void rct2_draw_fps(); +static void rct2_draw_fps(rct_drawpixelinfo *dpi); void rct2_quit() { @@ -273,7 +273,7 @@ int rct2_startup_checks() return 1; } -void rct2_draw() +void rct2_draw(rct_drawpixelinfo *dpi) { if (gIntroState != INTRO_STATE_NONE) { return; @@ -286,15 +286,15 @@ void rct2_draw() // update_rain_animation(); update_palette_effects(); - chat_draw(); - console_draw(&gScreenDPI); + chat_draw(dpi); + console_draw(dpi); if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) { - DrawOpenRCT2(0, gScreenHeight - 20); + DrawOpenRCT2(dpi, 0, gScreenHeight - 20); } if (gConfigGeneral.show_fps) { - rct2_draw_fps(); + rct2_draw_fps(dpi); } gCurrentDrawCount++; @@ -317,9 +317,8 @@ static float rct2_measure_fps() return _currentFPS; } -static void rct2_draw_fps() +static void rct2_draw_fps(rct_drawpixelinfo *dpi) { - rct_drawpixelinfo *dpi = &gScreenDPI; int x = gScreenWidth / 2; int y = 2; diff --git a/src/rct2.h b/src/rct2.h index 14955173b3..9d75f717fe 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -282,7 +282,6 @@ extern sint32 gScreenHeight; int rct2_init(); void rct2_dispose(); void rct2_update(); -void rct2_draw(); void substitute_path(char *dest, const char *path, const char *filename); int check_mutex(); int check_file_paths(); diff --git a/src/title.c b/src/title.c index 4d212b337b..f1ad746792 100644 --- a/src/title.c +++ b/src/title.c @@ -490,10 +490,9 @@ static void title_update_showcase() } while (gTitleScriptSkipTo != -1 && gTitleScriptSkipLoad == -1); } -void DrawOpenRCT2(int x, int y) +void DrawOpenRCT2(rct_drawpixelinfo *dpi, int x, int y) { utf8 buffer[256]; - rct_drawpixelinfo *dpi = &gScreenDPI; // Draw background gfx_fill_rect_inset(dpi, x, y, x + 128, y + 20, TRANSLUCENT(COLOUR_DARK_GREEN), 0x8); diff --git a/src/title.h b/src/title.h index a60b6ddab5..03cd06aadf 100644 --- a/src/title.h +++ b/src/title.h @@ -45,6 +45,6 @@ void title_skip_from_beginning(); void title_script_get_line(SDL_RWops *file, char *parts); bool title_refresh_sequence(); void title_fix_location(); -void DrawOpenRCT2(int x, int y); +void DrawOpenRCT2(rct_drawpixelinfo *dpi, int x, int y); #endif