diff --git a/src/gfx.c b/src/gfx.c index 8c0f84ae27..62435a8bdb 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -262,9 +262,10 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri } #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 -#define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 +#define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 #define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 -#define RCT2_X_RELATED_GLOBAL_2 0x9ABDA8 //sint16 +#define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 +#define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixelinfo *dpi){ if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ @@ -304,7 +305,7 @@ StartLoop: edx &= 0xFFFF0000; } edx += cx; - edx -= RCT2_GLOBAL(0x9ABDA8, sint16); + edx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); if (edx > 0){ cx -= edx; if (cx <= 0){ @@ -329,10 +330,10 @@ StartLoop: } TestLoop: if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; - edx = RCT2_GLOBAL(0x9ABDB0, sint16); + edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); ebp += edx; - RCT2_GLOBAL(0x9ABDAC, sint16)--; - if (RCT2_GLOBAL(0x9ABDAC, sint16))goto StartLoop; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16)--; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; } @@ -341,61 +342,75 @@ TestLoop: * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(rct_drawpixelinfo *source_dpi, rct_drawpixelinfo *dest_dpi, int x, int y){ +void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ - int _edi = dest_dpi, _esi; - sint16 translated_x = x, translated_y = y; char* bits_pointer; bits_pointer = dest_dpi->bits; - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dest_dpi->y; RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = source_dpi->y;//RCT2_GLOBAL(0x9E3D0E, sint16); - if (translated_y < 0) - { - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF808, sint16) -= translated_y; - translated_y = 0; - } - else{ - bits_pointer += (dest_dpi->width + dest_dpi->pitch)*translated_y; - } - - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dest_dpi->height; - if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; - } - - RCT2_GLOBAL(0xEDF80C, uint32) = 0; - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dest_dpi->x; - - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = source_dpi->x;//RCT2_GLOBAL(0x9E3D0C, sint16); - if (translated_x < 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF80C, sint16) -= translated_x; - translated_x = 0; - } - else{ - bits_pointer += translated_x; - } - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16); - translated_x -= dest_dpi->width; - if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; - } - - RCT2_GLOBAL(0x9ABDB0, uint16) = dest_dpi->width + dest_dpi->pitch; + int start_y, end_y; + start_y = y + source_g1->y_offset - dest_dpi->y; - // I dont think it uses ecx, edx but just in case - //esi is the source and bits_pointer is the destination - //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + //If the start position is negative reset to zero + if (start_y < 0){ + //Create the end point within the drawing area + end_y = source_g1->height + start_y; + //If the end point is now <= 0 no need to draw + if (end_y <= 0)return; - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dest_dpi); + RCT2_GLOBAL(0xEDF808, sint16) -= start_y; + start_y = 0; + } + else{ + end_y = source_g1->height; + //Move the pointer to the correct starting y location + bits_pointer += (dest_dpi->width + dest_dpi->pitch)*start_y; + } + + int height = start_y + end_y; + //If the image is taller than the drawing area + if (height > dest_dpi->height){ + //Make the end within the drawing area + end_y -= height - dest_dpi->height; + //If the end is now <=0 then there is nothing to draw + if (end_y <= 0)return; + } + + RCT2_GLOBAL(0xEDF80C, uint32) = 0; + int start_x, end_x; + start_x = x + source_g1->x_offset - dest_dpi->x; + + //If the start position is negative reset to zero + if (start_x < 0){ + //Create the end point within the drawing area + end_x = source_g1->width + start_x; + //If the end point is now <= 0 no need to draw + if (end_x <= 0)return; + + RCT2_GLOBAL(0xEDF80C, sint16) -= start_x; + start_x = 0; + } + else{ + end_x = source_g1->width; + //Increment the pointer to our start location + bits_pointer += start_x; + } + + int width = start_x + end_x; + //If the image is wider than the drawing area + if (width > dest_dpi->width){ + //Make the end within drawing area + end_x -= width - dest_dpi->width; + //If the end is now <=0 then there is nothing to draw + if (end_x <= 0)return; + } + + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; + //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); } /** @@ -423,7 +438,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return;//jump into 0x67a445 } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - char* find = "FINDMEDUNCAN"; RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return;//jump into 0x67a361 } @@ -477,16 +491,17 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); - rct_drawpixelinfo* g1_source_dpi = (rct_drawpixelinfo*)ebx; + rct_g1_element* g1_source = (rct_g1_element*)ebx; //This is a rct2_drawpixelinfo struct RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); + if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); - sub_0x67A934(g1_source_dpi, dpi, x, y); + sub_0x67A934(g1_source, dpi, x, y); return; } @@ -499,14 +514,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); translated_y = y + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; if (translated_y < 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) += translated_y; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0){ return; } translated_y = -translated_y; @@ -518,53 +533,53 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) bits_pointer += eax; } - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height;; + translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height;; if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <=0) + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0) { return; } } - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); eax = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(0x9ABDB0, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); translated_x = x + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; if (translated_x < 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ return; } translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); esi -= translated_x; RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; - RCT2_GLOBAL(0x9ABDB0, sint16) -= translated_x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) -= translated_x; translated_x = 0; } bits_pointer += translated_x; - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) - dpi->width; + translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) - dpi->width; if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ return; } RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; - RCT2_GLOBAL(0x9ABDB0, sint16) += translated_x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) += translated_x; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8)) << 8; + eax = (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; edx = RCT2_GLOBAL(0x9ABDAE, sint16); - ebp = RCT2_GLOBAL(0x9ABDB0, sint16); + ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690