1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

re-route draw sprite through IDrawingContext

This commit is contained in:
Ted John
2016-06-04 11:31:51 +01:00
parent 90704ac1fe
commit d20a8a1daa
6 changed files with 118 additions and 88 deletions

View File

@@ -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;
};

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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];