From 5fd4025b9b6ccc2b616eb33ba90f42ed3e389c0b Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 21 Feb 2016 12:02:29 +0100 Subject: [PATCH 01/26] Decompile first path --- src/interface/viewport.c | 120 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 4f5c0827b2..c9ee8da855 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2636,8 +2636,126 @@ void store_interaction_info(paint_struct *ps) * * rct2: 0x00679074 */ -void sub_679074(rct_drawpixelinfo *dpi, int imageId, int x, int y) +void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { + rct_g1_element image = g1Elements[imageId & 0x7FFFF]; + + switch (dpi->zoom_level) { + case 0: + // TODO: loc_6790A0: + break; + + case 1: + if (image.flags & 0x20) { + return; + } + + if (!(image.flags & 0x10)) { + dpi->zoom_level--; + dpi->x /= 2; + dpi->y /= 2; + + sub_679074(dpi, imageId - image.zoomed_offset, x / 2, y / 2); + + dpi->zoom_level++; + dpi->x *= 2; + dpi->y *= 2; + + return; + } + + RCT2_GLOBAL(0x9E3D08, uint32) = image.offset; + RCT2_GLOBAL(0x9E3D0C, uint32) = image.width; + RCT2_GLOBAL(0x9E3D10, uint32) = image.x_offset; + RCT2_GLOBAL(0x9E3D14, uint32) = image.flags; + + if (image.flags & 4) { + // push edi + y--; + // ebp = edi; + // esi = image.offset; + y += image.x_offset; + + uint16 width = image.width; + RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, uint32) = 0; + if (width % 2) { + width--; + if (width == 0) { + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, uint32)++; + } + + + // TODO: (y = y/2?) + y &= 0xFFFE; + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = width; + y -= dpi->y; + + if (y < 0) { + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) += y; + if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, sint16) -= y; + y = 0; + } + + y += RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16); + y--; + + if (y > 0) { + // inverse of JLE + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) -= y; + + if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + } + + sint16 ax = image.width; + RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = ax; + x += image.x_offset; + x &= 0xFFFE; + x -= dpi->x; + if (x < 0) { + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) += x; + if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) -= x; + x = 0; + } + + x += RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16); + x--; + if (x > 0) { + // inverse of JLE + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) -= x; + + if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + } + + RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, image.offset, (int) dpi, (int) dpi); + return; + } + break; + + case 2: + // TODO: loc_6798F5 + break; + + default: + // TODO: loc_679DEE + break; + } + RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int)dpi, 0); } From 8f1c7ff0640b3274d3c2b3b8329f1d080f825230 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 21 Feb 2016 18:58:11 +0100 Subject: [PATCH 02/26] Continue decompiling --- src/interface/viewport.c | 112 +++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 11 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index c9ee8da855..579d96882e 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2665,22 +2665,25 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } RCT2_GLOBAL(0x9E3D08, uint32) = image.offset; - RCT2_GLOBAL(0x9E3D0C, uint32) = image.width; - RCT2_GLOBAL(0x9E3D10, uint32) = image.x_offset; - RCT2_GLOBAL(0x9E3D14, uint32) = image.flags; + RCT2_GLOBAL(0x9E3D0C, sint16) = image.width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image.height; + RCT2_GLOBAL(0x9E3D10, sint16) = image.x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image.y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image.flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image.zoomed_offset; if (image.flags & 4) { // push edi y--; // ebp = edi; // esi = image.offset; - y += image.x_offset; + y += image.y_offset; - uint16 width = image.width; + uint16 height = image.height; RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, uint32) = 0; - if (width % 2) { - width--; - if (width == 0) { + if (height % 2) { + height--; + if (height == 0) { return; } @@ -2690,7 +2693,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // TODO: (y = y/2?) y &= 0xFFFE; - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = width; + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = height; y -= dpi->y; if (y < 0) { @@ -2715,9 +2718,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint16 ax = image.width; + sint16 width = image.width; RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = ax; + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = width; x += image.x_offset; x &= 0xFFFE; x -= dpi->x; @@ -2744,6 +2747,93 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, image.offset, (int) dpi, (int) dpi); return; + } else { + // push edi + // ebp = edi; + //esi = image.offset; + uint32 esi = image.offset; + y += image.y_offset; + sint16 height = image.height; + if (height % 2) { + sint16 ebx = image.width; + height--; + + esi += ebx; + } + + if (height == 0) { + return; + } + + y &= 0xFFFE; + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = height; + y -= image.height; + if (y < 0) { + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) += y; + if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + + y = -y; + esi += (y * image.width) & 0xFFFF; + y = 0; + } else { + // Do nothing? + } + + y += RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16); + y--; + + if (y > 0) { + RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) -= y; + if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + } + + sint16 ax = image.width; + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = ax; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image.x_offset; + x = floor2(x, 2); + x -= dpi->x; + + if (x < 0) { + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) += x; + if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + + esi -= x; + x = 0; + } + + + x += RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16); + x--; + if (x > 0) { + RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) -= x; + if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } + + // Or is this the 'flags' part? + if (!(image.zoomed_offset & (1 << 1))) { + sint8 ah = (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + int ebx = RCT2_GLOBAL(0x00EDF81C, uint32) = 0; + + // ah and edx don't seem to be used by this function... + RCT2_CALLPROC_X(0x00679662, 0, ebx, 0, 0, esi, 0, 0); + return; + } + + // loc_6795E4: } break; From db7b624b6e7ca045b69911a8b88bade8f5498a29 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Mon, 22 Feb 2016 23:05:54 +0100 Subject: [PATCH 03/26] Clean up leftmost branch --- src/addresses.h | 4 ++ src/interface/viewport.c | 91 +++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index bced7a06c6..eb35b9bc84 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -614,10 +614,14 @@ #define RCT2_ADDRESS_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 #define RCT2_ADDRESS_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 +#define _yEndPoint RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_Y_START_POINT_GLOBAL 0xEDF808 //sint16 +#define _yStartPoint RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 #define RCT2_ADDRESS_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 +#define _xEndPoint RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_X_START_POINT_GLOBAL 0xEDF80C //sint16 +#define _xStartPoint RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch #define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS 0x009AA00D #define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_CONFIG 0x009AB4C6 diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 579d96882e..ddb34c42f5 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2652,8 +2652,8 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) if (!(image.flags & 0x10)) { dpi->zoom_level--; - dpi->x /= 2; - dpi->y /= 2; + dpi->x >>= 1; + dpi->y >>= 1; sub_679074(dpi, imageId - image.zoomed_offset, x / 2, y / 2); @@ -2664,7 +2664,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - RCT2_GLOBAL(0x9E3D08, uint32) = image.offset; + RCT2_GLOBAL(0x9E3D08, uint8*) = image.offset; RCT2_GLOBAL(0x9E3D0C, sint16) = image.width; RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image.height; RCT2_GLOBAL(0x9E3D10, sint16) = image.x_offset; @@ -2672,79 +2672,82 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_GLOBAL(0x9E3D14, uint16) = image.flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image.zoomed_offset; - if (image.flags & 4) { - // push edi + if (!(image.flags & 4)) { y--; - // ebp = edi; - // esi = image.offset; y += image.y_offset; uint16 height = image.height; - RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, uint32) = 0; + _yStartPoint = 0; if (height % 2) { height--; if (height == 0) { return; } - RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, uint32)++; + _yStartPoint++; } - - // TODO: (y = y/2?) - y &= 0xFFFE; - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = height; + y = floor2(y, 2); + _yEndPoint = height; y -= dpi->y; if (y < 0) { - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) += y; - if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { return; } - RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, sint16) -= y; + _yStartPoint -= y; y = 0; } - y += RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16); + y += _yEndPoint; y--; if (y > 0) { - // inverse of JLE - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) -= y; + _yEndPoint -= y; - if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + if (_yEndPoint <= 0) { return; } } sint16 width = image.width; - RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = width; + _xStartPoint = 0; + _xEndPoint = width; x += image.x_offset; - x &= 0xFFFE; + x = floor2(x, 2); x -= dpi->x; if (x < 0) { - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) += x; - if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { return; } - RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) -= x; + _xStartPoint -= x; x = 0; } - x += RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16); + x += _xEndPoint; x--; - if (x > 0) { - // inverse of JLE - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) -= x; - if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + if (x > 0) { + _xEndPoint -= x; + + if (_xEndPoint <= 0) { return; } } + // eax: image.width(ax) + // ebx: [image] + // ecx: x (cx) + // edx: y (dx) + // esi: image.offset + // edi: dpi + // ebp: dpi + + //TODO: refactor into sub_679788 RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, image.offset, (int) dpi, (int) dpi); return; } else { @@ -2766,11 +2769,11 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } y &= 0xFFFE; - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) = height; + _yEndPoint = height; y -= image.height; if (y < 0) { - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) += y; - if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { return; } @@ -2781,26 +2784,26 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // Do nothing? } - y += RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16); + y += _yEndPoint; y--; if (y > 0) { - RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) -= y; - if (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) <= 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { return; } } sint16 ax = image.width; - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) = ax; + _xEndPoint = ax; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; x += image.x_offset; x = floor2(x, 2); x -= dpi->x; if (x < 0) { - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) += x; - if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { return; } @@ -2811,11 +2814,11 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } - x += RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16); + x += _xEndPoint; x--; if (x > 0) { - RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) -= x; - if (RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) <= 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { return; } @@ -2824,7 +2827,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // Or is this the 'flags' part? if (!(image.zoomed_offset & (1 << 1))) { - sint8 ah = (RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) >> 8) & 0xFF; + sint8 ah = (_yEndPoint >> 8) & 0xFF; int edx = RCT2_GLOBAL(0x009ABDAE, sint16); int ebx = RCT2_GLOBAL(0x00EDF81C, uint32) = 0; From cdf4b596e470b26ae3c08a9116a5e4c4627fff81 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 25 Feb 2016 22:08:20 +0100 Subject: [PATCH 04/26] Implement further --- src/interface/viewport.c | 181 +++++++++++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 35 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index ddb34c42f5..76fafeeaf7 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2632,13 +2632,84 @@ void store_interaction_info(paint_struct *ps) } } +void sub_679236(uint32 ebx, rct_g1_element *image, uint8 *esi) { + if (ebx & 0x20000000) { + if (!(image->flags & 1)) { + return; + } + + uint8 *ebx_palette = RCT2_GLOBAL(0x009ABDA4, uint8*); + uint8 al = *esi; + uint8 al2 = *(al + ebx_palette); + + if (al2 != 0) { + RCT2_GLOBAL(0x00141F569, uint8) = 1; + } + } else if (!(ebx & 0x40000000)) { + if (!(image->flags & 1)) { + RCT2_GLOBAL(0x00141F569, uint8) = 1; + return; + } + + if (*esi != 0) { + RCT2_GLOBAL(0x00141F569, uint8) = 1; + } + } +} + +void sub_679662_679B0D_679FF1(uint32 ebx, rct_g1_element *image, uint8 *esi) { + if (ebx & 0x20000000) { + if (!(image->flags & 1)) { + return; + } + + uint8 *ebx_palette = RCT2_GLOBAL(0x009ABDA4, uint8*); + + uint8 al = *esi; + uint8 al2 = *(al + ebx_palette); + if (al2 != 0) { + RCT2_GLOBAL(0x00141F569, uint8) = 1; + } + } else if (!(ebx & 0x40000000)) { + if (!(image->flags & 1)) { + return; + } + + if (*esi != 0) { + RCT2_GLOBAL(0x00141F569, uint8) = 1; + } + } +} + +void do_sub(int address, uint32 ebx, rct_g1_element *image, uint8 *esi) { + uint8 global_before = RCT2_GLOBAL(0x00141F569, uint8); + RCT2_CALLPROC_X(address, 0, ebx, 0, 0, (int) esi, 0, 0); + uint8 original_global = RCT2_GLOBAL(0x00141F569, uint8); + + RCT2_GLOBAL(0x00141F569, uint8) = global_before; + + if (address == 0x679236) { + sub_679236(ebx, image, esi); + } else { + sub_679662_679B0D_679FF1(ebx, image, esi); + } + uint8 new_global = RCT2_GLOBAL(0x00141F569, uint8); + + assert(new_global == original_global); +} + +void sub_679788(rct_g1_element *image, rct_drawpixelinfo *dpi) { + RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, (int) image->offset, (int) dpi, (int) dpi); +} + + /** * * rct2: 0x00679074 */ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { - rct_g1_element image = g1Elements[imageId & 0x7FFFF]; + rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; switch (dpi->zoom_level) { case 0: @@ -2646,16 +2717,16 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) break; case 1: - if (image.flags & 0x20) { + if (image->flags & 0x20) { return; } - if (!(image.flags & 0x10)) { + if (!(image->flags & 0x10)) { dpi->zoom_level--; dpi->x >>= 1; dpi->y >>= 1; - sub_679074(dpi, imageId - image.zoomed_offset, x / 2, y / 2); + sub_679074(dpi, imageId - image->zoomed_offset, x / 2, y / 2); dpi->zoom_level++; dpi->x *= 2; @@ -2664,19 +2735,19 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - RCT2_GLOBAL(0x9E3D08, uint8*) = image.offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image.width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image.height; - RCT2_GLOBAL(0x9E3D10, sint16) = image.x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image.y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image.flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image.zoomed_offset; + RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; + RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; + RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - if (!(image.flags & 4)) { + if (!(image->flags & 4)) { y--; - y += image.y_offset; + y += image->y_offset; - uint16 height = image.height; + uint16 height = image->height; _yStartPoint = 0; if (height % 2) { height--; @@ -2712,10 +2783,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint16 width = image.width; + sint16 width = image->width; _xStartPoint = 0; _xEndPoint = width; - x += image.x_offset; + x += image->x_offset; x = floor2(x, 2); x -= dpi->x; if (x < 0) { @@ -2739,38 +2810,35 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - // eax: image.width(ax) + // eax: image->width(ax) // ebx: [image] // ecx: x (cx) // edx: y (dx) - // esi: image.offset + // esi: image->offset // edi: dpi // ebp: dpi - //TODO: refactor into sub_679788 - RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, image.offset, (int) dpi, (int) dpi); + sub_679788(image, dpi); return; } else { // push edi // ebp = edi; - //esi = image.offset; - uint32 esi = image.offset; - y += image.y_offset; - sint16 height = image.height; + //esi = image->offset; + uint8 *esi = image->offset; + y += image->y_offset; + sint16 height = image->height; if (height % 2) { - sint16 ebx = image.width; height--; - - esi += ebx; + esi += image->width; } if (height == 0) { return; } - y &= 0xFFFE; + y = floor2(y, 2); _yEndPoint = height; - y -= image.height; + y -= dpi->y; if (y < 0) { _yEndPoint += y; if (_yEndPoint <= 0) { @@ -2778,7 +2846,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } y = -y; - esi += (y * image.width) & 0xFFFF; + esi += (y * image->width) & 0xFFFF; y = 0; } else { // Do nothing? @@ -2794,10 +2862,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint16 ax = image.width; - _xEndPoint = ax; + sint16 width = image->width; + _xEndPoint = width; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image.x_offset; + x += image->x_offset; x = floor2(x, 2); x -= dpi->x; @@ -2826,17 +2894,60 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } // Or is this the 'flags' part? - if (!(image.zoomed_offset & (1 << 1))) { + if (!(image->zoomed_offset & (1 << 1))) { sint8 ah = (_yEndPoint >> 8) & 0xFF; int edx = RCT2_GLOBAL(0x009ABDAE, sint16); int ebx = RCT2_GLOBAL(0x00EDF81C, uint32) = 0; // ah and edx don't seem to be used by this function... - RCT2_CALLPROC_X(0x00679662, 0, ebx, 0, 0, esi, 0, 0); + do_sub(0x00679662, ebx, image, esi); return; } // loc_6795E4: + uint8 *ebp = esi; + rct_g1_element *g1_source = image; + uint8 *source_pointer; + + int total_no_pixels = g1_source->width * g1_source->height; + source_pointer = g1_source->offset; + uint8 *new_source_pointer_start = malloc(total_no_pixels); + uint8 *new_source_pointer = new_source_pointer_start;// 0x9E3D28; + int ebx, ecx; + while (total_no_pixels > 0) { + sint8 no_pixels = *source_pointer; + if (no_pixels >= 0) { + source_pointer++; + total_no_pixels -= no_pixels; + memcpy((char *) new_source_pointer, (char *) source_pointer, no_pixels); + new_source_pointer += no_pixels; + source_pointer += no_pixels; + continue; + } + ecx = no_pixels; + no_pixels &= 0x7; + ecx >>= 3;//SAR + int eax = ((int) no_pixels) << 8; + ecx = -ecx;//Odd + eax = (eax & 0xFF00) + *(source_pointer + 1); + total_no_pixels -= ecx; + source_pointer += 2; + ebx = (uint32) new_source_pointer - eax; + eax = (uint32) source_pointer; + source_pointer = (uint8 *) ebx; + ebx = eax; + eax = 0; + memcpy((char *) new_source_pointer, (char *) source_pointer, ecx); + new_source_pointer += ecx; + source_pointer = (uint8 *) ebx; + } + + uint8 *esi_end = new_source_pointer_start + (uint32) ebp; + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); + return; } break; From ebb2ab3b0c8d987adb8ffc1a16cfb186e53e35bb Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 10:01:15 +0100 Subject: [PATCH 05/26] Decompile dpi->zoom_level == 0 && image->flags & 4 --- src/interface/viewport.c | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 76fafeeaf7..b17564315a 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2713,6 +2713,63 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) switch (dpi->zoom_level) { case 0: + RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; + RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; + RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; + if (image->flags & 4) { + y += image->y_offset; + _yStartPoint = 0; + _yEndPoint = image->height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + _yStartPoint -= y; + y = 0; + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + return; + } + + sint16 ax = image->width; + _xStartPoint = 0; + _xEndPoint = ax; + x += image->x_offset; + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + _xStartPoint -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + return; + } + + // TODO: refactor in sub_67933B + // ebp might be dpi + RCT2_CALLPROC_X(0x0067933B, 0, 0, 0, 0, (int)image->offset, 0xEEEEEEEE, 0xFFFFFFFF); + return; + } + // TODO: loc_6790A0: break; From 0519130b944ce9bd97d70f3b0f33a3b6c9119747 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 10:33:19 +0100 Subject: [PATCH 06/26] Complete dpi->zoom_level == 0 --- src/interface/viewport.c | 169 ++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 48 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index b17564315a..0889feca02 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2232,6 +2232,8 @@ struct paint_string_struct { uint8 *y_offsets; // 0x1A }; +void loc_6791B8_6795E4(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); + static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi) { int zoom = dpi->zoom_level; @@ -2742,9 +2744,8 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - sint16 ax = image->width; _xStartPoint = 0; - _xEndPoint = ax; + _xEndPoint = image->width; x += image->x_offset; x -= dpi->x; if (x < 0) { @@ -2765,12 +2766,82 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } // TODO: refactor in sub_67933B - // ebp might be dpi - RCT2_CALLPROC_X(0x0067933B, 0, 0, 0, 0, (int)image->offset, 0xEEEEEEEE, 0xFFFFFFFF); + // EDI: dpi + // EBP: dpi + RCT2_CALLPROC_X(0x0067933B, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); return; } - // TODO: loc_6790A0: + rct_drawpixelinfo *ebp = dpi; + uint8 *esi = image->offset; + + y += image->y_offset; + _yEndPoint = image->height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + y = 0; + esi += (image->width * -y) & 0xFFFF; + } else { + // bx = y; + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + sint8 ax = image->width; + _xEndPoint = ax; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image->x_offset; + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + esi -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + + if (!(image->flags & 2)) { + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + + // ah and edx don't seem to be used by this function... + do_sub(0x00679236, ebx, image, esi); + return; + } + + + uint8 *new_source_pointer_start, *esi_end; + loc_6791B8_6795E4(image, esi, &new_source_pointer_start, &esi_end); + do_sub(0x00679236, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); + break; case 1: @@ -2961,50 +3032,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - // loc_6795E4: - uint8 *ebp = esi; - rct_g1_element *g1_source = image; - uint8 *source_pointer; - - int total_no_pixels = g1_source->width * g1_source->height; - source_pointer = g1_source->offset; - uint8 *new_source_pointer_start = malloc(total_no_pixels); - uint8 *new_source_pointer = new_source_pointer_start;// 0x9E3D28; - int ebx, ecx; - while (total_no_pixels > 0) { - sint8 no_pixels = *source_pointer; - if (no_pixels >= 0) { - source_pointer++; - total_no_pixels -= no_pixels; - memcpy((char *) new_source_pointer, (char *) source_pointer, no_pixels); - new_source_pointer += no_pixels; - source_pointer += no_pixels; - continue; - } - ecx = no_pixels; - no_pixels &= 0x7; - ecx >>= 3;//SAR - int eax = ((int) no_pixels) << 8; - ecx = -ecx;//Odd - eax = (eax & 0xFF00) + *(source_pointer + 1); - total_no_pixels -= ecx; - source_pointer += 2; - ebx = (uint32) new_source_pointer - eax; - eax = (uint32) source_pointer; - source_pointer = (uint8 *) ebx; - ebx = eax; - eax = 0; - memcpy((char *) new_source_pointer, (char *) source_pointer, ecx); - new_source_pointer += ecx; - source_pointer = (uint8 *) ebx; - } - - uint8 *esi_end = new_source_pointer_start + (uint32) ebp; - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint8 *new_source_pointer_start, *esi_end; + loc_6791B8_6795E4(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); - return; } break; @@ -3017,7 +3048,49 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) break; } - RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int)dpi, 0); + RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); +} + +void loc_6791B8_6795E4(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { + uint8 *ebp = esi; + uint8 *source_pointer; + + int total_no_pixels = g1_source->width * g1_source->height; + source_pointer = g1_source->offset; + (*new_source_pointer_start) = malloc(total_no_pixels); + uint8 *new_source_pointer = (*new_source_pointer_start);// 0x9E3D28; + int ebx, ecx; + while (total_no_pixels > 0) { + sint8 no_pixels = *source_pointer; + if (no_pixels >= 0) { + source_pointer++; + total_no_pixels -= no_pixels; + memcpy((char *) new_source_pointer, (char *) source_pointer, no_pixels); + new_source_pointer += no_pixels; + source_pointer += no_pixels; + continue; + } + ecx = no_pixels; + no_pixels &= 0x7; + ecx >>= 3;//SAR + int eax = ((int) no_pixels) << 8; + ecx = -ecx;//Odd + eax = (eax & 0xFF00) + *(source_pointer + 1); + total_no_pixels -= ecx; + source_pointer += 2; + ebx = (uint32) new_source_pointer - eax; + eax = (uint32) source_pointer; + source_pointer = (uint8 *) ebx; + ebx = eax; + eax = 0; + memcpy((char *) new_source_pointer, (char *) source_pointer, ecx); + new_source_pointer += ecx; + source_pointer = (uint8 *) ebx; + } + + (*esi_end) = new_source_pointer_start + (uint32) ebp; + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); } /** From 68229904e100cc272e0b11f2bdcb5becbcb32b56 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 11:47:08 +0100 Subject: [PATCH 07/26] Decompile zoom level 2 --- src/interface/viewport.c | 215 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 202 insertions(+), 13 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 0889feca02..a45226c0f9 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2232,7 +2232,7 @@ struct paint_string_struct { uint8 *y_offsets; // 0x1A }; -void loc_6791B8_6795E4(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); +void loc_6791B8_6795E4_679A8F(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi) { @@ -2713,6 +2713,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; + uint8 *esi; + uint8 *new_source_pointer_start, *esi_end; + switch (dpi->zoom_level) { case 0: RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; @@ -2799,8 +2802,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint8 ax = image->width; - _xEndPoint = ax; + _xEndPoint = image->width; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; x += image->x_offset; x -= dpi->x; @@ -2837,12 +2839,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } - uint8 *new_source_pointer_start, *esi_end; - loc_6791B8_6795E4(image, esi, &new_source_pointer_start, &esi_end); + loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679236, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); - - break; + return; case 1: if (image->flags & 0x20) { @@ -2952,7 +2952,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // push edi // ebp = edi; //esi = image->offset; - uint8 *esi = image->offset; + esi = image->offset; y += image->y_offset; sint16 height = image->height; if (height % 2) { @@ -3032,16 +3032,205 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - uint8 *new_source_pointer_start, *esi_end; - loc_6791B8_6795E4(image, esi, &new_source_pointer_start, &esi_end); + loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); } break; case 2: - // TODO: loc_6798F5 - break; + if (image->flags & 0x20) { + return; + } + + if (image->flags & 0x10) { + // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` + rct_drawpixelinfo zoomed_dpi = { + .bits = dpi->bits, + .x = dpi->x >> 1, + .y = dpi->y >> 1, + .height = dpi->height, + .width = dpi->width, + .pitch = dpi->pitch, + .zoom_level = dpi->zoom_level - 1 + }; + + sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); + return; + } + + RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; + RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; + RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; + + if (image->flags & 4) { + y -= 3; + // ebp = dpi; + esi = image->offset; + + y += image->y_offset; + sint16 height = image->height; + _yStartPoint = 0; + if (height % 2) { + height--; + if (height == 0) { + return; + } + _yStartPoint++; + } + + if (height % 4) { + height -= 2; + if (height <= 0) { + return; + } + _yStartPoint += 2; + } + + y = floor2(y, 4); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + _yStartPoint -= y; + y = 0; + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + _xStartPoint = 0; + _xEndPoint = image->width; + y += image->x_offset; + x = floor2(x, 4); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + _xStartPoint -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + } + + // TODO: refactor in sub_679C4A + // EDI: dpi + // EBP: dpi + RCT2_CALLPROC_X(0x00679C4A, 0, 0, 0, 0, (int) esi, 0xEEEEEEEE, 0xFFFFFFFF); + return; + } + + esi = image->offset; + + y += image->y_offset; + sint16 height = image->height; + if (height % 2) { + // ebx = (image->width << 16)+ image->height + height--; + esi += (image->width << 16) & image->height; + } + + if (height % 4) { + height -= 2; + esi += ((image->width << 16) & image->height) << 1; + } + + if (height == 0) { + return; + } + + y = floor2(y, 4); + _yEndPoint = y; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + esi += (image->width * -y) & 0xFFFF; + y = 0; + } else { + // Nothing? + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + + _xEndPoint = image->width; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image->x_offset; + x = floor2(x, 4); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + esi -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } + + + if (!(image->flags & 2)) { + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + + // ah and edx don't seem to be used by this function... + do_sub(0x00679B0D, ebx, image, esi); + return; + } + + + loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); + do_sub(0x00679B0D, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); + return; default: // TODO: loc_679DEE @@ -3051,7 +3240,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); } -void loc_6791B8_6795E4(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { +void loc_6791B8_6795E4_679A8F(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { uint8 *ebp = esi; uint8 *source_pointer; From 6a2134896f025afec3e8eeb2694275a94f2789e2 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 12:19:07 +0100 Subject: [PATCH 08/26] Decompile zoom level 3 --- src/interface/viewport.c | 206 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 191 insertions(+), 15 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index a45226c0f9..c36b75bb4d 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2232,7 +2232,7 @@ struct paint_string_struct { uint8 *y_offsets; // 0x1A }; -void loc_6791B8_6795E4_679A8F(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); +void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi) { @@ -2713,6 +2713,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; + sint16 width, height; uint8 *esi; uint8 *new_source_pointer_start, *esi_end; @@ -2839,7 +2840,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } - loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679236, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); return; @@ -2911,7 +2912,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint16 width = image->width; + width = image->width; _xStartPoint = 0; _xEndPoint = width; x += image->x_offset; @@ -2954,7 +2955,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) //esi = image->offset; esi = image->offset; y += image->y_offset; - sint16 height = image->height; + height = image->height; if (height % 2) { height--; esi += image->width; @@ -2990,7 +2991,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - sint16 width = image->width; + width = image->width; _xEndPoint = width; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; x += image->x_offset; @@ -3032,7 +3033,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); } @@ -3073,7 +3074,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) esi = image->offset; y += image->y_offset; - sint16 height = image->height; + height = image->height; _yStartPoint = 0; if (height % 2) { height--; @@ -3147,7 +3148,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) esi = image->offset; y += image->y_offset; - sint16 height = image->height; + height = image->height; if (height % 2) { // ebx = (image->width << 16)+ image->height height--; @@ -3227,20 +3228,195 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } - loc_6791B8_6795E4_679A8F(image, esi, &new_source_pointer_start, &esi_end); + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679B0D, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); return; - default: - // TODO: loc_679DEE - break; - } + case 3: + if (image->flags & 0x20) { + return; + } - RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); + if (image->flags & 0x10) { + // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` + rct_drawpixelinfo zoomed_dpi = { + .bits = dpi->bits, + .x = dpi->x >> 1, + .y = dpi->y >> 1, + .height = dpi->height, + .width = dpi->width, + .pitch = dpi->pitch, + .zoom_level = dpi->zoom_level - 1 + }; + + sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); + return; + } + + RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; + RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; + RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; + + if (image->flags & 4) { + y -= 7; + esi = image->offset; + y += image->y_offset; + height = image->height; + _yStartPoint = 0; + if (height % 2) { + height--; + if (height == 0) { + return; + } + _yStartPoint++; + } + + y = floor2(y, 8); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + _yStartPoint -= y; + y = 0; + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + width = image->width; + _xStartPoint = 0; + _xEndPoint = width; + x += image->x_offset; + x = floor2(x, 8); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return;; + } + + _xStartPoint -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + } + + // TODO: refactor in sub_67A117 + // EDI: dpi + // EBP: dpi + RCT2_CALLPROC_X(0x0067A117, 0, 0, 0, 0, (int) esi, 0xEEEEEEEE, 0xFFFFFFFF); + return; + } + + esi = image->offset; + y += image->y_offset; + height = image->height; + if (height % 2) { + height--; + esi += (image->width << 16) & image->height; + } + + if (height == 0) { + return; + } + + y = floor2(y, 8); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + esi += ((image->width * -y) & 0xFFFF); + y = 0; + } else { + // Do nothing? + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + width = image->width; + _xEndPoint = width; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image->x_offset; + x = floor2(x, 32); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + esi -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } + + if (!(image->flags & 2)) { + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + + // ah and edx don't seem to be used by this function... + do_sub(0x00679FF1, ebx, image, esi); + return; + } + + + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); + do_sub(0x00679FF1, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); + return; + + default: + log_error("Unkown zoom level"); + return; + } } -void loc_6791B8_6795E4_679A8F(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { +void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { uint8 *ebp = esi; uint8 *source_pointer; From a0e08146bbe00faf204e5ed93e11d7501760152e Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 13:18:46 +0100 Subject: [PATCH 09/26] Make function uniform and apply fixes --- src/interface/viewport.c | 289 ++++++++++++++++++--------------------- 1 file changed, 132 insertions(+), 157 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index c36b75bb4d..337e3e4fa0 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2713,7 +2713,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; - sint16 width, height; + sint16 height; uint8 *esi; uint8 *new_source_pointer_start, *esi_end; @@ -2726,10 +2726,12 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; + if (image->flags & 4) { y += image->y_offset; _yStartPoint = 0; - _yEndPoint = image->height; + height = image->height; + _yEndPoint = height; y -= dpi->y; if (y < 0) { _yEndPoint += y; @@ -2745,7 +2747,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) y--; if (y > 0) { _yEndPoint -= y; - return; + if (_yEndPoint <= 0) { + return; + } } _xStartPoint = 0; @@ -2766,7 +2770,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) x--; if (x > 0) { _xEndPoint -= x; - return; + if (_xEndPoint <= 0) { + return; + } } // TODO: refactor in sub_67933B @@ -2776,11 +2782,11 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - rct_drawpixelinfo *ebp = dpi; - uint8 *esi = image->offset; + esi = image->offset; y += image->y_offset; - _yEndPoint = image->height; + height = image->height; + _yEndPoint = height; y -= dpi->y; if (y < 0) { _yEndPoint += y; @@ -2788,10 +2794,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - y = 0; esi += (image->width * -y) & 0xFFFF; + y = 0; } else { - // bx = y; + // Do nothing? } y += _yEndPoint; @@ -2825,9 +2831,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) if (_xEndPoint <= 0) { return; } - } - RCT2_GLOBAL(0x009ABDAE, sint16) += x; + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } if (!(image->flags & 2)) { sint8 ah = (_yEndPoint >> 8) & 0xFF; @@ -2839,7 +2845,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679236, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); @@ -2850,17 +2855,19 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - if (!(image->flags & 0x10)) { - dpi->zoom_level--; - dpi->x >>= 1; - dpi->y >>= 1; - - sub_679074(dpi, imageId - image->zoomed_offset, x / 2, y / 2); - - dpi->zoom_level++; - dpi->x *= 2; - dpi->y *= 2; + if (image->flags & 0x10) { + // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` + rct_drawpixelinfo zoomed_dpi = { + .bits = dpi->bits, + .x = dpi->x >> 1, + .y = dpi->y >> 1, + .height = dpi->height, + .width = dpi->width, + .pitch = dpi->pitch, + .zoom_level = dpi->zoom_level - 1 + }; + sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); return; } @@ -2872,25 +2879,22 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - if (!(image->flags & 4)) { - y--; + if (image->flags & 4) { + y -= 1; y += image->y_offset; - - uint16 height = image->height; _yStartPoint = 0; + height = image->height; if (height % 2) { height--; if (height == 0) { return; } - _yStartPoint++; } y = floor2(y, 2); _yEndPoint = height; y -= dpi->y; - if (y < 0) { _yEndPoint += y; if (_yEndPoint <= 0) { @@ -2903,18 +2907,15 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) y += _yEndPoint; y--; - if (y > 0) { _yEndPoint -= y; - if (_yEndPoint <= 0) { return; } } - width = image->width; _xStartPoint = 0; - _xEndPoint = width; + _xEndPoint = image->width; x += image->x_offset; x = floor2(x, 2); x -= dpi->x; @@ -2930,114 +2931,98 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) x += _xEndPoint; x--; - if (x > 0) { _xEndPoint -= x; - if (_xEndPoint <= 0) { return; } } - // eax: image->width(ax) - // ebx: [image] - // ecx: x (cx) - // edx: y (dx) - // esi: image->offset - // edi: dpi - // ebp: dpi - - sub_679788(image, dpi); + // TODO: refactor in sub_679788 + // EDI: dpi + // EBP: dpi + RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); return; - } else { - // push edi - // ebp = edi; - //esi = image->offset; - esi = image->offset; - y += image->y_offset; - height = image->height; - if (height % 2) { - height--; - esi += image->width; - } - - if (height == 0) { - return; - } - - y = floor2(y, 2); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - y = -y; - esi += (y * image->width) & 0xFFFF; - y = 0; - } else { - // Do nothing? - } - - y += _yEndPoint; - y--; - - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - width = image->width; - _xEndPoint = width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image->x_offset; - x = floor2(x, 2); - x -= dpi->x; - - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - - esi -= x; - x = 0; - } - - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) += x; - } - - // Or is this the 'flags' part? - if (!(image->zoomed_offset & (1 << 1))) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - int ebx = RCT2_GLOBAL(0x00EDF81C, uint32) = 0; - - // ah and edx don't seem to be used by this function... - do_sub(0x00679662, ebx, image, esi); - return; - } - - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); - free(new_source_pointer_start); } - break; + + esi = image->offset; + + y += image->y_offset; + height = image->height; + if (height % 2) { + height--; + esi += image->width; + } + + if (height == 0) { + return; + } + + y = floor2(y, 2); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + esi += (image->width * -y) & 0xFFFF; + y = 0; + } else { + // Do nothing? + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + _xEndPoint = image->width; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image->x_offset; + x = floor2(x, 2); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + esi -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } + + if (!(image->flags & 2)) { + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + + // ah and edx don't seem to be used by this function... + do_sub(0x00679662, ebx, image, esi); + return; + } + + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); + do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); + return; case 2: if (image->flags & 0x20) { @@ -3070,12 +3055,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) if (image->flags & 4) { y -= 3; - // ebp = dpi; - esi = image->offset; - y += image->y_offset; - height = image->height; _yStartPoint = 0; + height = image->height; if (height % 2) { height--; if (height == 0) { @@ -3116,7 +3098,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) _xStartPoint = 0; _xEndPoint = image->width; - y += image->x_offset; + x += image->x_offset; x = floor2(x, 4); x -= dpi->x; if (x < 0) { @@ -3141,7 +3123,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // TODO: refactor in sub_679C4A // EDI: dpi // EBP: dpi - RCT2_CALLPROC_X(0x00679C4A, 0, 0, 0, 0, (int) esi, 0xEEEEEEEE, 0xFFFFFFFF); + RCT2_CALLPROC_X(0x00679C4A, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); return; } @@ -3150,14 +3132,13 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) y += image->y_offset; height = image->height; if (height % 2) { - // ebx = (image->width << 16)+ image->height height--; - esi += (image->width << 16) & image->height; + esi += image->width; } if (height % 4) { height -= 2; - esi += ((image->width << 16) & image->height) << 1; + esi += image->width * 2; } if (height == 0) { @@ -3165,7 +3146,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } y = floor2(y, 4); - _yEndPoint = y; + _yEndPoint = height; y -= dpi->y; if (y < 0) { _yEndPoint += y; @@ -3176,7 +3157,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) esi += (image->width * -y) & 0xFFFF; y = 0; } else { - // Nothing? + // Do nothing? } y += _yEndPoint; @@ -3188,7 +3169,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - _xEndPoint = image->width; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; x += image->x_offset; @@ -3216,7 +3196,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) RCT2_GLOBAL(0x009ABDAE, sint16) += x; } - if (!(image->flags & 2)) { sint8 ah = (_yEndPoint >> 8) & 0xFF; int edx = RCT2_GLOBAL(0x009ABDAE, sint16); @@ -3227,7 +3206,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679B0D, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); @@ -3264,10 +3242,9 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) if (image->flags & 4) { y -= 7; - esi = image->offset; y += image->y_offset; - height = image->height; _yStartPoint = 0; + height = image->height; if (height % 2) { height--; if (height == 0) { @@ -3298,16 +3275,15 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - width = image->width; _xStartPoint = 0; - _xEndPoint = width; + _xEndPoint = image->width; x += image->x_offset; x = floor2(x, 8); x -= dpi->x; if (x < 0) { _xEndPoint += x; if (_xEndPoint <= 0) { - return;; + return; } _xStartPoint -= x; @@ -3326,16 +3302,17 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) // TODO: refactor in sub_67A117 // EDI: dpi // EBP: dpi - RCT2_CALLPROC_X(0x0067A117, 0, 0, 0, 0, (int) esi, 0xEEEEEEEE, 0xFFFFFFFF); + RCT2_CALLPROC_X(0x0067A117, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); return; } esi = image->offset; + y += image->y_offset; height = image->height; if (height % 2) { height--; - esi += (image->width << 16) & image->height; + esi += image->width; } if (height == 0) { @@ -3351,7 +3328,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - esi += ((image->width * -y) & 0xFFFF); + esi += (image->width * -y) & 0xFFFF; y = 0; } else { // Do nothing? @@ -3366,11 +3343,10 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } } - width = image->width; - _xEndPoint = width; + _xEndPoint = image->width; RCT2_GLOBAL(0x009ABDAE, sint16) = 0; x += image->x_offset; - x = floor2(x, 32); + x = floor2(x, 8); x -= dpi->x; if (x < 0) { _xEndPoint += x; @@ -3404,7 +3380,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return; } - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); do_sub(0x00679FF1, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); free(new_source_pointer_start); From ce4590f914812e0d04fd5ab894e83de8a87e24d8 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 20:51:55 +0100 Subject: [PATCH 10/26] Attempt to decompile sub_679C4A --- src/interface/viewport.c | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 337e3e4fa0..a047378a1d 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2705,6 +2705,73 @@ void sub_679788(rct_g1_element *image, rct_drawpixelinfo *dpi) { } +void sub_679C4A(rct_g1_element *image, uint8 *esi) { + uint8 *ebx = esi + *(esi + (_yStartPoint * 2)); + + uint8 last_data_line = 0; + while (!last_data_line) { + uint8 gap_size = *ebx++; + int no_pixels = *ebx++; + + last_data_line = no_pixels & 0x80; + + no_pixels &= 0x7F; + + ebx += no_pixels; + + if (gap_size & 1) { + gap_size++; + no_pixels--; + if (no_pixels == 0) { + continue; + } + } + + // This is only done for one of the functions + int sub = 0x679C4A; + if (sub == 0x679C4A) { + if (gap_size & 2) { + gap_size += 2; + no_pixels -= 2; + if (no_pixels <= 0) { + continue; + } + } + } + + int x_start = gap_size - _xStartPoint; + if (x_start <= 0) { + no_pixels += x_start; + if (no_pixels <= 0) { + continue; + } + + x_start = 0; + } else { + // Do nothing? + } + + x_start += no_pixels; + x_start--; + if (x_start > 0) { + no_pixels -= x_start; + if (no_pixels <= 0) { + continue; + } + } + + // These differ per variant ( `+7)>>3`, `+1)>>1` or `+3)>>2` ) + // Could be 'ceil2(n, 8)`, 'ceil2(n, 2)`, 'ceil2(n, 4)` + int pixel_offset = 3; + int shift_amount = 2; + no_pixels = (no_pixels + pixel_offset) >> shift_amount; + if (no_pixels != 0) { + RCT2_GLOBAL(0x141F569, uint8) = 1; + break; + } + } +} + /** * * rct2: 0x00679074 From 8f5000369789646d824c8f8d463fe4c1c99ce94f Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Fri, 26 Feb 2016 16:31:06 +0100 Subject: [PATCH 11/26] Refactor code --- src/interface/viewport.c | 835 +++++++++------------------------------ 1 file changed, 192 insertions(+), 643 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index a047378a1d..4937baf286 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2776,363 +2776,85 @@ void sub_679C4A(rct_g1_element *image, uint8 *esi) { * * rct2: 0x00679074 */ -void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) -{ +void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; sint16 height; uint8 *esi; uint8 *new_source_pointer_start, *esi_end; + if (dpi->zoom_level != 0) { + if (image->flags & 0x20) { + return; + } + + if (image->flags & 0x10) { + // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` + rct_drawpixelinfo zoomed_dpi = { + .bits = dpi->bits, + .x = dpi->x >> 1, + .y = dpi->y >> 1, + .height = dpi->height, + .width = dpi->width, + .pitch = dpi->pitch, + .zoom_level = dpi->zoom_level - 1 + }; + + sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); + return; + } + } + + RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; + RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; + RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; + RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; + RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; + RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; + RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; + + int round, address_1, address_2; switch (dpi->zoom_level) { case 0: - RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; - RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - - if (image->flags & 4) { - y += image->y_offset; - _yStartPoint = 0; - height = image->height; - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - _yStartPoint -= y; - y = 0; - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xStartPoint = 0; - _xEndPoint = image->width; - x += image->x_offset; - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - _xStartPoint -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - } - - // TODO: refactor in sub_67933B - // EDI: dpi - // EBP: dpi - RCT2_CALLPROC_X(0x0067933B, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); - return; - } - - esi = image->offset; - - y += image->y_offset; - height = image->height; - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - esi += (image->width * -y) & 0xFFFF; - y = 0; - } else { - // Do nothing? - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xEndPoint = image->width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image->x_offset; - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - esi -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) += x; - } - - if (!(image->flags & 2)) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); - - // ah and edx don't seem to be used by this function... - do_sub(0x00679236, ebx, image, esi); - return; - } - - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(0x00679236, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); - free(new_source_pointer_start); - return; + default: + round = 1; + address_1 = 0x0067933B; + address_2 = 0x00679236; + break; case 1: - if (image->flags & 0x20) { - return; - } - - if (image->flags & 0x10) { - // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` - rct_drawpixelinfo zoomed_dpi = { - .bits = dpi->bits, - .x = dpi->x >> 1, - .y = dpi->y >> 1, - .height = dpi->height, - .width = dpi->width, - .pitch = dpi->pitch, - .zoom_level = dpi->zoom_level - 1 - }; - - sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); - return; - } - - RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; - RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - - if (image->flags & 4) { - y -= 1; - y += image->y_offset; - _yStartPoint = 0; - height = image->height; - if (height % 2) { - height--; - if (height == 0) { - return; - } - _yStartPoint++; - } - - y = floor2(y, 2); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - _yStartPoint -= y; - y = 0; - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xStartPoint = 0; - _xEndPoint = image->width; - x += image->x_offset; - x = floor2(x, 2); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - _xStartPoint -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - } - - // TODO: refactor in sub_679788 - // EDI: dpi - // EBP: dpi - RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); - return; - } - - esi = image->offset; - - y += image->y_offset; - height = image->height; - if (height % 2) { - height--; - esi += image->width; - } - - if (height == 0) { - return; - } - - y = floor2(y, 2); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - esi += (image->width * -y) & 0xFFFF; - y = 0; - } else { - // Do nothing? - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xEndPoint = image->width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image->x_offset; - x = floor2(x, 2); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - esi -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) += x; - } - - if (!(image->flags & 2)) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); - - // ah and edx don't seem to be used by this function... - do_sub(0x00679662, ebx, image, esi); - return; - } - - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(0x00679662, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); - free(new_source_pointer_start); - return; + round = 2; + address_1 = 0x00679788; + address_2 = 0x00679662; + break; case 2: - if (image->flags & 0x20) { - return; - } + round = 4; + address_1 = 0x00679C4A; + address_2 = 0x00679B0D; + break; - if (image->flags & 0x10) { - // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` - rct_drawpixelinfo zoomed_dpi = { - .bits = dpi->bits, - .x = dpi->x >> 1, - .y = dpi->y >> 1, - .height = dpi->height, - .width = dpi->width, - .pitch = dpi->pitch, - .zoom_level = dpi->zoom_level - 1 - }; + case 3: + round = 8; + address_1 = 0x0067A117; + address_2 = 0x00679FF1; + } - sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); - return; - } - - RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; - RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - - if (image->flags & 4) { - y -= 3; - y += image->y_offset; - _yStartPoint = 0; - height = image->height; - if (height % 2) { - height--; - if (height == 0) { - return; - } - _yStartPoint++; + if (image->flags & G1_FLAG_RLE_COMPRESSION) { + y -= (round - 1); + y += image->y_offset; + _yStartPoint = 0; + height = image->height; + if (dpi->zoom_level != 0) { + if (height % 2) { + height--; + if (height == 0) { + return; } + _yStartPoint++; + } + if (dpi->zoom_level == 4) { if (height % 4) { height -= 2; if (height <= 0) { @@ -3140,322 +2862,149 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) } _yStartPoint += 2; } + } + } - y = floor2(y, 4); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - _yStartPoint -= y; - y = 0; - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xStartPoint = 0; - _xEndPoint = image->width; - x += image->x_offset; - x = floor2(x, 4); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - _xStartPoint -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - } - - // TODO: refactor in sub_679C4A - // EDI: dpi - // EBP: dpi - RCT2_CALLPROC_X(0x00679C4A, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); + y = floor2(y, round); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { return; } - esi = image->offset; + _yStartPoint -= y; + y = 0; + } - y += image->y_offset; - height = image->height; - if (height % 2) { - height--; - esi += image->width; + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + _xStartPoint = 0; + _xEndPoint = image->width; + x += image->x_offset; + x = floor2(x, round); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; } + _xStartPoint -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + } + + // TODO: refactor in sub_679C4A + // EDI: dpi + // EBP: dpi + RCT2_CALLPROC_X(address_1, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); + return; + } + + esi = image->offset; + + y += image->y_offset; + height = image->height; + + if (dpi->zoom_level != 0) { + if (height % 2) { + height--; + esi += image->width; + } + + if (dpi->zoom_level == 4) { if (height % 4) { height -= 2; esi += image->width * 2; } + } - if (height == 0) { - return; - } - - y = floor2(y, 4); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - esi += (image->width * -y) & 0xFFFF; - y = 0; - } else { - // Do nothing? - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xEndPoint = image->width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image->x_offset; - x = floor2(x, 4); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - esi -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) += x; - } - - if (!(image->flags & 2)) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); - - // ah and edx don't seem to be used by this function... - do_sub(0x00679B0D, ebx, image, esi); - return; - } - - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(0x00679B0D, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); - free(new_source_pointer_start); - return; - - case 3: - if (image->flags & 0x20) { - return; - } - - if (image->flags & 0x10) { - // TODO: SAR in dpi done with `>> 1`, in coordinates with `/ 2` - rct_drawpixelinfo zoomed_dpi = { - .bits = dpi->bits, - .x = dpi->x >> 1, - .y = dpi->y >> 1, - .height = dpi->height, - .width = dpi->width, - .pitch = dpi->pitch, - .zoom_level = dpi->zoom_level - 1 - }; - - sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); - return; - } - - RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; - RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - - if (image->flags & 4) { - y -= 7; - y += image->y_offset; - _yStartPoint = 0; - height = image->height; - if (height % 2) { - height--; - if (height == 0) { - return; - } - _yStartPoint++; - } - - y = floor2(y, 8); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - _yStartPoint -= y; - y = 0; - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xStartPoint = 0; - _xEndPoint = image->width; - x += image->x_offset; - x = floor2(x, 8); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - _xStartPoint -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - } - - // TODO: refactor in sub_67A117 - // EDI: dpi - // EBP: dpi - RCT2_CALLPROC_X(0x0067A117, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); - return; - } - - esi = image->offset; - - y += image->y_offset; - height = image->height; - if (height % 2) { - height--; - esi += image->width; - } - - if (height == 0) { - return; - } - - y = floor2(y, 8); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return; - } - - esi += (image->width * -y) & 0xFFFF; - y = 0; - } else { - // Do nothing? - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return; - } - } - - _xEndPoint = image->width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; - x += image->x_offset; - x = floor2(x, 8); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - esi -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return; - } - - RCT2_GLOBAL(0x009ABDAE, sint16) += x; - } - - if (!(image->flags & 2)) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); - - // ah and edx don't seem to be used by this function... - do_sub(0x00679FF1, ebx, image, esi); - return; - } - - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(0x00679FF1, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); - free(new_source_pointer_start); - return; - - default: - log_error("Unkown zoom level"); + if (height == 0) { return; + } } + + y = floor2(y, round); + _yEndPoint = height; + y -= dpi->y; + if (y < 0) { + _yEndPoint += y; + if (_yEndPoint <= 0) { + return; + } + + esi += (image->width * -y) & 0xFFFF; + y = 0; + } else { + // Do nothing? + } + + y += _yEndPoint; + y--; + if (y > 0) { + _yEndPoint -= y; + if (_yEndPoint <= 0) { + return; + } + } + + _xEndPoint = image->width; + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + x += image->x_offset; + x = floor2(x, round); + x -= dpi->x; + if (x < 0) { + _xEndPoint += x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + esi -= x; + x = 0; + } + + x += _xEndPoint; + x--; + if (x > 0) { + _xEndPoint -= x; + if (_xEndPoint <= 0) { + return; + } + + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } + + if (!(image->flags & 2)) { + sint8 ah = (_yEndPoint >> 8) & 0xFF; + int edx = RCT2_GLOBAL(0x009ABDAE, sint16); + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + + // ah and edx don't seem to be used by this function... + do_sub(address_2, ebx, image, esi); + return; + } + + loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); + do_sub(address_2, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + free(new_source_pointer_start); } void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { From c84681b8ee5069e6d30d53a6d57ed39d181212a5 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sat, 27 Feb 2016 01:01:30 +0100 Subject: [PATCH 12/26] Refactor sub_679C4A --- src/interface/viewport.c | 50 ++++++++++++++++------------------------ src/rct2.h | 3 +++ 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 4937baf286..4ca99987aa 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2704,9 +2704,11 @@ void sub_679788(rct_g1_element *image, rct_drawpixelinfo *dpi) { RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, (int) image->offset, (int) dpi, (int) dpi); } - -void sub_679C4A(rct_g1_element *image, uint8 *esi) { - uint8 *ebx = esi + *(esi + (_yStartPoint * 2)); +/** + * rct2: 0x0067933B, 0x00679788, 0x00679C4A, 0x0067A117 + */ +void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_start_point, int round) { + uint8 *ebx = esi + *(esi + (y_start_point * 2)); uint8 last_data_line = 0; while (!last_data_line) { @@ -2719,17 +2721,17 @@ void sub_679C4A(rct_g1_element *image, uint8 *esi) { ebx += no_pixels; - if (gap_size & 1) { - gap_size++; - no_pixels--; - if (no_pixels == 0) { - continue; + if (round > 1) { + if (gap_size & 1) { + gap_size++; + no_pixels--; + if (no_pixels == 0) { + continue; + } } } - // This is only done for one of the functions - int sub = 0x679C4A; - if (sub == 0x679C4A) { + if (round == 4) { if (gap_size & 2) { gap_size += 2; no_pixels -= 2; @@ -2739,7 +2741,7 @@ void sub_679C4A(rct_g1_element *image, uint8 *esi) { } } - int x_start = gap_size - _xStartPoint; + int x_start = gap_size - x_start_point; if (x_start <= 0) { no_pixels += x_start; if (no_pixels <= 0) { @@ -2760,15 +2762,10 @@ void sub_679C4A(rct_g1_element *image, uint8 *esi) { } } - // These differ per variant ( `+7)>>3`, `+1)>>1` or `+3)>>2` ) - // Could be 'ceil2(n, 8)`, 'ceil2(n, 2)`, 'ceil2(n, 4)` - int pixel_offset = 3; - int shift_amount = 2; - no_pixels = (no_pixels + pixel_offset) >> shift_amount; - if (no_pixels != 0) { - RCT2_GLOBAL(0x141F569, uint8) = 1; - break; - } + if (ceil2(no_pixels, round) == 0) continue; + + RCT2_GLOBAL(0x141F569, uint8) = 1; + break; } } @@ -2813,30 +2810,26 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - int round, address_1, address_2; + int round, address_2; switch (dpi->zoom_level) { case 0: default: round = 1; - address_1 = 0x0067933B; address_2 = 0x00679236; break; case 1: round = 2; - address_1 = 0x00679788; address_2 = 0x00679662; break; case 2: round = 4; - address_1 = 0x00679C4A; address_2 = 0x00679B0D; break; case 3: round = 8; - address_1 = 0x0067A117; address_2 = 0x00679FF1; } @@ -2911,10 +2904,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { } } - // TODO: refactor in sub_679C4A - // EDI: dpi - // EBP: dpi - RCT2_CALLPROC_X(address_1, 0, 0, 0, 0, (int) image->offset, 0xEEEEEEEE, 0xFFFFFFFF); + sub_67933B_679788_679C4A_67A117(image->offset, _xStartPoint, _yStartPoint, round); return; } diff --git a/src/rct2.h b/src/rct2.h index a7b40d25e8..1df0f8a608 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -86,6 +86,9 @@ typedef uint8 colour_t; // Rounds an integer down to the given power of 2. y must be a power of 2. #define floor2(x, y) ((x) & (~((y) - 1))) +// Rounds an integer up to the given power of 2. y must be a power of 2. +#define ceil2(x, y) (((x) + (y) - 1) & (~((y) - 1))) + #ifndef __cplusplus // in C++ you should be using Util::CountOf From 859e5cfddec6634e2411975c380bda0641f61817 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 12:26:10 +0100 Subject: [PATCH 13/26] Clena up code --- src/interface/viewport.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 4ca99987aa..63a910cf79 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2700,20 +2700,16 @@ void do_sub(int address, uint32 ebx, rct_g1_element *image, uint8 *esi) { assert(new_global == original_global); } -void sub_679788(rct_g1_element *image, rct_drawpixelinfo *dpi) { - RCT2_CALLPROC_X(0x00679788, 0, 0, 0, 0, (int) image->offset, (int) dpi, (int) dpi); -} - /** * rct2: 0x0067933B, 0x00679788, 0x00679C4A, 0x0067A117 */ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_start_point, int round) { - uint8 *ebx = esi + *(esi + (y_start_point * 2)); + const uint8 *ebx = esi + ((uint16 *) esi)[y_start_point]; uint8 last_data_line = 0; while (!last_data_line) { - uint8 gap_size = *ebx++; int no_pixels = *ebx++; + uint8 gap_size = *ebx++; last_data_line = no_pixels & 0x80; @@ -2722,7 +2718,7 @@ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_ ebx += no_pixels; if (round > 1) { - if (gap_size & 1) { + if (gap_size % 2) { gap_size++; no_pixels--; if (no_pixels == 0) { @@ -2732,7 +2728,7 @@ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_ } if (round == 4) { - if (gap_size & 2) { + if (gap_size % 4) { gap_size += 2; no_pixels -= 2; if (no_pixels <= 0) { @@ -2765,7 +2761,7 @@ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_ if (ceil2(no_pixels, round) == 0) continue; RCT2_GLOBAL(0x141F569, uint8) = 1; - break; + return; } } @@ -2847,7 +2843,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { _yStartPoint++; } - if (dpi->zoom_level == 4) { + if (dpi->zoom_level == 2) { if (height % 4) { height -= 2; if (height <= 0) { From bf7092e2f908c53cc8cb7bb99113df828c400177 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 12:26:21 +0100 Subject: [PATCH 14/26] Add comparison function --- src/interface/viewport.c | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 63a910cf79..22ab690764 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2769,7 +2769,7 @@ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_ * * rct2: 0x00679074 */ -void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { +void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; sint16 height; @@ -2793,7 +2793,7 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { .zoom_level = dpi->zoom_level - 1 }; - sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); + new_sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); return; } } @@ -2993,6 +2993,55 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { free(new_source_pointer_start); } +void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { + rct_g1_element before_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); + uint32 before_palette = RCT2_GLOBAL(0xEDF81C, uint32); + sint16 before_x = RCT2_GLOBAL(0x9ABDAE, sint16); + sint16 before_x_start_point = _xStartPoint; + sint16 before_y_start_point = _yStartPoint; + sint16 before_x_end_point = _xEndPoint; + sint16 before_y_end_point = _yEndPoint; + uint8 before_output = RCT2_GLOBAL(0x00141F569, uint8); + + RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); + rct_g1_element original_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); + uint32 original_palette = RCT2_GLOBAL(0xEDF81C, uint32); + sint16 original_x = RCT2_GLOBAL(0x9ABDAE, sint16); + sint16 original_x_start_point = _xStartPoint; + sint16 original_y_start_point = _yStartPoint; + sint16 original_x_end_point = _xEndPoint; + sint16 original_y_end_point = _yEndPoint; + uint8 original_output = RCT2_GLOBAL(0x00141F569, uint8); + + RCT2_GLOBAL(0x9E3D08, rct_g1_element) = before_image; + RCT2_GLOBAL(0xEDF81C, uint32) = before_palette; + RCT2_GLOBAL(0x9ABDAE, sint16) = before_x; + _xStartPoint = before_x_start_point; + _yStartPoint = before_y_start_point; + _xEndPoint = before_x_end_point; + _yEndPoint = before_y_end_point; + RCT2_GLOBAL(0x00141F569, uint8) = before_output; + + new_sub_679074(dpi, imageId, x, y); + rct_g1_element new_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); + uint32 new_palette = RCT2_GLOBAL(0xEDF81C, uint32); + sint16 new_x = RCT2_GLOBAL(0x9ABDAE, sint16); + sint16 new_x_start_point = _xStartPoint; + sint16 new_y_start_point = _yStartPoint; + sint16 new_x_end_point = _xEndPoint; + sint16 new_y_end_point = _yEndPoint; + uint8 new_output = RCT2_GLOBAL(0x00141F569, uint8); + + assert(new_image.offset == original_image.offset); + assert(new_palette == original_palette); + assert(new_x == original_x); + assert(new_x_start_point == original_x_start_point); + assert(new_y_start_point == original_y_start_point); + assert(new_x_end_point == original_x_end_point); + assert(new_y_end_point == original_y_end_point); + assert(new_output == original_output); +} + void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { uint8 *ebp = esi; uint8 *source_pointer; From dbd3c4942c0a8d9b9ef1901cacb6e186ca13e813 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 12:28:52 +0100 Subject: [PATCH 15/26] Add assert to check whether address is ever reached --- src/interface/viewport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 22ab690764..34b58ad183 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2649,6 +2649,7 @@ void sub_679236(uint32 ebx, rct_g1_element *image, uint8 *esi) { } } else if (!(ebx & 0x40000000)) { if (!(image->flags & 1)) { + assert(false); RCT2_GLOBAL(0x00141F569, uint8) = 1; return; } From 6e59f2c02b4d0147a6765a082b5224e80c3c6fe9 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 15:53:46 +0100 Subject: [PATCH 16/26] Start code cleanup --- src/interface/viewport.c | 127 ++++++++++++--------------------------- 1 file changed, 40 insertions(+), 87 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 34b58ad183..41cc5b9a79 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2634,77 +2634,32 @@ void store_interaction_info(paint_struct *ps) } } -void sub_679236(uint32 ebx, rct_g1_element *image, uint8 *esi) { - if (ebx & 0x20000000) { - if (!(image->flags & 1)) { - return; - } - - uint8 *ebx_palette = RCT2_GLOBAL(0x009ABDA4, uint8*); - uint8 al = *esi; - uint8 al2 = *(al + ebx_palette); - - if (al2 != 0) { - RCT2_GLOBAL(0x00141F569, uint8) = 1; - } - } else if (!(ebx & 0x40000000)) { - if (!(image->flags & 1)) { - assert(false); - RCT2_GLOBAL(0x00141F569, uint8) = 1; - return; - } - - if (*esi != 0) { - RCT2_GLOBAL(0x00141F569, uint8) = 1; - } +static bool sub_679236_679662_679B0D_679FF1(uint32 ebx, rct_g1_element *image, uint8 *esi) { + if (!(image->flags & G1_FLAG_BMP)) { + assert(false); + return false; } -} -void sub_679662_679B0D_679FF1(uint32 ebx, rct_g1_element *image, uint8 *esi) { if (ebx & 0x20000000) { - if (!(image->flags & 1)) { - return; - } - uint8 *ebx_palette = RCT2_GLOBAL(0x009ABDA4, uint8*); uint8 al = *esi; uint8 al2 = *(al + ebx_palette); - if (al2 != 0) { - RCT2_GLOBAL(0x00141F569, uint8) = 1; - } - } else if (!(ebx & 0x40000000)) { - if (!(image->flags & 1)) { - return; - } - if (*esi != 0) { - RCT2_GLOBAL(0x00141F569, uint8) = 1; - } + return (al2 != 0); } -} -void do_sub(int address, uint32 ebx, rct_g1_element *image, uint8 *esi) { - uint8 global_before = RCT2_GLOBAL(0x00141F569, uint8); - RCT2_CALLPROC_X(address, 0, ebx, 0, 0, (int) esi, 0, 0); - uint8 original_global = RCT2_GLOBAL(0x00141F569, uint8); - - RCT2_GLOBAL(0x00141F569, uint8) = global_before; - - if (address == 0x679236) { - sub_679236(ebx, image, esi); - } else { - sub_679662_679B0D_679FF1(ebx, image, esi); + if (ebx & 0x40000000) { + return false; } - uint8 new_global = RCT2_GLOBAL(0x00141F569, uint8); - assert(new_global == original_global); + return (*esi != 0); } /** * rct2: 0x0067933B, 0x00679788, 0x00679C4A, 0x0067A117 */ -void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_start_point, int round) { +static bool sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_start_point, int round) { const uint8 *ebx = esi + ((uint16 *) esi)[y_start_point]; uint8 last_data_line = 0; @@ -2761,16 +2716,19 @@ void sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, sint16 y_ if (ceil2(no_pixels, round) == 0) continue; - RCT2_GLOBAL(0x141F569, uint8) = 1; - return; + return true; } + + return false; } /** * * rct2: 0x00679074 + * + * @return 0x00141F569 */ -void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { +static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; sint16 height; @@ -2779,7 +2737,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (dpi->zoom_level != 0) { if (image->flags & 0x20) { - return; + return false; } if (image->flags & 0x10) { @@ -2794,8 +2752,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { .zoom_level = dpi->zoom_level - 1 }; - new_sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); - return; + return new_sub_679074(&zoomed_dpi, imageId - image->zoomed_offset, x / 2, y / 2); } } @@ -2812,22 +2769,18 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { case 0: default: round = 1; - address_2 = 0x00679236; break; case 1: round = 2; - address_2 = 0x00679662; break; case 2: round = 4; - address_2 = 0x00679B0D; break; case 3: round = 8; - address_2 = 0x00679FF1; } if (image->flags & G1_FLAG_RLE_COMPRESSION) { @@ -2839,7 +2792,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (height % 2) { height--; if (height == 0) { - return; + return false; } _yStartPoint++; } @@ -2848,7 +2801,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (height % 4) { height -= 2; if (height <= 0) { - return; + return false; } _yStartPoint += 2; } @@ -2861,7 +2814,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (y < 0) { _yEndPoint += y; if (_yEndPoint <= 0) { - return; + return false; } _yStartPoint -= y; @@ -2873,7 +2826,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (y > 0) { _yEndPoint -= y; if (_yEndPoint <= 0) { - return; + return false; } } @@ -2885,7 +2838,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (x < 0) { _xEndPoint += x; if (_xEndPoint <= 0) { - return; + return false; } _xStartPoint -= x; @@ -2897,12 +2850,11 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (x > 0) { _xEndPoint -= x; if (_xEndPoint <= 0) { - return; + return false; } } - sub_67933B_679788_679C4A_67A117(image->offset, _xStartPoint, _yStartPoint, round); - return; + return sub_67933B_679788_679C4A_67A117(image->offset, _xStartPoint, _yStartPoint, round); } esi = image->offset; @@ -2924,7 +2876,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { } if (height == 0) { - return; + return false; } } @@ -2934,7 +2886,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (y < 0) { _yEndPoint += y; if (_yEndPoint <= 0) { - return; + return false; } esi += (image->width * -y) & 0xFFFF; @@ -2948,7 +2900,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (y > 0) { _yEndPoint -= y; if (_yEndPoint <= 0) { - return; + return false; } } @@ -2960,7 +2912,7 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (x < 0) { _xEndPoint += x; if (_xEndPoint <= 0) { - return; + return false; } RCT2_GLOBAL(0x009ABDAE, sint16) -= x; @@ -2973,28 +2925,30 @@ void new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { if (x > 0) { _xEndPoint -= x; if (_xEndPoint <= 0) { - return; + return false; } RCT2_GLOBAL(0x009ABDAE, sint16) += x; } + uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); + if (!(image->flags & 2)) { sint8 ah = (_yEndPoint >> 8) & 0xFF; int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); // ah and edx don't seem to be used by this function... - do_sub(address_2, ebx, image, esi); - return; + return sub_679236_679662_679B0D_679FF1(ebx, image, esi); } loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); - do_sub(address_2, RCT2_GLOBAL(0x00EDF81C, uint32), image, esi_end); + bool output = sub_679236_679662_679B0D_679FF1(ebx, image, esi_end); free(new_source_pointer_start); + + return output; } -void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { +static bool sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element before_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 before_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 before_x = RCT2_GLOBAL(0x9ABDAE, sint16); @@ -3002,7 +2956,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { sint16 before_y_start_point = _yStartPoint; sint16 before_x_end_point = _xEndPoint; sint16 before_y_end_point = _yEndPoint; - uint8 before_output = RCT2_GLOBAL(0x00141F569, uint8); RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); rct_g1_element original_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); @@ -3021,9 +2974,8 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { _yStartPoint = before_y_start_point; _xEndPoint = before_x_end_point; _yEndPoint = before_y_end_point; - RCT2_GLOBAL(0x00141F569, uint8) = before_output; - new_sub_679074(dpi, imageId, x, y); + bool new_output = new_sub_679074(dpi, imageId, x, y); rct_g1_element new_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 new_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 new_x = RCT2_GLOBAL(0x9ABDAE, sint16); @@ -3031,7 +2983,6 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { sint16 new_y_start_point = _yStartPoint; sint16 new_x_end_point = _xEndPoint; sint16 new_y_end_point = _yEndPoint; - uint8 new_output = RCT2_GLOBAL(0x00141F569, uint8); assert(new_image.offset == original_image.offset); assert(new_palette == original_palette); @@ -3041,6 +2992,8 @@ void sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { assert(new_x_end_point == original_x_end_point); assert(new_y_end_point == original_y_end_point); assert(new_output == original_output); + + return new_output; } void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { @@ -3104,7 +3057,7 @@ void sub_679023(rct_drawpixelinfo *dpi, int imageId, int x, int y) } else { RCT2_GLOBAL(0x00EDF81C, uint32) = 0; } - sub_679074(dpi, imageId, x, y); + RCT2_GLOBAL(0x00141F569, uint8) = sub_679074(dpi, imageId, x, y); } /** From 32d45d3018837ffb86fc3c0309cb8fd93b985180 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 16:26:41 +0100 Subject: [PATCH 17/26] Fix zoom level check --- src/interface/viewport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 41cc5b9a79..197e7185f9 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2868,7 +2868,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 esi += image->width; } - if (dpi->zoom_level == 4) { + if (dpi->zoom_level == 2) { if (height % 4) { height -= 2; esi += image->width * 2; From 99555a1b81373c03f8494f14e169c1c73c98b46c Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sun, 28 Feb 2016 17:10:33 +0100 Subject: [PATCH 18/26] Merge branches and don't use deprecated globals --- src/addresses.h | 4 - src/interface/viewport.c | 157 +++++++++------------------------------ 2 files changed, 35 insertions(+), 126 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index eb35b9bc84..bced7a06c6 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -614,14 +614,10 @@ #define RCT2_ADDRESS_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 #define RCT2_ADDRESS_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 -#define _yEndPoint RCT2_GLOBAL(RCT2_ADDRESS_Y_END_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_Y_START_POINT_GLOBAL 0xEDF808 //sint16 -#define _yStartPoint RCT2_GLOBAL(RCT2_ADDRESS_Y_START_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 #define RCT2_ADDRESS_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 -#define _xEndPoint RCT2_GLOBAL(RCT2_ADDRESS_X_END_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_X_START_POINT_GLOBAL 0xEDF80C //sint16 -#define _xStartPoint RCT2_GLOBAL(RCT2_ADDRESS_X_START_POINT_GLOBAL, sint16) #define RCT2_ADDRESS_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch #define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS 0x009AA00D #define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_CONFIG 0x009AB4C6 diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 197e7185f9..2fa70c93ba 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2732,7 +2732,6 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; sint16 height; - uint8 *esi; uint8 *new_source_pointer_start, *esi_end; if (dpi->zoom_level != 0) { @@ -2764,7 +2763,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - int round, address_2; + int round; switch (dpi->zoom_level) { case 0: default: @@ -2785,93 +2784,21 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 if (image->flags & G1_FLAG_RLE_COMPRESSION) { y -= (round - 1); - y += image->y_offset; - _yStartPoint = 0; - height = image->height; - if (dpi->zoom_level != 0) { - if (height % 2) { - height--; - if (height == 0) { - return false; - } - _yStartPoint++; - } - - if (dpi->zoom_level == 2) { - if (height % 4) { - height -= 2; - if (height <= 0) { - return false; - } - _yStartPoint += 2; - } - } - } - - y = floor2(y, round); - _yEndPoint = height; - y -= dpi->y; - if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { - return false; - } - - _yStartPoint -= y; - y = 0; - } - - y += _yEndPoint; - y--; - if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { - return false; - } - } - - _xStartPoint = 0; - _xEndPoint = image->width; - x += image->x_offset; - x = floor2(x, round); - x -= dpi->x; - if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { - return false; - } - - _xStartPoint -= x; - x = 0; - } - - x += _xEndPoint; - x--; - if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { - return false; - } - } - - return sub_67933B_679788_679C4A_67A117(image->offset, _xStartPoint, _yStartPoint, round); } - esi = image->offset; - y += image->y_offset; + sint16 yStartPoint = 0; height = image->height; - if (dpi->zoom_level != 0) { if (height % 2) { height--; - esi += image->width; + yStartPoint++; } if (dpi->zoom_level == 2) { if (height % 4) { height -= 2; - esi += image->width * 2; + yStartPoint += 2; } } @@ -2881,63 +2808,71 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 } y = floor2(y, round); - _yEndPoint = height; + sint16 yEndPoint = height; y -= dpi->y; if (y < 0) { - _yEndPoint += y; - if (_yEndPoint <= 0) { + yEndPoint += y; + if (yEndPoint <= 0) { return false; } - esi += (image->width * -y) & 0xFFFF; + yStartPoint -= y; y = 0; - } else { - // Do nothing? } - y += _yEndPoint; + y += yEndPoint; y--; if (y > 0) { - _yEndPoint -= y; - if (_yEndPoint <= 0) { + yEndPoint -= y; + if (yEndPoint <= 0) { return false; } } - _xEndPoint = image->width; - RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + sint16 xStartPoint = 0; + sint16 xEndPoint = image->width; + if (!(image->flags & G1_FLAG_RLE_COMPRESSION)) { + RCT2_GLOBAL(0x009ABDAE, sint16) = 0; + } + x += image->x_offset; x = floor2(x, round); x -= dpi->x; if (x < 0) { - _xEndPoint += x; - if (_xEndPoint <= 0) { + xEndPoint += x; + if (xEndPoint <= 0) { return false; } - RCT2_GLOBAL(0x009ABDAE, sint16) -= x; - esi -= x; + if (!(image->flags & G1_FLAG_RLE_COMPRESSION)) { + RCT2_GLOBAL(0x009ABDAE, sint16) -= x; + } + + xStartPoint -= x; x = 0; } - x += _xEndPoint; + x += xEndPoint; x--; if (x > 0) { - _xEndPoint -= x; - if (_xEndPoint <= 0) { + xEndPoint -= x; + if (xEndPoint <= 0) { return false; } - RCT2_GLOBAL(0x009ABDAE, sint16) += x; + if (!(image->flags & G1_FLAG_RLE_COMPRESSION)) { + RCT2_GLOBAL(0x009ABDAE, sint16) += x; + } } + if (image->flags & G1_FLAG_RLE_COMPRESSION) { + return sub_67933B_679788_679C4A_67A117(image->offset, xStartPoint, yStartPoint, round); + } + + uint8 *esi = image->offset + (yStartPoint * image->width) + xStartPoint; uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); if (!(image->flags & 2)) { - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); - - // ah and edx don't seem to be used by this function... return sub_679236_679662_679B0D_679FF1(ebx, image, esi); } @@ -2952,45 +2887,25 @@ static bool sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) rct_g1_element before_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 before_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 before_x = RCT2_GLOBAL(0x9ABDAE, sint16); - sint16 before_x_start_point = _xStartPoint; - sint16 before_y_start_point = _yStartPoint; - sint16 before_x_end_point = _xEndPoint; - sint16 before_y_end_point = _yEndPoint; RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); rct_g1_element original_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 original_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 original_x = RCT2_GLOBAL(0x9ABDAE, sint16); - sint16 original_x_start_point = _xStartPoint; - sint16 original_y_start_point = _yStartPoint; - sint16 original_x_end_point = _xEndPoint; - sint16 original_y_end_point = _yEndPoint; uint8 original_output = RCT2_GLOBAL(0x00141F569, uint8); RCT2_GLOBAL(0x9E3D08, rct_g1_element) = before_image; RCT2_GLOBAL(0xEDF81C, uint32) = before_palette; RCT2_GLOBAL(0x9ABDAE, sint16) = before_x; - _xStartPoint = before_x_start_point; - _yStartPoint = before_y_start_point; - _xEndPoint = before_x_end_point; - _yEndPoint = before_y_end_point; bool new_output = new_sub_679074(dpi, imageId, x, y); rct_g1_element new_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 new_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 new_x = RCT2_GLOBAL(0x9ABDAE, sint16); - sint16 new_x_start_point = _xStartPoint; - sint16 new_y_start_point = _yStartPoint; - sint16 new_x_end_point = _xEndPoint; - sint16 new_y_end_point = _yEndPoint; assert(new_image.offset == original_image.offset); assert(new_palette == original_palette); assert(new_x == original_x); - assert(new_x_start_point == original_x_start_point); - assert(new_y_start_point == original_y_start_point); - assert(new_x_end_point == original_x_end_point); - assert(new_y_end_point == original_y_end_point); assert(new_output == original_output); return new_output; @@ -3034,8 +2949,6 @@ void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint } (*esi_end) = new_source_pointer_start + (uint32) ebp; - sint8 ah = (_yEndPoint >> 8) & 0xFF; - int edx = RCT2_GLOBAL(0x009ABDAE, sint16); } /** From d8dbd8decf9ea36f878eac17d61f1eea7f59172f Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Wed, 2 Mar 2016 10:31:57 +0100 Subject: [PATCH 19/26] Use power of two for calculating round level --- src/interface/viewport.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 2fa70c93ba..ccd72929e4 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2763,24 +2763,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - int round; - switch (dpi->zoom_level) { - case 0: - default: - round = 1; - break; - - case 1: - round = 2; - break; - - case 2: - round = 4; - break; - - case 3: - round = 8; - } + int round = 1 << dpi->zoom_level; if (image->flags & G1_FLAG_RLE_COMPRESSION) { y -= (round - 1); From daee6748944bbe89968d15317559c502be2a5e5d Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Wed, 2 Mar 2016 10:42:59 +0100 Subject: [PATCH 20/26] Inline loc_6791B8_6795E4_679A8F_679F73 --- src/interface/viewport.c | 80 +++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index ccd72929e4..68e44da44d 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2232,8 +2232,6 @@ struct paint_string_struct { uint8 *y_offsets; // 0x1A }; -void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *image, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end); - static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi) { int zoom = dpi->zoom_level; @@ -2859,7 +2857,43 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 return sub_679236_679662_679B0D_679FF1(ebx, image, esi); } - loc_6791B8_6795E4_679A8F_679F73(image, esi, &new_source_pointer_start, &esi_end); + uint8 *ebp = esi; + uint8 *source_pointer; + + int total_no_pixels = image->width * image->height; + source_pointer = image->offset; + (*&new_source_pointer_start) = malloc(total_no_pixels); + uint8 *new_source_pointer = (*&new_source_pointer_start);// 0x9E3D28; + int ebx1, ecx; + while (total_no_pixels > 0) { + sint8 no_pixels = *source_pointer; + if (no_pixels >= 0) { + source_pointer++; + total_no_pixels -= no_pixels; + memcpy((char *) new_source_pointer, (char *) source_pointer, no_pixels); + new_source_pointer += no_pixels; + source_pointer += no_pixels; + continue; + } + ecx = no_pixels; + no_pixels &= 0x7; + ecx >>= 3;//SAR + int eax = ((int) no_pixels) << 8; + ecx = -ecx;//Odd + eax = (eax & 0xFF00) + *(source_pointer + 1); + total_no_pixels -= ecx; + source_pointer += 2; + ebx1 = (uint32) new_source_pointer - eax; + eax = (uint32) source_pointer; + source_pointer = (uint8 *) ebx1; + ebx1 = eax; + eax = 0; + memcpy((char *) new_source_pointer, (char *) source_pointer, ecx); + new_source_pointer += ecx; + source_pointer = (uint8 *) ebx1; + } + + (*&esi_end) = &new_source_pointer_start + (uint32) ebp; bool output = sub_679236_679662_679B0D_679FF1(ebx, image, esi_end); free(new_source_pointer_start); @@ -2894,46 +2928,6 @@ static bool sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) return new_output; } -void loc_6791B8_6795E4_679A8F_679F73(rct_g1_element *g1_source, uint8 *esi, uint8 **new_source_pointer_start, uint8 **esi_end) { - uint8 *ebp = esi; - uint8 *source_pointer; - - int total_no_pixels = g1_source->width * g1_source->height; - source_pointer = g1_source->offset; - (*new_source_pointer_start) = malloc(total_no_pixels); - uint8 *new_source_pointer = (*new_source_pointer_start);// 0x9E3D28; - int ebx, ecx; - while (total_no_pixels > 0) { - sint8 no_pixels = *source_pointer; - if (no_pixels >= 0) { - source_pointer++; - total_no_pixels -= no_pixels; - memcpy((char *) new_source_pointer, (char *) source_pointer, no_pixels); - new_source_pointer += no_pixels; - source_pointer += no_pixels; - continue; - } - ecx = no_pixels; - no_pixels &= 0x7; - ecx >>= 3;//SAR - int eax = ((int) no_pixels) << 8; - ecx = -ecx;//Odd - eax = (eax & 0xFF00) + *(source_pointer + 1); - total_no_pixels -= ecx; - source_pointer += 2; - ebx = (uint32) new_source_pointer - eax; - eax = (uint32) source_pointer; - source_pointer = (uint8 *) ebx; - ebx = eax; - eax = 0; - memcpy((char *) new_source_pointer, (char *) source_pointer, ecx); - new_source_pointer += ecx; - source_pointer = (uint8 *) ebx; - } - - (*esi_end) = new_source_pointer_start + (uint32) ebp; -} - /** * * rct2: 0x00679023 From cfed9fd1c0c8a3a7e2fadfcb1ea6b7ff2041e633 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Wed, 2 Mar 2016 10:48:01 +0100 Subject: [PATCH 21/26] Clean up variable declarations --- src/interface/viewport.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 68e44da44d..a46572b854 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2729,9 +2729,6 @@ static bool sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, si static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; - sint16 height; - uint8 *new_source_pointer_start, *esi_end; - if (dpi->zoom_level != 0) { if (image->flags & 0x20) { return false; @@ -2769,7 +2766,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y += image->y_offset; sint16 yStartPoint = 0; - height = image->height; + sint16 height = image->height; if (dpi->zoom_level != 0) { if (height % 2) { height--; @@ -2850,19 +2847,16 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 return sub_67933B_679788_679C4A_67A117(image->offset, xStartPoint, yStartPoint, round); } - uint8 *esi = image->offset + (yStartPoint * image->width) + xStartPoint; + uint8 *offset = image->offset + (yStartPoint * image->width) + xStartPoint; uint32 ebx = RCT2_GLOBAL(0x00EDF81C, uint32); if (!(image->flags & 2)) { - return sub_679236_679662_679B0D_679FF1(ebx, image, esi); + return sub_679236_679662_679B0D_679FF1(ebx, image, offset); } - uint8 *ebp = esi; - uint8 *source_pointer; - int total_no_pixels = image->width * image->height; - source_pointer = image->offset; - (*&new_source_pointer_start) = malloc(total_no_pixels); + uint8 *source_pointer = image->offset; + uint8 *new_source_pointer_start = malloc(total_no_pixels); uint8 *new_source_pointer = (*&new_source_pointer_start);// 0x9E3D28; int ebx1, ecx; while (total_no_pixels > 0) { @@ -2893,8 +2887,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 source_pointer = (uint8 *) ebx1; } - (*&esi_end) = &new_source_pointer_start + (uint32) ebp; - bool output = sub_679236_679662_679B0D_679FF1(ebx, image, esi_end); + bool output = sub_679236_679662_679B0D_679FF1(ebx, image, new_source_pointer_start + (uint32) offset); free(new_source_pointer_start); return output; From 6a368b1960745facaaff160dee3a263395c305e7 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Wed, 2 Mar 2016 11:10:19 +0100 Subject: [PATCH 22/26] Update function docblocks --- src/interface/viewport.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index a46572b854..3f14445d0c 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2632,6 +2632,9 @@ void store_interaction_info(paint_struct *ps) } } +/** + * rct2: 0x00679236, 0x00679662, 0x00679B0D, 0x00679FF1 + */ static bool sub_679236_679662_679B0D_679FF1(uint32 ebx, rct_g1_element *image, uint8 *esi) { if (!(image->flags & G1_FLAG_BMP)) { assert(false); @@ -2721,10 +2724,13 @@ static bool sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, si } /** + * rct2: 0x00679074 * - * rct2: 0x00679074 - * - * @return 0x00141F569 + * @param dpi (edi) + * @param imageId (ebx) + * @param x (cx) + * @param y (dx) + * @return value originally stored in 0x00141F569 */ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; From 0db00cdc750335793449525892ee74943388b931 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 3 Mar 2016 11:57:06 +0100 Subject: [PATCH 23/26] Add helper function for retrieving g1 element --- src/drawing/drawing.h | 1 + src/drawing/sprite.c | 15 +++++++++------ src/interface/viewport.c | 11 ++--------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index d0cf9e729e..cf1e2be650 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -123,6 +123,7 @@ int gfx_load_g1(); int gfx_load_g2(); void gfx_unload_g1(); void gfx_unload_g2(); +rct_g1_element* gfx_get_g1_element(int image_id); void sub_68371D(); void FASTCALL gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type); void FASTCALL gfx_rle_sprite_to_buffer(const uint8* source_bits_pointer, uint8* dest_bits_pointer, const uint8* palette_pointer, const rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width); diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 177f909535..eadd08a538 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -375,12 +375,7 @@ void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int image_element = image_id & 0x7FFFF; int image_type = (image_id & 0xE0000000) >> 28; - rct_g1_element* g1_source; - if (image_element < SPR_G2_BEGIN) { - g1_source = &g1Elements[image_element]; - } else { - g1_source = &g2.elements[image_element - SPR_G2_BEGIN]; - } + rct_g1_element *g1_source = gfx_get_g1_element(image_element); if ( dpi->zoom_level && (g1_source->flags & (1<<4)) ){ rct_drawpixelinfo zoomed_dpi = { @@ -553,3 +548,11 @@ void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, free(new_source_pointer_start); return; } + +rct_g1_element *gfx_get_g1_element(int image_id) { + if (image_id < SPR_G2_BEGIN) { + return &g1Elements[image_id]; + } + + return &g2.elements[image_id - SPR_G2_BEGIN]; +} diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 3f14445d0c..df685fab6b 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -907,15 +907,8 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int height, sint16 le ps->image_id = image_id; - rct_g1_element *g1Element; uint32 image_element = image_id & 0x7FFFF; - - if (image_element < SPR_G2_BEGIN) { - g1Element = &g1Elements[image_element]; - } - else { - g1Element = &g2.elements[image_element - SPR_G2_BEGIN]; - } + rct_g1_element *g1Element = gfx_get_g1_element(image_element); rct_xyz16 coord_3d = { .x = al, @@ -2733,7 +2726,7 @@ static bool sub_67933B_679788_679C4A_67A117(uint8 *esi, sint16 x_start_point, si * @return value originally stored in 0x00141F569 */ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { - rct_g1_element *image = &g1Elements[imageId & 0x7FFFF]; + rct_g1_element *image = gfx_get_g1_element(imageId & 0x7FFFF); if (dpi->zoom_level != 0) { if (image->flags & 0x20) { From 6ce6ad91664a0bbf11ed5caedc20c088057c572d Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 3 Mar 2016 13:19:33 +0100 Subject: [PATCH 24/26] Add comments --- src/interface/viewport.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index df685fab6b..880823eff1 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2629,8 +2629,8 @@ void store_interaction_info(paint_struct *ps) * rct2: 0x00679236, 0x00679662, 0x00679B0D, 0x00679FF1 */ static bool sub_679236_679662_679B0D_679FF1(uint32 ebx, rct_g1_element *image, uint8 *esi) { + // Probably used to check for corruption if (!(image->flags & G1_FLAG_BMP)) { - assert(false); return false; } @@ -2749,6 +2749,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 } } + // TODO: Check whether this assignment is used outside this function RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; @@ -2853,6 +2854,7 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 return sub_679236_679662_679B0D_679FF1(ebx, image, offset); } + // The code below is untested. int total_no_pixels = image->width * image->height; uint8 *source_pointer = image->offset; uint8 *new_source_pointer_start = malloc(total_no_pixels); From ea87812fe704cf07de6207694c3bcdcfb8df5e9b Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 3 Mar 2016 14:31:05 +0100 Subject: [PATCH 25/26] Don't store data in `0x9E3D08` --- src/interface/viewport.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 880823eff1..fbb48aa96e 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2749,15 +2749,6 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 } } - // TODO: Check whether this assignment is used outside this function - RCT2_GLOBAL(0x9E3D08, uint8*) = image->offset; - RCT2_GLOBAL(0x9E3D0C, sint16) = image->width; - RCT2_GLOBAL(0x9E3D0C + 2, sint16) = image->height; - RCT2_GLOBAL(0x9E3D10, sint16) = image->x_offset; - RCT2_GLOBAL(0x9E3D10 + 2, sint16) = image->y_offset; - RCT2_GLOBAL(0x9E3D14, uint16) = image->flags; - RCT2_GLOBAL(0x9E3D14 + 2, uint16) = image->zoomed_offset; - int round = 1 << dpi->zoom_level; if (image->flags & G1_FLAG_RLE_COMPRESSION) { @@ -2895,26 +2886,21 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 } static bool sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { - rct_g1_element before_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 before_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 before_x = RCT2_GLOBAL(0x9ABDAE, sint16); RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); - rct_g1_element original_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 original_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 original_x = RCT2_GLOBAL(0x9ABDAE, sint16); uint8 original_output = RCT2_GLOBAL(0x00141F569, uint8); - RCT2_GLOBAL(0x9E3D08, rct_g1_element) = before_image; RCT2_GLOBAL(0xEDF81C, uint32) = before_palette; RCT2_GLOBAL(0x9ABDAE, sint16) = before_x; bool new_output = new_sub_679074(dpi, imageId, x, y); - rct_g1_element new_image = RCT2_GLOBAL(0x9E3D08, rct_g1_element); uint32 new_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 new_x = RCT2_GLOBAL(0x9ABDAE, sint16); - assert(new_image.offset == original_image.offset); assert(new_palette == original_palette); assert(new_x == original_x); assert(new_output == original_output); From 93b190b54d8df73e1082374c55aca7db3cc332b1 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 3 Mar 2016 14:38:11 +0100 Subject: [PATCH 26/26] Clean up asserts --- src/interface/viewport.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index fbb48aa96e..88a6bba5d8 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2886,22 +2886,19 @@ static bool new_sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 } static bool sub_679074(rct_drawpixelinfo *dpi, int imageId, sint16 x, sint16 y) { - uint32 before_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 before_x = RCT2_GLOBAL(0x9ABDAE, sint16); + uint8 before_output = RCT2_GLOBAL(0x00141F569, uint8); RCT2_CALLPROC_X(0x00679074, 0, imageId, x, y, 0, (int) dpi, 0); - uint32 original_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 original_x = RCT2_GLOBAL(0x9ABDAE, sint16); uint8 original_output = RCT2_GLOBAL(0x00141F569, uint8); - RCT2_GLOBAL(0xEDF81C, uint32) = before_palette; RCT2_GLOBAL(0x9ABDAE, sint16) = before_x; + RCT2_GLOBAL(0x00141F569, uint8) = before_output; bool new_output = new_sub_679074(dpi, imageId, x, y); - uint32 new_palette = RCT2_GLOBAL(0xEDF81C, uint32); sint16 new_x = RCT2_GLOBAL(0x9ABDAE, sint16); - assert(new_palette == original_palette); assert(new_x == original_x); assert(new_output == original_output);