diff --git a/src/drawing/IDrawingContext.h b/src/drawing/IDrawingContext.h index ad5b1edf02..d14a60cfaf 100644 --- a/src/drawing/IDrawingContext.h +++ b/src/drawing/IDrawingContext.h @@ -26,7 +26,9 @@ interface IDrawingContext virtual IDrawingEngine * GetEngine() abstract; - virtual void Clear(uint32 colour) abstract; - virtual void FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) abstract; - virtual void DrawSprite(uint32 image, sint32 x, sint32 y) abstract; + virtual void Clear(uint32 colour) abstract; + virtual void FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) abstract; + virtual void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) abstract; + virtual void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) abstract; + virtual void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) abstract; }; diff --git a/src/drawing/NewDrawing.cpp b/src/drawing/NewDrawing.cpp index 35381321ec..0565df03dd 100644 --- a/src/drawing/NewDrawing.cpp +++ b/src/drawing/NewDrawing.cpp @@ -70,10 +70,6 @@ extern "C" { } - /** - * Clears the screen with the specified colour. - * rct2: 0x00678A9F - */ void gfx_clear(rct_drawpixelinfo * dpi, int colour) { if (_drawingEngine != nullptr) @@ -83,17 +79,7 @@ extern "C" } } - /** - * - * rct2: 0x00678AD4 - * dpi (edi) - * left (ax) - * top (cx) - * right (bx) - * bottom (dx) - * colour (ebp) - */ - void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour) + void gfx_fill_rect(rct_drawpixelinfo * dpi, int left, int top, int right, int bottom, int colour) { if (_drawingEngine != nullptr) { @@ -101,4 +87,31 @@ extern "C" dc->FillRect(colour, left, top, right, bottom); } } + + void FASTCALL gfx_draw_sprite(rct_drawpixelinfo * dpi, int image, int x, int y, uint32 tertiary_colour) + { + if (_drawingEngine != nullptr) + { + IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); + dc->DrawSprite(image, x, y, tertiary_colour); + } + } + + void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 * palette, uint8 * unknown) + { + if (_drawingEngine != nullptr) + { + IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); + dc->DrawSpritePaletteSet(image, x, y, palette, unknown); + } + } + + void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo * dpi, int x, int y, int maskImage, int colourImage) + { + if (_drawingEngine != nullptr) + { + IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi); + dc->DrawSpriteRawMasked(x, y, maskImage, colourImage); + } + } } diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index 0801364f87..0fe4fc32b5 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -293,70 +293,6 @@ void gfx_draw_pickedup_peep() } } -/** - * Draws the given colour image masked out by the given mask image. This can currently only cope with bitmap formatted mask and - * colour images. Presumably the original game never used RLE images for masking. Colour 0 represents transparent. - * - * rct2: 0x00681DE2 - */ -void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage) -{ - 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; - } -} - void gfx_configure_dirty_grid() { _screenDirtyBlockShiftX = 7; diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index de4092b08c..c267afcc97 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -148,12 +148,15 @@ 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* RESTRICT source_bits_pointer, uint8* RESTRICT dest_bits_pointer, const uint8* RESTRICT palette_pointer, const rct_drawpixelinfo * RESTRICT dpi, int image_type, int source_y_start, int height, int source_x_start, int width); void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); +void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); +void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); +void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage); + // string int clip_text(char *buffer, int width); int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height); diff --git a/src/drawing/engines/SoftwareDrawingEngine.cpp b/src/drawing/engines/SoftwareDrawingEngine.cpp index 18f9eabbcc..afc0e2eee8 100644 --- a/src/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/drawing/engines/SoftwareDrawingEngine.cpp @@ -165,7 +165,9 @@ public: void Clear(uint32 colour) override; void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override; - void DrawSprite(uint32 image, sint32 x, sint32 y) override; + void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; + void DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) override; + void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; void SetDPI(rct_drawpixelinfo * dpi); }; @@ -749,9 +751,19 @@ void SoftwareDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, si } } -void SoftwareDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y) +void SoftwareDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) { + gfx_draw_sprite_software(_dpi, image, x, y, tertiaryColour); +} +void SoftwareDrawingContext::DrawSpritePaletteSet(uint32 image, sint32 x, sint32 y, uint8 * palette, uint8 * unknown) +{ + gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, unknown); +} + +void SoftwareDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) +{ + gfx_draw_sprite_raw_masked_software(_dpi, x, y, maskImage, colourImage); } void SoftwareDrawingContext::SetDPI(rct_drawpixelinfo * dpi) diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 8ab3e55ba8..596a13a6ff 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -138,7 +138,7 @@ void sub_68371D() * image. * rct2: 0x0067A690 */ -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){ +static 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){ uint16 zoom_level = dest_dpi->zoom_level; uint8 zoom_amount = 1 << zoom_level; uint32 dest_line_width = (dest_dpi->width / zoom_amount) + dest_dpi->pitch; @@ -282,7 +282,7 @@ void FASTCALL gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_po * dpi (esi) * tertiary_colour (ebp) */ -void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour) +void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour) { int image_type = (image_id & 0xE0000000) >> 28; int image_sub_type = (image_id & 0x1C000000) >> 26; @@ -366,7 +366,7 @@ void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y * x (cx) * y (dx) */ -void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer) +void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer) { int image_element = image_id & 0x7FFFF; int image_type = (image_id & 0xE0000000) >> 28; @@ -545,6 +545,70 @@ void FASTCALL gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, return; } +/** + * Draws the given colour image masked out by the given mask image. This can currently only cope with bitmap formatted mask and + * colour images. Presumably the original game never used RLE images for masking. Colour 0 represents transparent. + * + * rct2: 0x00681DE2 + */ +void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage) +{ + 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; + } +} + rct_g1_element *gfx_get_g1_element(int image_id) { if (image_id < SPR_G2_BEGIN) { return &g1Elements[image_id];