diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index 85a41e0f9c..cc323848b6 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -308,9 +308,6 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); rct_drawpixelinfo *windowDPI = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_DPI, rct_drawpixelinfo); - // Unsure what this does - RCT2_CALLPROC_X(0x00683326, left, top, right - 1, bottom - 1, 0, 0, 0); - windowDPI->bits = screenDPI->bits + left + ((screenDPI->width + screenDPI->pitch) * top); windowDPI->x = left; windowDPI->y = top; @@ -516,7 +513,66 @@ void gfx_draw_pickedup_peep() } } -void sub_681DE2(rct_drawpixelinfo *dpi, int x, int y, int image1, int image2) +/** + * Draws the given colour image masked out by the given mask image. This can currently only cope with bitmap formatted mask and + * colour images. Presumebly the original game never used RLE images for masking. Colour 0 represents transparent. + * + * rct2: 0x00681DE2 + */ +void gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage) { - RCT2_CALLPROC_X(0x00681DE2, 0, image1, x, y, 0, (int)dpi, image2); + int left, top, right, bottom, width, height; + rct_g1_element *imgMask = &g1Elements[maskImage & 0x7FFFF]; + rct_g1_element *imgColour = &g1Elements[colourImage & 0x7FFFF]; + + assert(imgMask->flags & 1); + assert(imgColour->flags & 1); + + if (dpi->zoom_level != 0) { + // TODO implement other zoom levels (probably not used though) + assert(false); + return; + } + + width = min(imgMask->width, imgColour->width); + height = min(imgMask->height, imgColour->height); + + x += imgMask->x_offset; + y += imgMask->y_offset; + + left = max(dpi->x, x); + top = max(dpi->y, y); + right = min(dpi->x + dpi->width, x + width); + bottom = min(dpi->y + dpi->height, y + height); + + width = right - left; + height = bottom - top; + if (width < 0 || height < 0) + return; + + int skipX = left - x; + int skipY = top - y; + + uint8 *maskSrc = imgMask->offset + (skipY * imgMask->width) + skipX; + uint8 *colourSrc = imgColour->offset + (skipY * imgColour->width) + skipX; + uint8 *dst = dpi->bits + (left - dpi->x) + ((top - dpi->y) * (dpi->width + dpi->pitch)); + + int maskWrap = imgMask->width - width; + int colourWrap = imgColour->width - width; + int dstWrap = ((dpi->width + dpi->pitch) - width); + for (int y = top; y < bottom; y++) { + for (int x = left; x < right; x++) { + uint8 colour = (*colourSrc) & (*maskSrc); + if (colour != 0) { + *dst = colour; + } + + maskSrc++; + colourSrc++; + dst++; + } + maskSrc += maskWrap; + colourSrc += colourWrap; + dst += dstWrap; + } } diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 280f48073f..49b36f6c57 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -112,6 +112,7 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width); void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); +void gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); // string int clip_text(char *buffer, int width); @@ -142,9 +143,6 @@ void ttf_dispose(); void update_rain_animation(); void redraw_rain(); -// unknown -void sub_681DE2(rct_drawpixelinfo *dpi, int x, int y, int image1, int image2); - // scrolling text void scrolling_text_initialise_bitmaps(); int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode); diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 8f13405a09..8a1dc70934 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -652,7 +652,7 @@ void paint_attached_ps(paint_struct* ps, paint_struct* attached_ps, rct_drawpixe } if (attached_ps->var_0C & 1) { - sub_681DE2(dpi, x, y, image_id, attached_ps->var_04); + gfx_draw_sprite_raw_masked(dpi, x, y, image_id, attached_ps->var_04); } else { gfx_draw_sprite(dpi, image_id, x, y, ps->var_04); } @@ -704,7 +704,7 @@ void sub_688485(){ } if (ps->var_1A & 1) - sub_681DE2(dpi, x, y, image_id, ps->var_04); + gfx_draw_sprite_raw_masked(dpi, x, y, image_id, ps->var_04); else gfx_draw_sprite(dpi, image_id, x, y, ps->var_04); diff --git a/src/windows/new_ride.c b/src/windows/new_ride.c index c035581e4a..0e1acc21eb 100644 --- a/src/windows/new_ride.c +++ b/src/windows/new_ride.c @@ -790,7 +790,7 @@ static void window_new_ride_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, i if (w->new_ride.highlighted_ride_id == *((sint16*)listItem) || flags != 0) gfx_fill_rect_inset(dpi, x, y, x + 115, y + 115, w->colours[1], 0x80 | flags); - // Draw ride image + // Draw ride image with feathered border rideEntry = rideEntries[listItem->entry_index]; int image_id = rideEntry->images_offset; if (listItem->type != rideEntry->ride_type[0]) { @@ -798,7 +798,7 @@ static void window_new_ride_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, i if (listItem->type != rideEntry->ride_type[1]) image_id++; } - sub_681DE2(dpi, x + 2, y + 2, 29013, image_id); + gfx_draw_sprite_raw_masked(dpi, x + 2, y + 2, 29013, image_id); // Next position x += 116;