Start using ImageId

This commit is contained in:
Ted John 2019-08-24 18:35:40 +01:00
parent 583855d639
commit 3925a6162d
8 changed files with 106 additions and 60 deletions

View File

@ -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, image, -element->x_offset, y - element->y_offset, 0);
gfx_draw_sprite_software(&dpi, ImageId(image), -element->x_offset, y - element->y_offset, 0);
}
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, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(image), -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
return dpi;
}
@ -310,7 +310,7 @@ 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, 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;
}

View File

@ -238,14 +238,14 @@ static bool sprite_file_export(int32_t spriteIndex, const char* outPath)
if (spriteHeader->flags & G1_FLAG_RLE_COMPRESSION)
{
gfx_rle_sprite_to_buffer(
spriteHeader->offset, pixels, (uint8_t*)spriteFilePalette, &dpi, IMAGE_TYPE_DEFAULT, 0, spriteHeader->height, 0,
spriteHeader->offset, pixels, (uint8_t*)spriteFilePalette, &dpi, ImageId(), 0, spriteHeader->height, 0,
spriteHeader->width);
}
else
{
gfx_bmp_sprite_to_buffer(
(uint8_t*)spriteFilePalette, spriteHeader->offset, pixels, spriteHeader, &dpi, spriteHeader->height,
spriteHeader->width, IMAGE_TYPE_DEFAULT);
spriteHeader->width, ImageId());
}
auto const pixels8 = dpi.bits;

View File

