diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 5e7bbdf04e..16dee7ba1e 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -176,7 +176,7 @@ void TextureCache::GeneratePaletteTexture() GLint y = PaletteToY(i); uint16_t image = palette_to_g1_offset[i]; auto element = gfx_get_g1_element(image); - gfx_draw_sprite_software(&dpi, ImageId(image), -element->x_offset, y - element->y_offset, 0); + gfx_draw_sprite_software(&dpi, ImageId(image), -element->x_offset, y - element->y_offset); } glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture); @@ -299,7 +299,7 @@ rct_drawpixelinfo TextureCache::GetImageAsDPI(uint32_t image, uint32_t tertiaryC int32_t height = g1Element->height; rct_drawpixelinfo dpi = CreateDPI(width, height); - gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(image), -g1Element->x_offset, -g1Element->y_offset, tertiaryColour); + gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(image, tertiaryColour), -g1Element->x_offset, -g1Element->y_offset); return dpi; } @@ -310,7 +310,8 @@ rct_drawpixelinfo TextureCache::GetGlyphAsDPI(uint32_t image, uint8_t* palette) int32_t height = g1Element->height; rct_drawpixelinfo dpi = CreateDPI(width, height); - gfx_draw_sprite_palette_set_software(&dpi, ImageId::FromUInt32(image), -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); + gfx_draw_sprite_palette_set_software( + &dpi, ImageId::FromUInt32(image), -g1Element->x_offset, -g1Element->y_offset, palette, nullptr); return dpi; } diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index d58e3186db..769a2b07b9 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -508,12 +508,9 @@ void FASTCALL gfx_bmp_sprite_to_buffer( } } -uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId, uint32_t tertiary_colour) +uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId) { - if (!imageId.HasPrimary() && !imageId.HasSecondary() && !imageId.IsBlended()) - return nullptr; - - if (!imageId.HasSecondary()) + if (imageId.IsRemap()) { uint8_t palette_ref = imageId.GetRemap(); if (!imageId.IsBlended()) @@ -532,20 +529,20 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId, uint32_t tertiary return g1->offset; } } - else + else if (imageId.HasSecondary()) { uint8_t* palette_pointer = gPeepPalette; uint32_t primary_offset = palette_to_g1_offset[imageId.GetPrimary()]; uint32_t secondary_offset = palette_to_g1_offset[imageId.GetSecondary()]; - if (!imageId.HasPrimary()) + if (imageId.HasTertiary()) { palette_pointer = gOtherPalette; #if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2 assert(tertiary_colour < PALETTE_TO_G1_OFFSET_COUNT); #endif // DEBUG_LEVEL_2 - uint32_t tertiary_offset = palette_to_g1_offset[tertiary_colour]; + uint32_t tertiary_offset = palette_to_g1_offset[imageId.GetTertiary()]; auto tertiary_palette = gfx_get_g1_element(tertiary_offset); if (tertiary_palette != nullptr) { @@ -565,35 +562,18 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId, uint32_t tertiary return palette_pointer; } + else + { + return nullptr; + } } -/** - * - * rct2: 0x0067A28E - * image_id (ebx) - * image_id as below - * 0b_111X_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_type - * 0b_XXX1_11XX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX image_sub_type (unknown pointer) - * 0b_XXX1_1111_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX secondary_colour - * 0b_XXXX_XXXX_1111_1XXX_XXXX_XXXX_XXXX_XXXX primary_colour - * 0b_XXXX_X111_1111_1XXX_XXXX_XXXX_XXXX_XXXX palette_ref - * 0b_XXXX_XXXX_XXXX_X111_1111_1111_1111_1111 image_id (offset to g1) - * x (cx) - * y (dx) - * dpi (esi) - * tertiary_colour (ebp) - */ -void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y, uint32_t tertiary_colour) +void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y) { if (imageId.HasValue()) { - uint8_t* palette_pointer = gfx_draw_sprite_get_palette(imageId, tertiary_colour); - if (imageId.HasSecondary()) - { - imageId = imageId.WithPrimary(imageId.GetPrimary()); - } - - gfx_draw_sprite_palette_set_software(dpi, imageId, x, y, palette_pointer, nullptr); + auto palette = gfx_draw_sprite_get_palette(imageId); + gfx_draw_sprite_palette_set_software(dpi, imageId, x, y, palette, nullptr); } } @@ -786,7 +766,7 @@ void FASTCALL // Only BMP format is supported for masking if (!(imgMask->flags & G1_FLAG_BMP) || !(imgColour->flags & G1_FLAG_BMP)) { - gfx_draw_sprite_software(dpi, ImageId::FromUInt32(colourImage), x, y, 0); + gfx_draw_sprite_software(dpi, ImageId::FromUInt32(colourImage), x, y); return; } diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 2d24c6983e..0570458bf6 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -266,6 +266,7 @@ private: // clang-format on uint32_t _value = VALUE_UNDEFINED; + uint8_t _tertiary = 0; public: static ImageId FromUInt32(uint32_t value) @@ -275,6 +276,14 @@ public: return result; } + static ImageId FromUInt32(uint32_t value, uint32_t tertiary) + { + ImageId result; + result._value = value; + result._tertiary = tertiary & 0xFF; + return result; + } + ImageId() = default; explicit ImageId(uint32_t index) @@ -282,8 +291,8 @@ public: { } - ImageId(uint32_t index, colour_t primaryColour) - : ImageId(ImageId(index).WithPrimary(primaryColour)) + ImageId(uint32_t index, uint8_t primaryColourOrPalette) + : ImageId(ImageId(index).WithPrimary(primaryColourOrPalette)) { } @@ -292,6 +301,11 @@ public: { } + ImageId(uint32_t index, colour_t primaryColour, colour_t secondaryColour, colour_t tertiaryColour) + : ImageId(ImageId(index).WithPrimary(primaryColour).WithSecondary(secondaryColour).WithTertiary(tertiaryColour)) + { + } + uint32_t ToUInt32() const { return _value; @@ -304,7 +318,7 @@ public: bool HasPrimary() const { - return _value & FLAG_PRIMARY; + return (_value & FLAG_PRIMARY) || (_value & FLAG_SECONDARY); } bool HasSecondary() const @@ -312,6 +326,16 @@ public: return _value & FLAG_SECONDARY; } + bool HasTertiary() const + { + return !(_value & FLAG_PRIMARY) && (_value & FLAG_SECONDARY); + } + + bool IsRemap() const + { + return (_value & FLAG_PRIMARY) && !(_value & FLAG_SECONDARY); + } + bool IsBlended() const { return _value & FLAG_BLEND; @@ -337,6 +361,11 @@ public: return (_value & MASK_SECONDARY) >> SHIFT_SECONDARY; } + colour_t GetTertiary() const + { + return _tertiary; + } + ImageCatalogue GetCatalogue() const; ImageId WithIndex(uint32_t index) @@ -359,6 +388,21 @@ public: result._value = (_value & ~MASK_SECONDARY) | ((colour << SHIFT_SECONDARY) & MASK_SECONDARY) | FLAG_SECONDARY; return result; } + + ImageId WithTertiary(colour_t tertiary) + { + ImageId result = *this; + result._value &= ~FLAG_PRIMARY; + if (!(_value & FLAG_SECONDARY)) + { + // Tertiary implies primary and secondary, so if colour was remap (8-bit primary) then + // we need to zero the secondary colour. + result._value &= ~MASK_SECONDARY; + result._value |= FLAG_SECONDARY; + } + result._tertiary = tertiary; + return result; + } }; #define SPRITE_ID_PALETTE_COLOUR_1(colourId) (IMAGE_TYPE_REMAP | ((colourId) << 19)) @@ -454,8 +498,8 @@ void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage); void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t colour); -void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y, uint32_t tertiary_colour); -uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId, uint32_t tertiary_colour); +void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y); +uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId); void FASTCALL gfx_draw_sprite_palette_set_software( rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer); void FASTCALL diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index e6ba629473..441ece67c3 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -53,7 +53,7 @@ void scrolling_text_initialise_bitmaps() for (int32_t i = 0; i < FONT_SPRITE_GLYPH_COUNT; i++) { std::fill_n(drawingSurface, sizeof(drawingSurface), 0x00); - gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(SPR_CHAR_START + FONT_SPRITE_BASE_TINY + i), -1, 0, 0); + gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(SPR_CHAR_START + FONT_SPRITE_BASE_TINY + i), -1, 0); for (int32_t x = 0; x < 8; x++) { @@ -75,7 +75,7 @@ void scrolling_text_initialise_bitmaps() { std::fill_n(drawingSurface, sizeof(drawingSurface), 0x00); gfx_draw_sprite_software( - &dpi, ImageId::FromUInt32(SPR_G2_CHAR_BEGIN + (FONT_SIZE_TINY * SPR_G2_GLYPH_COUNT) + i), -1, 0, 0); + &dpi, ImageId::FromUInt32(SPR_G2_CHAR_BEGIN + (FONT_SIZE_TINY * SPR_G2_GLYPH_COUNT) + i), -1, 0); for (int32_t x = 0; x < 8; x++) { diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 774a6a58bb..36f321ba3a 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -730,7 +730,7 @@ void X8DrawingContext::DrawLine(uint32_t colour, int32_t x1, int32_t y1, int32_t void X8DrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) { - gfx_draw_sprite_software(_dpi, ImageId::FromUInt32(image), x, y, tertiaryColour); + gfx_draw_sprite_software(_dpi, ImageId::FromUInt32(image, tertiaryColour), x, y); } void X8DrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) @@ -743,7 +743,8 @@ void X8DrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uin uint8_t palette[256]; std::fill_n(palette, sizeof(palette), colour); palette[0] = 0; - gfx_draw_sprite_palette_set_software(_dpi, ImageId::FromUInt32((image & 0x7FFFF) | IMAGE_TYPE_REMAP), x, y, palette, nullptr); + gfx_draw_sprite_palette_set_software( + _dpi, ImageId::FromUInt32((image & 0x7FFFF) | IMAGE_TYPE_REMAP), x, y, palette, nullptr); } void X8DrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t* palette) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index e8a6f3806e..a9c8b784bf 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -6072,7 +6072,7 @@ void set_vehicle_type_image_max_sizes(rct_ride_entry_vehicle* vehicle_type, int3 for (int32_t i = 0; i < num_images; ++i) { - gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(vehicle_type->base_image_id + i), 0, 0, 0); + gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(vehicle_type->base_image_id + i), 0, 0); } int32_t al = -1; for (int32_t i = 99; i != 0; --i)