diff --git a/src/addresses.h b/src/addresses.h index 56912ac3e9..b2e7533375 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -84,6 +84,11 @@ #define RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS 0x009ABDE8 #define RCT2_ADDRESS_DIRTY_BLOCK_ROWS 0x009ABDEC +//This is the number of pixels that are in the +//rain_pixel_store +#define RCT2_ADDRESS_NO_RAIN_PIXELS 0x009AC00C +#define RCT2_ADDRESS_RAIN_PATTERN 0x009AC010 + #define RCT2_ADDRESS_LIGHTNING_ACTIVE 0x009AC068 #define RCT2_ADDRESS_VIEWPORT_PAINT_BITS_PTR 0x009AC118 @@ -163,6 +168,10 @@ #define RCT2_ADDRESS_PATH_TYPES 0x009ADA14 +//Every pixel changed by rain is stored. +//32bit (pixel_offset 24 bit)(pixel_colour 8 bit) +#define RCT2_ADDRESS_RAIN_PIXEL_STORE 0x00EDF850 + #define RCT2_ADDRESS_MAP_IMAGE_DATA 0x00F1AD68 #define RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS 0x00F3EF92 diff --git a/src/game.c b/src/game.c index 841fcb2031..101d760904 100644 --- a/src/game.c +++ b/src/game.c @@ -65,7 +65,7 @@ void draw_light_rain(int left, int top, int width, int height){ edi += left; esi += top; - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x18; esi = (RCT2_GLOBAL(0x00F663AC, int) * 4) + 0x0D; @@ -73,8 +73,7 @@ void draw_light_rain(int left, int top, int width, int height){ edi += left; esi += top; - - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); } /** @@ -89,7 +88,7 @@ void draw_heavy_rain(int left, int top, int width, int height){ edi += left; esi += top; - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x10; esi = (RCT2_GLOBAL(0x00F663AC, int) * 6) + 5; @@ -98,7 +97,7 @@ void draw_heavy_rain(int left, int top, int width, int height){ edi += left; esi += top; - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); edi = -RCT2_GLOBAL(0x00F663AC, int) + 8; esi = (RCT2_GLOBAL(0x00F663AC, int) * 3) + 7; @@ -107,7 +106,7 @@ void draw_heavy_rain(int left, int top, int width, int height){ edi += left; esi += top; - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x18; esi = (RCT2_GLOBAL(0x00F663AC, int) * 4) + 0x0D; @@ -116,7 +115,7 @@ void draw_heavy_rain(int left, int top, int width, int height){ edi += left; esi += top; - RCT2_CALLPROC_X(0x00684027, left, top, width, height, esi, edi, 0); + gfx_draw_rain(left, top, width, height, edi, esi); } /** @@ -129,6 +128,9 @@ const draw_rain_func draw_rain_function[] = { &draw_heavy_rain // Heavy rain }; + + + /** * * rct2: 0x006ED801 diff --git a/src/gfx.c b/src/gfx.c index 272de4cdb0..bfdea7ccbd 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -2322,4 +2322,61 @@ rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int widt rct2_free(newDrawPixelInfo); return NULL; +} + +/*** +* +* rct2: 0x00684027 +* +* ebp used to be a parameter but it is always zero +* left : eax +* top : ebx +* width : ecx +* height : edx +* x_start: edi +* y_start: esi +*/ +void gfx_draw_rain(int left, int top, int width, int height, uint32 x_start, uint32 y_start){ + uint8* pattern = RCT2_GLOBAL(RCT2_ADDRESS_RAIN_PATTERN, uint8*); + uint8 pattern_x_space = *pattern++; + uint8 pattern_y_space = *pattern++; + + uint8 pattern_start_x_offset = x_start % pattern_x_space; + uint8 pattern_start_y_offset = y_start % pattern_y_space;; + + rct_drawpixelinfo* dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); + uint32 pixel_offset = (dpi->pitch + dpi->width)*top + left; + uint8 pattern_y_pos = pattern_start_y_offset; + + //Stores the colours of changed pixels + uint32* pixel_store = RCT2_ADDRESS(RCT2_ADDRESS_RAIN_PIXEL_STORE, uint32); + pixel_store += RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32); + + for (; height != 0; height--){ + uint8 pattern_x = pattern[pattern_y_pos * 2]; + if (pattern_x != 0xFF){ + if (RCT2_GLOBAL(0x9AC00C, uint32) <= 0x1F38){ + + int final_pixel_offset = width + pixel_offset; + + int x_pixel_offset = pixel_offset; + x_pixel_offset += ((uint8)(pattern_x - pattern_start_x_offset)) % pattern_x_space; + + uint8 pattern_pixel = pattern[pattern_y_pos * 2 + 1]; + for (; x_pixel_offset < final_pixel_offset; x_pixel_offset += pattern_x_space){ + uint8 current_pixel = dpi->bits[x_pixel_offset]; + dpi->bits[x_pixel_offset] = pattern_pixel; + RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32)++; + + //Store colour and position + *pixel_store++ = (x_pixel_offset << 8) | current_pixel; + } + } + } + + pixel_offset += dpi->pitch + dpi->width; + + pattern_y_pos++; + pattern_y_pos %= pattern_y_space; + } } \ No newline at end of file diff --git a/src/gfx.h b/src/gfx.h index f20d37e428..f57cc558f6 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -92,6 +92,8 @@ void gfx_draw_all_dirty_blocks(); void gfx_redraw_screen_rect(short left, short top, short right, short bottom); void gfx_invalidate_screen(); +void gfx_draw_rain(int left, int top, int width, int height, uint32 x_start, uint32 y_start); + rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height); #endif