@ -402,10 +402,11 @@ bool gfx_load_csg()
* Copies a sprite onto the buffer. There is no compression used on the sprite
* image.
* rct2: 0x0067A690
* @param imageId Only flags are used.
*/
void FASTCALL gfx_bmp_sprite_to_buffer(
const uint8_t* palette_pointer, uint8_t* source_pointer, uint8_t* dest_pointer, const rct_g1_element* source_image,
rct_drawpixelinfo* dest_dpi, int32_t height, int32_t width, int32_t image_type)
rct_drawpixelinfo* dest_dpi, int32_t height, int32_t width, ImageId imageId)
{
uint16_t zoom_level = dest_dpi->zoom_level;
uint8_t zoom_amount = 1 << zoom_level;
@ -413,7 +414,7 @@ void FASTCALL gfx_bmp_sprite_to_buffer(
uint32_t source_line_width = source_image->width * zoom_amount;
// Image uses the palette pointer to remap the colours of the image
if (image_type & IMAGE_TYPE_REMAP)
if (imageId.HasPrimary())
{
assert(palette_pointer != nullptr);
@ -442,7 +443,7 @@ void FASTCALL gfx_bmp_sprite_to_buffer(
// Image is transparent. It only uses source pointer for
// telling if it needs to be drawn not for colour. Colour provided
// by the palette pointer.
if (image_type & IMAGE_TYPE_TRANSPARENT)
if (imageId.IsBlended())
{ // Not tested
assert(palette_pointer != nullptr);
for (; height > 0; height -= zoom_amount)
@ -507,16 +508,15 @@ void FASTCALL gfx_bmp_sprite_to_buffer(
}
}
uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiary_colour)
uint8_t* FASTCALL gfx_draw_sprite_get_palette(ImageId imageId, uint32_t tertiary_colour)
{
int32_t image_type = (image_id & 0xE0000000);
if (image_type == 0)
if (!imageId.HasPrimary() && !imageId.HasSecondary() && !imageId.IsBlended())
return nullptr;
if (!(image_type & IMAGE_TYPE_REMAP_2_PLUS))
if (!imageId.HasSecondary())
{
uint8_t palette_ref = (image_id >> 19) & 0xFF;
if (!(image_type & IMAGE_TYPE_TRANSPARENT))
uint8_t palette_ref = imageId.GetRemap();
if (!imageId.IsBlended())
{
palette_ref &= 0x7F;
}
@ -536,10 +536,10 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiar
{
uint8_t* palette_pointer = gPeepPalette;
uint32_t primary_offset = palette_to_g1_offset[(image_id >> 19) & 0x1F];
uint32_t secondary_offset = palette_to_g1_offset[(image_id >> 24) & 0x1F];
uint32_t primary_offset = palette_to_g1_offset[imageId.GetPrimary()];
uint32_t secondary_offset = palette_to_g1_offset[imageId.GetSecondary()];
if (!(image_type & IMAGE_TYPE_REMAP))
if (!imageId.HasPrimary())
{
palette_pointer = gOtherPalette;
#if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2
@ -583,17 +583,17 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiar
* dpi (esi)
* tertiary_colour (ebp)
*/
void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, int32_t image_id, 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, uint32_t tertiary_colour)
{
if (image_id != -1)
if (imageId.HasValue())
{
uint8_t* palette_pointer = gfx_draw_sprite_get_palette(image_id, tertiary_colour);
if (image_id & IMAGE_TYPE_REMAP_2_PLUS)
uint8_t* palette_pointer = gfx_draw_sprite_get_palette(imageId, tertiary_colour);
if (imageId.HasSecondary())
{
image_id |= IMAGE_TYPE_REMAP;
imageId = imageId.WithPrimary(imageId.GetPrimary());
}
gfx_draw_sprite_palette_set_software(dpi, image_id, x, y, palette_pointer, nullptr);
gfx_draw_sprite_palette_set_software(dpi, imageId, x, y, palette_pointer, nullptr);
}
}
@ -607,12 +607,9 @@ void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, int32_t image_id,
* y (dx)
*/
void FASTCALL gfx_draw_sprite_palette_set_software(
rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer)
rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer)
{
int32_t image_element = image_id & 0x7FFFF;
int32_t image_type = image_id & 0xE0000000;
const rct_g1_element* g1 = gfx_get_g1_element(image_element);
const auto* g1 = gfx_get_g1_element(imageId);
if (g1 == nullptr)
{
return;
@ -629,7 +626,8 @@ void FASTCALL gfx_draw_sprite_palette_set_software(
zoomed_dpi.pitch = dpi->pitch;
zoomed_dpi.zoom_level = dpi->zoom_level - 1;
gfx_draw_sprite_palette_set_software(
&zoomed_dpi, image_type | (image_element - g1->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer);
&zoomed_dpi, imageId.WithIndex(imageId.GetIndex() - g1->zoomed_offset), x >> 1, y >> 1, palette_pointer,
unknown_pointer);
return;
}
@ -757,16 +755,14 @@ void FASTCALL gfx_draw_sprite_palette_set_software(
// We have to use a different method to move the source pointer for
// rle encoded sprites so that will be handled within this function
gfx_rle_sprite_to_buffer(
g1->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width);
g1->offset, dest_pointer, palette_pointer, dpi, imageId, source_start_y, height, source_start_x, width);
return;
}
uint8_t* source_pointer = g1->offset;
// Move the pointer to the start point of the source
source_pointer += g1->width * source_start_y + source_start_x;
if (!(g1->flags & G1_FLAG_1))
else if (!(g1->flags & G1_FLAG_1))
{
gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1, dpi, height, width, image_type);
// Move the pointer to the start point of the source
auto source_pointer = g1->offset + (((size_t)g1->width * source_start_y) + source_start_x);
gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1, dpi, height, width, imageId);
}
}
@ -790,7 +786,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, colourImage, x, y, 0);
gfx_draw_sprite_software(dpi, ImageId::FromUInt32(colourImage), x, y, 0);
return;
}
@ -831,6 +827,11 @@ void FASTCALL
mask_fn(width, height, maskSrc, colourSrc, dst, maskWrap, colourWrap, dstWrap);
}
const rct_g1_element* gfx_get_g1_element(ImageId imageId)
{
return gfx_get_g1_element(imageId.GetIndex());
}
const rct_g1_element* gfx_get_g1_element(int32_t image_id)
{
openrct2_assert(!gOpenRCT2NoGraphics, "gfx_get_g1_element called on headless instance");

View File

@ -252,19 +252,32 @@ struct ImageId
private:
// clang-format off
static constexpr uint32_t MASK_INDEX = 0b00000000000001111111111111111111;
static constexpr uint32_t MASK_REMAP = 0b00000111111110000000000000000000;
static constexpr uint32_t MASK_PRIMARY = 0b00000000111110000000000000000000;
static constexpr uint32_t MASK_SECONDARY = 0b00011111000000000000000000000000;
static constexpr uint32_t FLAG_PRIMARY = 0b00100000000000000000000000000000;
static constexpr uint32_t FLAG_TRANSPARENT = 0b01000000000000000000000000000000;
static constexpr uint32_t FLAG_BLEND = 0b01000000000000000000000000000000;
static constexpr uint32_t FLAG_SECONDARY = 0b10000000000000000000000000000000;
static constexpr uint32_t SHIFT_REMAP = 19;
static constexpr uint32_t SHIFT_PRIMARY = 19;
static constexpr uint32_t SHIFT_SECONDARY = 24;
static constexpr uint32_t INDEX_UNDEFINED = 0b00000000000001111111111111111111;
static constexpr uint32_t VALUE_UNDEFINED = INDEX_UNDEFINED;
// clang-format on
uint32_t _value;
uint32_t _value = VALUE_UNDEFINED;
public:
ImageId(uint32_t index)
static ImageId FromUInt32(uint32_t value)
{
ImageId result;
result._value = value;
return result;
}
ImageId() = default;
explicit ImageId(uint32_t index)
: _value(index & MASK_INDEX)
{
}
@ -284,23 +297,55 @@ public:
return _value;
}
bool HasValue() const
{
return GetIndex() != INDEX_UNDEFINED;
}
bool HasPrimary() const
{
return _value & FLAG_PRIMARY;
}
bool HasSecondary() const
{
return _value & FLAG_SECONDARY;
}
bool IsBlended() const
{
return _value & FLAG_BLEND;
}
uint32_t GetIndex() const
{
return _value & MASK_INDEX;
}
uint8_t GetRemap() const
{
return (_value & MASK_REMAP) >> SHIFT_REMAP;
}
colour_t GetPrimary() const
{
return _value & MASK_PRIMARY;
return (_value & MASK_PRIMARY) >> SHIFT_PRIMARY;
}
colour_t GetSecondary() const
{
return _value & MASK_SECONDARY;
return (_value & MASK_SECONDARY) >> SHIFT_SECONDARY;
}
ImageCatalogue GetCatalogue() const;
ImageId WithIndex(uint32_t index)
{
ImageId result = *this;
result._value = (_value & ~MASK_INDEX) | (index & MASK_INDEX);
return result;
}
ImageId WithPrimary(colour_t colour)
{
ImageId result = *this;
@ -390,6 +435,7 @@ bool gfx_load_csg();
void gfx_unload_g1();
void gfx_unload_g2();
void gfx_unload_csg();
const rct_g1_element* gfx_get_g1_element(ImageId imageId);
const rct_g1_element* gfx_get_g1_element(int32_t image_id);
void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1);
bool is_csg_loaded();
@ -398,21 +444,20 @@ void gfx_object_free_images(uint32_t baseImageId, uint32_t count);
void gfx_object_check_all_images_freed();
void FASTCALL gfx_bmp_sprite_to_buffer(
const uint8_t* palette_pointer, uint8_t* source_pointer, uint8_t* dest_pointer, const rct_g1_element* source_image,
rct_drawpixelinfo* dest_dpi, int32_t height, int32_t width, int32_t image_type);
rct_drawpixelinfo* dest_dpi, int32_t height, int32_t width, ImageId imageId);
void FASTCALL gfx_rle_sprite_to_buffer(
const uint8_t* RESTRICT source_bits_pointer, uint8_t* RESTRICT dest_bits_pointer, const uint8_t* RESTRICT palette_pointer,
const rct_drawpixelinfo* RESTRICT dpi, int32_t image_type, int32_t source_y_start, int32_t height, int32_t source_x_start,
const rct_drawpixelinfo* RESTRICT dpi, ImageId imageId, int32_t source_y_start, int32_t height, int32_t source_x_start,
int32_t width);
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour);
void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette);
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, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour);
uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiary_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_palette_set_software(
rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer);
rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer);
void FASTCALL
gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage);

