1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

optimise drawing

This commit is contained in:
IntelOrca
2014-04-10 18:41:35 +01:00
parent 32dec4ab52
commit ee2b89a1b4
6 changed files with 55 additions and 29 deletions

View File

@@ -59,6 +59,11 @@
#define RCT2_ADDRESS_SCREEN_WIDTH 0x009ABDD8
#define RCT2_ADDRESS_SCREEN_HEIGHT 0x009ABDDA
#define RCT2_ADDRESS_DIRTY_BLOCK_WIDTH 0x009ABDE4
#define RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT 0x009ABDE6
#define RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS 0x009ABDE8
#define RCT2_ADDRESS_DIRTY_BLOCK_ROWS 0x009ABDEC
#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319
#define RCT2_ADDRESS_INPUT_STATE 0x009DE51D

View File

@@ -28,6 +28,8 @@
uint8 _screenDirtyBlocks[5120];
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows);
/**
*
* rct2: 0x00678998
@@ -219,43 +221,61 @@ void gfx_set_dirty_blocks(int left, int top, int right, int bottom)
}
/**
*
* rct2: 0x006E73BE
*/
void gfx_draw_dirty_blocks()
*
* rct2: 0x006E73BE
*/
void gfx_draw_all_dirty_blocks()
{
int i, x, y, yy, yyy;
int x, y, xx, yy, columns, rows;
short left, top, right, bottom;
uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
x = y = i = 0;
for (x = 0; x < RCT2_GLOBAL(0x009ABDE8, sint32); x++) {
for (y = 0; y < RCT2_GLOBAL(0x009ABDEC, sint32); y++) {
if (screenDirtyBlocks[y * RCT2_GLOBAL(0x009ABDE8, sint32) + x] == 0)
for (x = 0; x < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); x++) {
for (y = 0; y < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); y++) {
if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + x] == 0)
continue;
for (yy = y; yy < RCT2_GLOBAL(0x009ABDEC, sint32); yy++)
if (screenDirtyBlocks[yy * RCT2_GLOBAL(0x009ABDE8, sint32) + x] == 0)
// Determine columns
for (xx = x; xx < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32); xx++)
if (screenDirtyBlocks[y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
break;
yy--;
columns = xx - x;
// Reset the dirty blocks
for (yyy = y; yyy <= yy; yyy += RCT2_GLOBAL(0x009ABDE8, sint32))
screenDirtyBlocks[yyy * RCT2_GLOBAL(0x009ABDE8, sint32) + x] = 0;
left = x * RCT2_GLOBAL(0x009ABDE4, sint16);
top = y * RCT2_GLOBAL(0x009ABDE6, sint16);
right = ((x + 1) * RCT2_GLOBAL(0x009ABDE4, sint16));
bottom = ((yy + 1) * RCT2_GLOBAL(0x009ABDE4, sint16));
if (left < RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) && top < RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16)) {
right = min(right, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16));
bottom = min(bottom, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16));
gfx_redraw_screen_rect(left, top, right, bottom);
}
// Check rows
for (yy = y; yy < RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_ROWS, sint32); yy++)
for (xx = x; xx < x + columns; xx++)
if (screenDirtyBlocks[yy * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + xx] == 0)
goto endRowCheck;
endRowCheck:
rows = yy - y;
gfx_draw_dirty_blocks(x, y, columns, rows);
}
}
}
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows)
{
int left, top, right, bottom;
uint8 *screenDirtyBlocks = RCT2_ADDRESS(0x00EDE408, uint8);
// Unset dirty blocks
for (top = y; top < y + rows; top++)
for (left = x; left < x + columns; left++)
screenDirtyBlocks[top * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS, sint32) + left] = 0;
// Determine region in pixels
left = max(0, x * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16));
top = max(0, y * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16));
right = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), left + (columns * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_WIDTH, sint16)));
bottom = min(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16), top + (rows * RCT2_GLOBAL(RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT, sint16)));
if (right <= left || bottom <= top)
return;
// Draw region
gfx_redraw_screen_rect(left, top, right, bottom);
}
/**
*
* rct2: 0x006E7499

View File

@@ -68,7 +68,7 @@ int clip_text(char *buffer, int width);
void gfx_fill_rect_inset(rct_drawpixelinfo *dpi, short left, short top, short right, short bottom, int colour, short _si);
void gfx_set_dirty_blocks(int left, int top, int right, int bottom);
void gfx_draw_dirty_blocks();
void gfx_draw_all_dirty_blocks();
void gfx_redraw_screen_rect(short left, short top, short right, short bottom);
void gfx_invalidate_screen();

View File

@@ -33,6 +33,7 @@
#include "intro.h"
#include "map.h"
#include "news_item.h"
#include "object.h"
#include "osinterface.h"
#include "park.h"
#include "rct2.h"
@@ -106,7 +107,7 @@ void rct2_init()
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = 0;
config_load();
// RCT2_CALLPROC_EBPSAFE(0x00674B81); // pointless expansion pack crap
RCT2_CALLPROC_EBPSAFE(0x006A8B40); // object_load_list()
object_load_list();
scenario_load_list();
RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, 253, 0, 0, 0); // track_load_list(253)
gfx_load_g1();

View File

@@ -241,7 +241,7 @@ static void scenario_scores_save()
HANDLE hFile;
DWORD bytes_written;
hFile = CreateFile(get_file_path(32), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
hFile = CreateFile(get_file_path(PATH_ID_SCORES), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
WriteFile(hFile, (void*)0x009A9FFC, 16, &bytes_written, NULL);

View File

@@ -63,7 +63,7 @@ void window_update_all()
if (RCT2_GLOBAL(0x009ABDF2, sint8) == 0)
return;
gfx_draw_dirty_blocks();
gfx_draw_all_dirty_blocks();
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++)
if (w->viewport != NULL)