View File

@ -176,15 +176,16 @@ static void FASTCALL DrawRLESprite1(
* Transfers readied images onto buffers
* This function copies the sprite data onto the screen
* rct2: 0x0067AA18
* @param imageId Only flags are used.
*/
void FASTCALL gfx_rle_sprite_to_buffer(
const uint8_t* RESTRICT source_bits_pointer, uint8_t* RESTRICT dest_bits_pointer, const uint8_t* RESTRICT palette_pointer,
const rct_drawpixelinfo* RESTRICT dpi, int32_t image_type, int32_t source_y_start, int32_t height, int32_t source_x_start,
const rct_drawpixelinfo* RESTRICT dpi, ImageId imageId, int32_t source_y_start, int32_t height, int32_t source_x_start,
int32_t width)
{
if (image_type & IMAGE_TYPE_REMAP)
if (imageId.HasPrimary())
{
if (image_type & IMAGE_TYPE_TRANSPARENT)
if (imageId.IsBlended())
{
DrawRLESpriteHelper1(IMAGE_TYPE_REMAP | IMAGE_TYPE_TRANSPARENT);
}
@ -193,7 +194,7 @@ void FASTCALL gfx_rle_sprite_to_buffer(
DrawRLESpriteHelper1(IMAGE_TYPE_REMAP);
}
}
else if (image_type & IMAGE_TYPE_TRANSPARENT)
else if (imageId.IsBlended())
{
DrawRLESpriteHelper1(IMAGE_TYPE_TRANSPARENT);
}

View File

@ -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, 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, 0);
for (int32_t x = 0; x < 8; x++)
{
@ -74,7 +74,8 @@ void scrolling_text_initialise_bitmaps()
for (int32_t i = 0; i < SPR_G2_GLYPH_COUNT; i++)
{
std::fill_n(drawingSurface, sizeof(drawingSurface), 0x00);
gfx_draw_sprite_software(&dpi, SPR_G2_CHAR_BEGIN + (FONT_SIZE_TINY * SPR_G2_GLYPH_COUNT) + i, -1, 0, 0);
gfx_draw_sprite_software(
&dpi, ImageId::FromUInt32(SPR_G2_CHAR_BEGIN + (FONT_SIZE_TINY * SPR_G2_GLYPH_COUNT) + i), -1, 0, 0);
for (int32_t x = 0; x < 8; x++)
{

View File

@ -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, image, x, y, tertiaryColour);
gfx_draw_sprite_software(_dpi, ImageId::FromUInt32(image), x, y, tertiaryColour);
}
void X8DrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
@ -743,14 +743,12 @@ 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;
image &= 0x7FFFF;
gfx_draw_sprite_palette_set_software(_dpi, image | 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)
{
gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, nullptr);
gfx_draw_sprite_palette_set_software(_dpi, ImageId::FromUInt32(image), x, y, palette, nullptr);
}
void X8DrawingContext::SetDPI(rct_drawpixelinfo* dpi)

View File

@ -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, vehicle_type->base_image_id + i, 0, 0, 0);
gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(vehicle_type->base_image_id + i), 0, 0, 0);
}
int32_t al = -1;
for (int32_t i = 99; i != 0; --i)