Refactor ImageId and use in more functions

This commit is contained in:
Ted John 2021-12-03 18:59:33 +00:00 committed by GitHub
parent 98db974b49
commit 5f9d03e9df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 452 additions and 341 deletions

View File

@ -105,8 +105,8 @@ public:
void FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) override;
void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) override;
void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSpriteRawMasked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
void DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y) override;
void DrawSpriteRawMasked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, ImageId maskImage, ImageId colourImage) override;
void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) override;
void DrawBitmap(
@ -617,12 +617,11 @@ void OpenGLDrawingContext::DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, con
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y)
{
CalculcateClipping(dpi);
int32_t g1Id = image & 0x7FFFF;
auto g1Element = gfx_get_g1_element(g1Id);
auto g1Element = gfx_get_g1_element(imageId);
if (g1Element == nullptr)
{
return;
@ -640,7 +639,7 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, in
zoomedDPI.width = dpi->width >> 1;
zoomedDPI.pitch = dpi->pitch;
zoomedDPI.zoom_level = dpi->zoom_level - 1;
DrawSprite(&zoomedDPI, (image & 0xFFF80000) | (g1Id - g1Element->zoomed_offset), x >> 1, y >> 1, tertiaryColour);
DrawSprite(&zoomedDPI, imageId.WithIndex(imageId.GetIndex() - g1Element->zoomed_offset), x >> 1, y >> 1);
return;
}
if (g1Element->flags & G1_FLAG_NO_ZOOM_DRAW)
@ -702,29 +701,29 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, in
right += _spriteOffset.x;
bottom += _spriteOffset.y;
const auto texture = _textureCache->GetOrLoadImageTexture(image);
const auto texture = _textureCache->GetOrLoadImageTexture(imageId);
int paletteCount;
ivec3 palettes{};
bool special = false;
if (image & IMAGE_TYPE_REMAP_2_PLUS)
if (imageId.HasSecondary())
{
palettes.x = TextureCache::PaletteToY(static_cast<FilterPaletteID>((image >> 19) & 0x1F));
palettes.y = TextureCache::PaletteToY(static_cast<FilterPaletteID>((image >> 24) & 0x1F));
if (image & IMAGE_TYPE_REMAP)
palettes.x = TextureCache::PaletteToY(static_cast<FilterPaletteID>(imageId.GetPrimary()));
palettes.y = TextureCache::PaletteToY(static_cast<FilterPaletteID>(imageId.GetSecondary()));
if (!imageId.HasTertiary())
{
paletteCount = 2;
}
else
{
paletteCount = 3;
palettes.z = TextureCache::PaletteToY(static_cast<FilterPaletteID>(tertiaryColour & 0xFF));
palettes.z = TextureCache::PaletteToY(static_cast<FilterPaletteID>(imageId.GetTertiary()));
}
}
else if ((image & IMAGE_TYPE_REMAP) || (image & IMAGE_TYPE_TRANSPARENT))
else if (imageId.IsRemap() || imageId.IsBlended())
{
paletteCount = 1;
FilterPaletteID palette = static_cast<FilterPaletteID>((image >> 19) & 0xFF);
FilterPaletteID palette = static_cast<FilterPaletteID>(imageId.GetRemap());
palettes.x = TextureCache::PaletteToY(palette);
if (palette == FilterPaletteID::PaletteWater)
{
@ -736,7 +735,7 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, in
paletteCount = 0;
}
if (special || (image & IMAGE_TYPE_TRANSPARENT))
if (special || imageId.IsBlended())
{
DrawRectCommand& command = _commandBuffers.transparent.allocate();
@ -769,12 +768,12 @@ void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, in
}
void OpenGLDrawingContext::DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
rct_drawpixelinfo* dpi, int32_t x, int32_t y, ImageId maskImage, ImageId colourImage)
{
CalculcateClipping(dpi);
auto g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF);
auto g1ElementColour = gfx_get_g1_element(colourImage & 0x7FFFF);
auto g1ElementMask = gfx_get_g1_element(maskImage);
auto g1ElementColour = gfx_get_g1_element(colourImage);
if (g1ElementMask == nullptr || g1ElementColour == nullptr)
{
return;
@ -844,7 +843,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t imag
return;
}
const auto texture = _textureCache->GetOrLoadImageTexture(image);
const auto texture = _textureCache->GetOrLoadImageTexture(ImageId::FromUInt32(image));
int32_t drawOffsetX = g1Element->x_offset;
int32_t drawOffsetY = g1Element->y_offset;
@ -894,7 +893,7 @@ void OpenGLDrawingContext::DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int
return;
}
const auto texture = _textureCache->GetOrLoadGlyphTexture(image, palette);
const auto texture = _textureCache->GetOrLoadGlyphTexture(ImageId::FromUInt32(image), palette);
int32_t left = x + g1Element->x_offset;
int32_t top = y + g1Element->y_offset;

View File

@ -30,7 +30,7 @@ TextureCache::~TextureCache()
FreeTextures();
}
void TextureCache::InvalidateImage(uint32_t image)
void TextureCache::InvalidateImage(ImageIndex image)
{
unique_lock lock(_mutex);
@ -64,17 +64,15 @@ void TextureCache::InvalidateImage(uint32_t image)
}
// Note: for performance reasons, this returns a BasicTextureInfo over an AtlasTextureInfo (also to not expose the cache)
BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image)
BasicTextureInfo TextureCache::GetOrLoadImageTexture(ImageId imageId)
{
uint32_t index;
image &= 0x7FFFFUL;
// Try to read cached texture first.
{
shared_lock lock(_mutex);
index = _indexMap[image];
index = _indexMap[imageId.GetIndex()];
if (index != UNUSED_INDEX)
{
const auto& info = _textureCache[index];
@ -90,18 +88,18 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image)
index = static_cast<uint32_t>(_textureCache.size());
AtlasTextureInfo info = LoadImageTexture(image);
AtlasTextureInfo info = LoadImageTexture(imageId);
_textureCache.push_back(info);
_indexMap[image] = index;
_indexMap[imageId.GetIndex()] = index;
return info;
}
BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap)
BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(ImageId imageId, const PaletteMap& paletteMap)
{
GlyphId glyphId{};
glyphId.Image = image;
glyphId.Image = imageId.GetIndex();
// Try to read cached texture first.
{
@ -128,18 +126,16 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, const Palet
// Load new texture.
unique_lock lock(_mutex);
auto cacheInfo = LoadGlyphTexture(image, paletteMap);
auto cacheInfo = LoadGlyphTexture(imageId, paletteMap);
auto it = _glyphTextureMap.insert(std::make_pair(glyphId, cacheInfo));
return (*it.first).second;
}
BasicTextureInfo TextureCache::GetOrLoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height)
BasicTextureInfo TextureCache::GetOrLoadBitmapTexture(ImageIndex image, const void* pixels, size_t width, size_t height)
{
uint32_t index;
image &= 0x7FFFF;
// Try to read cached texture first.
{
shared_lock lock(_mutex);
@ -270,12 +266,12 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
_atlasesTextureIndices = newIndices;
}
AtlasTextureInfo TextureCache::LoadImageTexture(uint32_t image)
AtlasTextureInfo TextureCache::LoadImageTexture(ImageId imageId)
{
rct_drawpixelinfo dpi = GetImageAsDPI(image, 0);
rct_drawpixelinfo dpi = GetImageAsDPI(ImageId(imageId.GetIndex()));
auto cacheInfo = AllocateImage(dpi.width, dpi.height);
cacheInfo.image = image;
cacheInfo.image = imageId.GetIndex();
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
glTexSubImage3D(
@ -287,12 +283,12 @@ AtlasTextureInfo TextureCache::LoadImageTexture(uint32_t image)
return cacheInfo;
}
AtlasTextureInfo TextureCache::LoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap)
AtlasTextureInfo TextureCache::LoadGlyphTexture(ImageId imageId, const PaletteMap& paletteMap)
{
rct_drawpixelinfo dpi = GetGlyphAsDPI(image, paletteMap);
rct_drawpixelinfo dpi = GetGlyphAsDPI(imageId, paletteMap);
auto cacheInfo = AllocateImage(dpi.width, dpi.height);
cacheInfo.image = image;
cacheInfo.image = imageId.GetIndex();
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
glTexSubImage3D(
@ -304,7 +300,7 @@ AtlasTextureInfo TextureCache::LoadGlyphTexture(uint32_t image, const PaletteMap
return cacheInfo;
}
AtlasTextureInfo TextureCache::LoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height)
AtlasTextureInfo TextureCache::LoadBitmapTexture(ImageIndex image, const void* pixels, size_t width, size_t height)
{
auto cacheInfo = AllocateImage(int32_t(width), int32_t(height));
cacheInfo.image = image;
@ -351,27 +347,27 @@ AtlasTextureInfo TextureCache::AllocateImage(int32_t imageWidth, int32_t imageHe
return _atlases.back().Allocate(imageWidth, imageHeight);
}
rct_drawpixelinfo TextureCache::GetImageAsDPI(uint32_t image, uint32_t tertiaryColour)
rct_drawpixelinfo TextureCache::GetImageAsDPI(ImageId imageId)
{
auto g1Element = gfx_get_g1_element(image & 0x7FFFFUL);
auto g1Element = gfx_get_g1_element(imageId);
int32_t width = g1Element->width;
int32_t height = g1Element->height;
rct_drawpixelinfo dpi = CreateDPI(width, height);
gfx_draw_sprite_software(&dpi, ImageId::FromUInt32(image, tertiaryColour), { -g1Element->x_offset, -g1Element->y_offset });
gfx_draw_sprite_software(&dpi, imageId, { -g1Element->x_offset, -g1Element->y_offset });
return dpi;
}
rct_drawpixelinfo TextureCache::GetGlyphAsDPI(uint32_t image, const PaletteMap& palette)
rct_drawpixelinfo TextureCache::GetGlyphAsDPI(ImageId imageId, const PaletteMap& palette)
{
auto g1Element = gfx_get_g1_element(image & 0x7FFFFUL);
auto g1Element = gfx_get_g1_element(imageId);
int32_t width = g1Element->width;
int32_t height = g1Element->height;
rct_drawpixelinfo dpi = CreateDPI(width, height);
const auto glyphCoords = ScreenCoordsXY{ -g1Element->x_offset, -g1Element->y_offset };
gfx_draw_sprite_palette_set_software(&dpi, ImageId::FromUInt32(image), glyphCoords, palette);
gfx_draw_sprite_palette_set_software(&dpi, imageId, glyphCoords, palette);
return dpi;
}

View File

@ -17,6 +17,7 @@
#include <array>
#include <mutex>
#include <openrct2/common.h>
#include <openrct2/drawing/Drawing.h>
#ifndef __MACOSX__
# include <shared_mutex>
#endif
@ -29,7 +30,7 @@ enum class FilterPaletteID : int32_t;
struct GlyphId
{
uint32_t Image;
ImageIndex Image;
uint64_t Palette;
struct Hash
@ -71,7 +72,7 @@ struct AtlasTextureInfo : public BasicTextureInfo
{
GLuint slot;
ivec4 bounds;
uint32_t image;
ImageIndex image;
};
// Represents a texture atlas that images of a given maximum size can be allocated from
@ -218,10 +219,10 @@ private:
public:
TextureCache();
~TextureCache();
void InvalidateImage(uint32_t image);
BasicTextureInfo GetOrLoadImageTexture(uint32_t image);
BasicTextureInfo GetOrLoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap);
BasicTextureInfo GetOrLoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height);
void InvalidateImage(ImageIndex image);
BasicTextureInfo GetOrLoadImageTexture(ImageId imageId);
BasicTextureInfo GetOrLoadGlyphTexture(ImageId imageId, const PaletteMap& paletteMap);
BasicTextureInfo GetOrLoadBitmapTexture(ImageIndex image, const void* pixels, size_t width, size_t height);
GLuint GetAtlasesTexture();
GLuint GetPaletteTexture();
@ -231,12 +232,12 @@ private:
void CreateTextures();
void GeneratePaletteTexture();
void EnlargeAtlasesTexture(GLuint newEntries);
AtlasTextureInfo LoadImageTexture(uint32_t image);
AtlasTextureInfo LoadGlyphTexture(uint32_t image, const PaletteMap& paletteMap);
AtlasTextureInfo LoadImageTexture(ImageId image);
AtlasTextureInfo LoadGlyphTexture(ImageId image, const PaletteMap& paletteMap);
AtlasTextureInfo AllocateImage(int32_t imageWidth, int32_t imageHeight);
AtlasTextureInfo LoadBitmapTexture(uint32_t image, const void* pixels, size_t width, size_t height);
static rct_drawpixelinfo GetImageAsDPI(uint32_t image, uint32_t tertiaryColour);
static rct_drawpixelinfo GetGlyphAsDPI(uint32_t image, const PaletteMap& paletteMap);
AtlasTextureInfo LoadBitmapTexture(ImageIndex image, const void* pixels, size_t width, size_t height);
static rct_drawpixelinfo GetImageAsDPI(ImageId imageId);
static rct_drawpixelinfo GetGlyphAsDPI(ImageId imageId, const PaletteMap& paletteMap);
void FreeTextures();
static rct_drawpixelinfo CreateDPI(int32_t width, int32_t height);

View File

@ -957,10 +957,8 @@ public:
}
const int32_t ride_tabs[] = {
SPR_TAB_RIDE_16, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_TRANSPORT_0,
SPR_TAB_RIDES_GENTLE_0, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_ROLLER_COASTERS_0,
SPR_TAB_RIDES_THRILL_0, SPR_TAB_RIDES_WATER_0,
SPR_TAB_RIDES_SHOP_0, SPR_TAB_FINANCES_RESEARCH_0,
SPR_TAB_RIDE_16, SPR_TAB_RIDES_TRANSPORT_0, SPR_TAB_RIDES_GENTLE_0, SPR_TAB_RIDES_ROLLER_COASTERS_0,
SPR_TAB_RIDES_THRILL_0, SPR_TAB_RIDES_WATER_0, SPR_TAB_RIDES_SHOP_0, SPR_TAB_FINANCES_RESEARCH_0,
};
const int32_t ThrillRidesTabAnimationSequence[] = {
5, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0,

View File

@ -629,9 +629,9 @@ static void WindowNewRideDrawTabImage(rct_drawpixelinfo* dpi, rct_window* w, int
static void WindowNewRideDrawTabImages(rct_drawpixelinfo* dpi, rct_window* w)
{
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_TRANSPORT, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_TRANSPORT_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_TRANSPORT, SPR_TAB_RIDES_TRANSPORT_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_GENTLE, SPR_TAB_RIDES_GENTLE_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_ROLLER_COASTERS_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER, SPR_TAB_RIDES_ROLLER_COASTERS_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_THRILL, SPR_TAB_RIDES_THRILL_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_WATER, SPR_TAB_RIDES_WATER_0);
WindowNewRideDrawTabImage(dpi, w, WINDOW_NEW_RIDE_PAGE_SHOP, SPR_TAB_RIDES_SHOP_0);
@ -793,6 +793,13 @@ static void WindowNewRidePaint(rct_window* w, rct_drawpixelinfo* dpi)
}
}
static ImageIndex GetRideImage(RideSelection rideSelection)
{
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = static_cast<RideObject*>(objMgr.GetLoadedObject(ObjectType::Ride, rideSelection.EntryIndex));
return obj == nullptr ? ImageIndexUndefined : obj->GetPreviewImage(rideSelection.Type);
}
/**
*
* rct2: 0x006B6ABF
@ -808,7 +815,6 @@ static void WindowNewRideScrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int3
RideSelection* listItem = _windowNewRideListItems;
while (listItem->Type != RIDE_TYPE_NULL || listItem->EntryIndex != OBJECT_ENTRY_INDEX_NULL)
{
rct_ride_entry* rideEntry;
// Draw flat button rectangle
int32_t flags = 0;
if (w->new_ride.SelectedRide == *listItem)
@ -818,18 +824,9 @@ static void WindowNewRideScrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int3
dpi, { coords, coords + ScreenCoordsXY{ 115, 115 } }, w->colours[1], INSET_RECT_FLAG_FILL_MID_LIGHT | flags);
// Draw ride image with feathered border
rideEntry = get_ride_entry(listItem->EntryIndex);
int32_t imageId = rideEntry->images_offset;
for (size_t i = 0; i < RCT2::ObjectLimits::MaxRideTypesPerRideEntry; i++)
{
if (rideEntry->ride_type[i] == listItem->Type)
break;
imageId++;
}
gfx_draw_sprite_raw_masked(dpi, coords + ScreenCoordsXY{ 2, 2 }, SPR_NEW_RIDE_MASK, imageId);
auto mask = ImageId(SPR_NEW_RIDE_MASK);
auto rideImage = ImageId(GetRideImage(*listItem));
gfx_draw_sprite_raw_masked(dpi, coords + ScreenCoordsXY{ 2, 2 }, mask, rideImage);
// Next position
coords.x += 116;

View File

@ -596,11 +596,11 @@ void FASTCALL gfx_sprite_to_buffer(rct_drawpixelinfo& dpi, const DrawSpriteArgs&
* rct2: 0x00681DE2
*/
void FASTCALL gfx_draw_sprite_raw_masked_software(
rct_drawpixelinfo* dpi, const ScreenCoordsXY& scrCoords, int32_t maskImage, int32_t colourImage)
rct_drawpixelinfo* dpi, const ScreenCoordsXY& scrCoords, ImageId maskImage, ImageId colourImage)
{
int32_t left, top, right, bottom, width, height;
auto imgMask = gfx_get_g1_element(maskImage & 0x7FFFF);
auto imgColour = gfx_get_g1_element(colourImage & 0x7FFFF);
auto imgMask = gfx_get_g1_element(maskImage);
auto imgColour = gfx_get_g1_element(colourImage);
if (imgMask == nullptr || imgColour == nullptr)
{
return;
@ -609,7 +609,7 @@ void FASTCALL gfx_draw_sprite_raw_masked_software(
// 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), scrCoords);
gfx_draw_sprite_software(dpi, colourImage, scrCoords);
return;
}
@ -654,12 +654,12 @@ 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)
const rct_g1_element* gfx_get_g1_element(ImageIndex image_id)
{
openrct2_assert(!gOpenRCT2NoGraphics, "gfx_get_g1_element called on headless instance");
auto offset = static_cast<size_t>(image_id);
if (offset == 0x7FFFF)
if (offset == 0x7FFFF || offset == ImageIndexUndefined)
{
return nullptr;
}
@ -718,7 +718,7 @@ const rct_g1_element* gfx_get_g1_element(int32_t image_id)
return nullptr;
}
void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1)
void gfx_set_g1_element(ImageIndex imageId, const rct_g1_element* g1)
{
bool isTemp = imageId == SPR_TEMP;
bool isValid = (imageId >= SPR_IMAGE_LIST_BEGIN && imageId < SPR_IMAGE_LIST_END)
@ -740,7 +740,7 @@ void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1)
{
if (imageId < SPR_RCTC_G1_END)
{
if (imageId < static_cast<int32_t>(_g1.elements.size()))
if (imageId < static_cast<ImageIndex>(_g1.elements.size()))
{
_g1.elements[imageId] = *g1;
}

View File

@ -14,6 +14,7 @@
#include "../interface/ZoomLevel.h"
#include "../world/Location.hpp"
#include "Font.h"
#include "ImageId.hpp"
#include "Text.h"
#include <memory>
@ -201,6 +202,7 @@ enum class FilterPaletteID : int32_t
Palette34 = 34,
Palette44 = 44, // Construction marker
Palette45 = 45, // Decolourise + lighten
Palette46 = 46,
@ -317,188 +319,6 @@ struct rct_size16
int16_t height;
};
enum class ImageCatalogue
{
UNKNOWN,
G1,
G2,
CSG,
OBJECT,
TEMPORARY,
};
/**
* Represents a specific image from a catalogue such as G1, G2, CSG etc. with remap
* colours and flags.
*
* This is currently all stored as a single 32-bit integer, but will allow easy
* extension to 64-bits or higher so that more images can be used.
*/
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_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 = VALUE_UNDEFINED;
uint8_t _tertiary = 0;
public:
static ImageId FromUInt32(uint32_t value)
{
ImageId result;
result._value = value;
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 constexpr ImageId(uint32_t index)
: _value(index & MASK_INDEX)
{
}
constexpr ImageId(uint32_t index, uint8_t primaryColourOrPalette)
: ImageId(ImageId(index).WithPrimary(primaryColourOrPalette))
{
}
constexpr ImageId(uint32_t index, colour_t primaryColour, colour_t secondaryColour)
: ImageId(ImageId(index).WithPrimary(primaryColour).WithSecondary(secondaryColour))
{
}
constexpr 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;
}
bool HasValue() const
{
return GetIndex() != INDEX_UNDEFINED;
}
bool HasPrimary() const
{
return (_value & FLAG_PRIMARY) || (_value & FLAG_SECONDARY);
}
bool HasSecondary() const
{
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;
}
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) >> SHIFT_PRIMARY;
}
colour_t GetSecondary() const
{
return (_value & MASK_SECONDARY) >> SHIFT_SECONDARY;
}
colour_t GetTertiary() const
{
return _tertiary;
}
ImageCatalogue GetCatalogue() const;
constexpr ImageId WithIndex(uint32_t index)
{
ImageId result = *this;
result._value = (_value & ~MASK_INDEX) | (index & MASK_INDEX);
return result;
}
constexpr ImageId WithRemap(uint8_t paletteId)
{
ImageId result = *this;
result._value = (_value & ~MASK_REMAP) | ((paletteId << SHIFT_REMAP) & MASK_REMAP) | FLAG_PRIMARY;
return result;
}
constexpr ImageId WithPrimary(colour_t colour)
{
ImageId result = *this;
result._value = (_value & ~MASK_PRIMARY) | ((colour << SHIFT_PRIMARY) & MASK_PRIMARY) | FLAG_PRIMARY;
return result;
}
constexpr ImageId WithSecondary(colour_t colour)
{
ImageId result = *this;
result._value = (_value & ~MASK_SECONDARY) | ((colour << SHIFT_SECONDARY) & MASK_SECONDARY) | FLAG_SECONDARY;
return result;
}
constexpr 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;
}
};
/**
* Represents an 8-bit indexed map that maps from one palette index to another.
*/
@ -702,8 +522,8 @@ 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);
const rct_g1_element* gfx_get_g1_element(ImageIndex image_id);
void gfx_set_g1_element(ImageIndex imageId, const rct_g1_element* g1);
bool is_csg_loaded();
uint32_t gfx_object_allocate_images(const rct_g1_element* images, uint32_t count);
void gfx_object_free_images(uint32_t baseImageId, uint32_t count);
@ -717,15 +537,14 @@ void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, ImageId image_id, const Sc
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image_id, const ScreenCoordsXY& coords, uint32_t tertiary_colour);
void FASTCALL
gfx_draw_glyph(rct_drawpixelinfo* dpi, int32_t image_id, const ScreenCoordsXY& coords, const PaletteMap& paletteMap);
void FASTCALL
gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, int32_t maskImage, int32_t colourImage);
void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, const ScreenCoordsXY& coords, uint8_t colour);
void FASTCALL
gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, ImageId maskImage, ImageId colourImage);
void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, ImageId imageId, const ScreenCoordsXY& spriteCoords);
void FASTCALL gfx_draw_sprite_palette_set_software(
rct_drawpixelinfo* dpi, ImageId imageId, const ScreenCoordsXY& coords, const PaletteMap& paletteMap);
void FASTCALL gfx_draw_sprite_raw_masked_software(
rct_drawpixelinfo* dpi, const ScreenCoordsXY& scrCoords, int32_t maskImage, int32_t colourImage);
rct_drawpixelinfo* dpi, const ScreenCoordsXY& scrCoords, ImageId maskImage, ImageId colourImage);
// string
void gfx_draw_string(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const_utf8string buffer, TextPaint textPaint = {});

View File

@ -27,9 +27,9 @@ namespace OpenRCT2::Drawing
virtual void FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract;
virtual void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) abstract;
virtual void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) abstract;
virtual void DrawSprite(rct_drawpixelinfo* dpi, ImageId image, int32_t x, int32_t y) abstract;
virtual void DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract;
rct_drawpixelinfo* dpi, int32_t x, int32_t y, ImageId maskImage, ImageId colourImage) abstract;
virtual void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract;
virtual void DrawGlyph(
rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) abstract;

View File

@ -0,0 +1,273 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include <cassert>
#include <cstdint>
#include <limits>
using colour_t = uint8_t;
enum class FilterPaletteID : int32_t;
typedef uint32_t ImageIndex;
static constexpr ImageIndex ImageIndexUndefined = std::numeric_limits<ImageIndex>::max();
enum class ImageCatalogue
{
UNKNOWN,
G1,
G2,
CSG,
OBJECT,
TEMPORARY,
};
/**
* Represents a specific image from a catalogue such as G1, G2, CSG etc. with remap
* colours and flags.
*
* This is currently all stored as a single 32-bit integer, but will allow easy
* extension to 64-bits or higher so that more images can be used.
*/
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_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;
static constexpr uint8_t NEW_FLAG_PRIMARY = 1;
static constexpr uint8_t NEW_FLAG_BLEND = 2;
static constexpr uint8_t NEW_FLAG_SECONDARY = 4;
// clang-format on
// NONE = No remap
// PRIMARY = Remap with palette id (first 32 are colour palettes)
// PRIMARY | SECONDARY = Remap with primary and secondary colours
// SECONDARY = Remap with primary, secondary and tertiary colours
ImageIndex _index = ImageIndexUndefined;
uint8_t _primary = 0;
uint8_t _secondary = 0;
uint8_t _tertiary = 0;
uint8_t _flags = 0;
public:
static ImageId FromUInt32(uint32_t value)
{
ImageId result;
result._index = value & MASK_INDEX;
if (value & FLAG_SECONDARY)
result._primary = (value & MASK_PRIMARY) >> SHIFT_PRIMARY;
else
result._primary = (value & MASK_REMAP) >> SHIFT_REMAP;
if (value & FLAG_SECONDARY)
result._secondary = (value & MASK_SECONDARY) >> SHIFT_SECONDARY;
if (value & FLAG_PRIMARY)
result._flags |= NEW_FLAG_PRIMARY;
if (value & FLAG_BLEND)
result._flags |= NEW_FLAG_BLEND;
if (value & FLAG_SECONDARY)
result._flags |= NEW_FLAG_SECONDARY;
assert(result.ToUInt32() == value);
return result;
}
static ImageId FromUInt32(uint32_t value, uint32_t tertiary)
{
if (!(value & FLAG_PRIMARY) && (value & FLAG_SECONDARY))
{
auto result = ImageId::FromUInt32(value).WithTertiary(tertiary);
assert(result.ToUInt32() == value);
return result;
}
else
{
return ImageId::FromUInt32(value);
}
}
ImageId() = default;
explicit constexpr ImageId(ImageIndex index)
: _index(index)
{
}
constexpr ImageId(uint32_t index, uint8_t primaryColourOrPalette)
: ImageId(ImageId(index).WithPrimary(primaryColourOrPalette))
{
}
constexpr ImageId(uint32_t index, colour_t primaryColour, colour_t secondaryColour)
: ImageId(ImageId(index).WithPrimary(primaryColour).WithSecondary(secondaryColour))
{
}
constexpr 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
{
auto result = (_index & MASK_INDEX);
result |= (_primary << SHIFT_REMAP) & MASK_REMAP;
if (_flags & NEW_FLAG_PRIMARY)
result |= FLAG_PRIMARY;
if (_flags & NEW_FLAG_SECONDARY)
{
result |= (_secondary << SHIFT_SECONDARY) & MASK_SECONDARY;
result |= FLAG_SECONDARY;
}
if (_flags & NEW_FLAG_BLEND)
result |= FLAG_BLEND;
return result;
}
bool HasValue() const
{
return GetIndex() != INDEX_UNDEFINED;
}
bool HasPrimary() const
{
return (_flags & NEW_FLAG_PRIMARY) || (_flags & NEW_FLAG_SECONDARY);
}
bool HasSecondary() const
{
return _flags & NEW_FLAG_SECONDARY;
}
bool HasTertiary() const
{
return !(_flags & NEW_FLAG_PRIMARY) && (_flags & NEW_FLAG_SECONDARY);
}
bool IsRemap() const
{
return (_flags & NEW_FLAG_PRIMARY) && !(_flags & NEW_FLAG_SECONDARY);
}
bool IsBlended() const
{
return _flags & NEW_FLAG_BLEND;
}
ImageIndex GetIndex() const
{
return _index;
}
uint8_t GetRemap() const
{
return _primary;
}
colour_t GetPrimary() const
{
return _primary;
}
colour_t GetSecondary() const
{
return _secondary;
}
colour_t GetTertiary() const
{
return _tertiary;
}
ImageCatalogue GetCatalogue() const;
constexpr ImageId WithIndex(ImageIndex index) const
{
ImageId result = *this;
result._index = index;
return result;
}
constexpr ImageId WithIndexOffset(ImageIndex offset) const
{
ImageId result = *this;
result._index += offset;
return result;
}
constexpr ImageId WithRemap(FilterPaletteID paletteId) const
{
return WithRemap(static_cast<uint8_t>(paletteId));
}
constexpr ImageId WithRemap(uint8_t paletteId) const
{
ImageId result = *this;
result._primary = paletteId;
result._secondary = 0;
result._tertiary = 0;
result._flags |= NEW_FLAG_PRIMARY;
result._flags &= ~NEW_FLAG_SECONDARY;
return result;
}
constexpr ImageId WithPrimary(colour_t colour) const
{
ImageId result = *this;
result._primary = colour;
result._flags |= NEW_FLAG_PRIMARY;
return result;
}
constexpr ImageId WithSecondary(colour_t colour) const
{
ImageId result = *this;
result._secondary = colour;
result._flags |= NEW_FLAG_SECONDARY;
return result;
}
constexpr ImageId WithTertiary(colour_t tertiary) const
{
ImageId result = *this;
result._tertiary = tertiary;
result._flags &= ~NEW_FLAG_PRIMARY;
result._flags |= NEW_FLAG_SECONDARY;
if (!(_flags & NEW_FLAG_SECONDARY))
{
// Tertiary implies primary and secondary, so if colour was remap (8-bit primary) then
// we need to zero the secondary colour.
result._secondary = 0;
}
return result;
}
constexpr ImageId WithBlended(bool value) const
{
ImageId result = *this;
if (value)
result._flags |= NEW_FLAG_BLEND;
else
result._flags &= ~NEW_FLAG_BLEND;
return result;
}
};
static_assert(sizeof(ImageId) == 8);

View File

@ -233,18 +233,18 @@ void gfx_draw_dashed_line(
}
}
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, ImageId image_id, const ScreenCoordsXY& coords)
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, const ScreenCoordsXY& coords, uint32_t tertiary_colour)
{
gfx_draw_sprite(dpi, image_id.ToUInt32(), coords, image_id.GetTertiary());
gfx_draw_sprite(dpi, ImageId::FromUInt32(image, tertiary_colour), coords);
}
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, const ScreenCoordsXY& coords, uint32_t tertiary_colour)
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, ImageId imageId, const ScreenCoordsXY& coords)
{
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawSprite(dpi, image, coords.x, coords.y, tertiary_colour);
dc->DrawSprite(dpi, imageId, coords.x, coords.y);
}
}
@ -259,7 +259,7 @@ void FASTCALL gfx_draw_glyph(rct_drawpixelinfo* dpi, int32_t image, const Screen
}
void FASTCALL
gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, int32_t maskImage, int32_t colourImage)
gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, ImageId maskImage, ImageId colourImage)
{
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)

View File

@ -718,13 +718,12 @@ void X8DrawingContext::DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const S
gfx_draw_line_software(dpi, line, colour);
}
void X8DrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
void X8DrawingContext::DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y)
{
gfx_draw_sprite_software(dpi, ImageId::FromUInt32(image, tertiaryColour), { x, y });
gfx_draw_sprite_software(dpi, imageId, { x, y });
}
void X8DrawingContext::DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
void X8DrawingContext::DrawSpriteRawMasked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, ImageId maskImage, ImageId colourImage)
{
gfx_draw_sprite_raw_masked_software(dpi, { x, y }, maskImage, colourImage);
}

View File

@ -145,9 +145,9 @@ namespace OpenRCT2
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right,
int32_t bottom) override;
void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) override;
void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSprite(rct_drawpixelinfo* dpi, ImageId imageId, int32_t x, int32_t y) override;
void DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
rct_drawpixelinfo* dpi, int32_t x, int32_t y, ImageId maskImage, ImageId colourImage) override;
void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
void DrawBitmap(

View File

@ -79,6 +79,7 @@ enum : uint8_t
PALETTE_INDEX_21 = 21, // Dark grey (11), White (lighter-11)
PALETTE_INDEX_40 = 40, //
PALETTE_INDEX_42 = 42, // Light Brown (lighter), Saturated brown (11)
PALETTE_INDEX_44 = 44, // Construction marker
PALETTE_INDEX_46 = 46, // Tertiary remap 0 / Yellow (darkest)
PALETTE_INDEX_47 = 47, // Tertiary remap 1 / Yellow
PALETTE_INDEX_48 = 48, // Tertiary remap 2 / Yellow

View File

@ -405,6 +405,17 @@ std::string RideObject::GetCapacity() const
return GetString(ObjectStringID::CAPACITY);
}
ImageIndex RideObject::GetPreviewImage(ride_type_t type)
{
auto it = std::find(std::begin(_legacyType.ride_type), std::end(_legacyType.ride_type), type);
if (it == std::end(_legacyType.ride_type))
{
return ImageIndexUndefined;
}
return _legacyType.images_offset + std::distance(std::begin(_legacyType.ride_type), it);
}
void RideObject::SetRepositoryItem(ObjectRepositoryItem* item) const
{
// Find the first non-null ride type, to be used when checking the ride group and determining the category.

View File

@ -10,7 +10,9 @@
#pragma once
#include "../core/IStream.hpp"
#include "../drawing/ImageId.hpp"
#include "../ride/RideEntry.h"
#include "../ride/RideTypes.h"
#include "Object.h"
#include <vector>
@ -38,6 +40,7 @@ public:
std::string GetDescription() const;
std::string GetCapacity() const;
ImageIndex GetPreviewImage(ride_type_t type);
void SetRepositoryItem(ObjectRepositoryItem* item) const override;

View File

@ -53,9 +53,9 @@ bool gPaintBoundingBoxes;
bool gPaintBlockedTiles;
static void PaintAttachedPS(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t viewFlags);
static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int32_t x, int32_t y);
static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int32_t x, int32_t y);
static uint32_t PaintPSColourifyImage(uint32_t imageId, ViewportInteractionItem spriteType, uint32_t viewFlags);
static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y);
static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y);
static ImageId PaintPSColourifyImage(ImageId imageId, ViewportInteractionItem spriteType, uint32_t viewFlags);
static int32_t RemapPositionToQuadrant(const paint_struct& ps, uint8_t rotation)
{
@ -147,10 +147,10 @@ static constexpr CoordsXYZ RotateBoundBoxSize(const CoordsXYZ& bbSize, const uin
* Extracted from 0x0098196c, 0x0098197c, 0x0098198c, 0x0098199c
*/
static paint_struct* CreateNormalPaintStruct(
paint_session* session, const uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset)
{
auto* const g1 = gfx_get_g1_element(image_id & 0x7FFFF);
auto* const g1 = gfx_get_g1_element(image_id);
if (g1 == nullptr)
{
return nullptr;
@ -176,7 +176,7 @@ static paint_struct* CreateNormalPaintStruct(
return nullptr;
}
ps->image_id = image_id;
ps->image_id = image_id.ToUInt32();
ps->x = imagePos.x;
ps->y = imagePos.y;
ps->bounds.x_end = rotBoundBoxSize.x + rotBoundBoxOffset.x + session->SpritePosition.x;
@ -501,7 +501,8 @@ static void PaintDrawStruct(paint_session* session, paint_struct* ps)
}
}
uint32_t imageId = PaintPSColourifyImage(ps->image_id, ps->sprite_type, session->ViewFlags);
auto imageId = PaintPSColourifyImage(
ImageId::FromUInt32(ps->image_id, ps->tertiary_colour), ps->sprite_type, session->ViewFlags);
if (gPaintBoundingBoxes && dpi->zoom_level == ZoomLevel{ 0 })
{
PaintPSImageWithBoundingBoxes(dpi, ps, imageId, x, y);
@ -549,19 +550,20 @@ static void PaintAttachedPS(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t v
{
auto screenCoords = ScreenCoordsXY{ attached_ps->x + ps->x, attached_ps->y + ps->y };
uint32_t imageId = PaintPSColourifyImage(attached_ps->image_id, ps->sprite_type, viewFlags);
auto imageId = PaintPSColourifyImage(
ImageId::FromUInt32(attached_ps->image_id, ps->tertiary_colour), ps->sprite_type, viewFlags);
if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED)
{
gfx_draw_sprite_raw_masked(dpi, screenCoords, imageId, attached_ps->colour_image_id);
gfx_draw_sprite_raw_masked(dpi, screenCoords, imageId, ImageId::FromUInt32(attached_ps->colour_image_id));
}
else
{
gfx_draw_sprite(dpi, imageId, screenCoords, ps->tertiary_colour);
gfx_draw_sprite(dpi, imageId, screenCoords);
}
}
}
static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int32_t x, int32_t y)
static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y)
{
const uint8_t colour = BoundBoxDebugColours[EnumValue(ps->sprite_type)];
const uint8_t rotation = get_current_rotation();
@ -647,36 +649,31 @@ static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct*
gfx_draw_line(dpi, { screenCoordFrontTop, screenCoordRightTop }, colour);
}
static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int32_t x, int32_t y)
static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y)
{
if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED)
{
return gfx_draw_sprite_raw_masked(dpi, { x, y }, imageId, ps->colour_image_id);
return gfx_draw_sprite_raw_masked(dpi, { x, y }, imageId, ImageId::FromUInt32(ps->colour_image_id));
}
gfx_draw_sprite(dpi, imageId, { x, y }, ps->tertiary_colour);
gfx_draw_sprite(dpi, imageId, { x, y });
}
static uint32_t PaintPSColourifyImage(uint32_t imageId, ViewportInteractionItem spriteType, uint32_t viewFlags)
static ImageId PaintPSColourifyImage(ImageId imageId, ViewportInteractionItem spriteType, uint32_t viewFlags)
{
constexpr uint32_t primaryColour = COLOUR_BRIGHT_YELLOW;
constexpr uint32_t secondaryColour = COLOUR_GREY;
constexpr uint32_t seeThoughFlags = IMAGE_TYPE_TRANSPARENT | (primaryColour << 19) | (secondaryColour << 24);
auto seeThrough = imageId.WithPrimary(COLOUR_BRIGHT_YELLOW).WithSecondary(COLOUR_GREY).WithBlended(true);
if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES)
{
if (spriteType == ViewportInteractionItem::Ride)
{
imageId &= 0x7FFFF;
imageId |= seeThoughFlags;
return seeThrough;
}
}
if (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)
{
if (spriteType == ViewportInteractionItem::Wall)
{
imageId &= 0x7FFFF;
imageId |= seeThoughFlags;
return seeThrough;
}
}
if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS)
@ -686,9 +683,7 @@ static uint32_t PaintPSColourifyImage(uint32_t imageId, ViewportInteractionItem
case ViewportInteractionItem::Footpath:
case ViewportInteractionItem::FootpathItem:
case ViewportInteractionItem::Banner:
imageId &= 0x7FFFF;
imageId |= seeThoughFlags;
break;
return seeThrough;
default:
break;
}
@ -700,9 +695,7 @@ static uint32_t PaintPSColourifyImage(uint32_t imageId, ViewportInteractionItem
case ViewportInteractionItem::Scenery:
case ViewportInteractionItem::LargeScenery:
case ViewportInteractionItem::Wall:
imageId &= 0x7FFFF;
imageId |= seeThoughFlags;
break;
return seeThrough;
default:
break;
}
@ -735,7 +728,20 @@ void PaintSessionFree([[maybe_unused]] paint_session* session)
paint_struct* PaintAddImageAsParent(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize)
{
return PaintAddImageAsParent(session, image_id, offset, boundBoxSize, offset);
return PaintAddImageAsParent(session, ImageId::FromUInt32(image_id), offset, boundBoxSize, offset);
}
paint_struct* PaintAddImageAsParent(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset)
{
return PaintAddImageAsParent(session, ImageId::FromUInt32(image_id), offset, boundBoxSize, boundBoxOffset);
}
paint_struct* PaintAddImageAsParent(
paint_session* session, ImageId imageId, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize)
{
return PaintAddImageAsParent(session, imageId, offset, boundBoxSize, offset);
}
/**
@ -755,7 +761,7 @@ paint_struct* PaintAddImageAsParent(
*/
// Track Pieces, Shops.
paint_struct* PaintAddImageAsParent(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset)
{
session->LastPS = nullptr;
@ -790,24 +796,19 @@ paint_struct* PaintAddImageAsParent(
* Creates a paint struct but does not allocate to a paint quadrant. Result cannot be ignored!
*/
[[nodiscard]] paint_struct* PaintAddImageAsOrphan(
paint_session* session, uint32_t image_id, int32_t x_offset, int32_t y_offset, int32_t bound_box_length_x,
int32_t bound_box_length_y, int32_t bound_box_length_z, int32_t z_offset, int32_t bound_box_offset_x,
int32_t bound_box_offset_y, int32_t bound_box_offset_z)
paint_session* session, ImageId imageId, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset)
{
session->LastPS = nullptr;
session->LastAttachedPS = nullptr;
return CreateNormalPaintStruct(session, imageId, offset, boundBoxSize, boundBoxOffset);
}
CoordsXYZ offset = { x_offset, y_offset, z_offset };
CoordsXYZ boundBoxSize = { bound_box_length_x, bound_box_length_y, bound_box_length_z };
CoordsXYZ boundBoxOffset = { bound_box_offset_x, bound_box_offset_y, bound_box_offset_z };
auto* ps = CreateNormalPaintStruct(session, image_id, offset, boundBoxSize, boundBoxOffset);
if (ps == nullptr)
{
return nullptr;
}
return ps;
paint_struct* PaintAddImageAsChild(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxLength,
const CoordsXYZ& boundBoxOffset)
{
return PaintAddImageAsChild(session, ImageId::FromUInt32(image_id), offset, boundBoxLength, boundBoxOffset);
}
/**
@ -828,7 +829,7 @@ paint_struct* PaintAddImageAsParent(
* If there is no parent paint struct then image is added as a parent
*/
paint_struct* PaintAddImageAsChild(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxLength,
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxLength,
const CoordsXYZ& boundBoxOffset)
{
paint_struct* parentPS = session->LastPS;
@ -900,6 +901,11 @@ bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int3
* @return (!CF) success
*/
bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int32_t x, int32_t y)
{
return PaintAttachToPreviousPS(session, ImageId::FromUInt32(image_id), x, y);
}
bool PaintAttachToPreviousPS(paint_session* session, ImageId image_id, int32_t x, int32_t y)
{
auto* masterPs = session->LastPS;
if (masterPs == nullptr)
@ -913,7 +919,7 @@ bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int32_t
return false;
}
ps->image_id = image_id;
ps->image_id = image_id.ToUInt32();
ps->x = x;
ps->y = y;
ps->flags = 0;

View File

@ -289,10 +289,14 @@ paint_struct* PaintAddImageAsParent(
paint_struct* PaintAddImageAsParent(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset);
paint_struct* PaintAddImageAsParent(
paint_session* session, ImageId imageId, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize);
paint_struct* PaintAddImageAsParent(
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset);
[[nodiscard]] paint_struct* PaintAddImageAsOrphan(
paint_session* session, uint32_t image_id, int32_t x_offset, int32_t y_offset, int32_t bound_box_length_x,
int32_t bound_box_length_y, int32_t bound_box_length_z, int32_t z_offset, int32_t bound_box_offset_x,
int32_t bound_box_offset_y, int32_t bound_box_offset_z);
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset);
paint_struct* PaintAddImageAsChild(
paint_session* session, uint32_t image_id, int32_t x_offset, int32_t y_offset, int32_t bound_box_length_x,
int32_t bound_box_length_y, int32_t bound_box_length_z, int32_t z_offset, int32_t bound_box_offset_x,
@ -300,6 +304,9 @@ paint_struct* PaintAddImageAsChild(
paint_struct* PaintAddImageAsChild(
paint_session* session, uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxLength,
const CoordsXYZ& boundBoxOffset);
paint_struct* PaintAddImageAsChild(
paint_session* session, ImageId image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxLength,
const CoordsXYZ& boundBoxOffset);
paint_struct* PaintAddImageAsParentRotated(
paint_session* session, uint8_t direction, uint32_t image_id, int32_t x_offset, int32_t y_offset,
@ -325,6 +332,7 @@ paint_struct* PaintAddImageAsParentRotated(
void paint_util_push_tunnel_rotated(paint_session* session, uint8_t direction, uint16_t height, uint8_t type);
bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int32_t x, int32_t y);
bool PaintAttachToPreviousPS(paint_session* session, ImageId image_id, int32_t x, int32_t y);
bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int32_t x, int32_t y);
void PaintFloatingMoneyEffect(
paint_session* session, money64 amount, rct_string_id string_id, int32_t y, int32_t z, int8_t y_offsets[], int32_t offset_x,

View File

@ -595,8 +595,8 @@ bool wooden_a_supports_paint_setup(
{
hasSupports = true;
paint_struct* ps = PaintAddImageAsOrphan(
session, imageId, 0, 0, bBox.length.x, bBox.length.y, bBox.length.z, z, bBox.offset.x, bBox.offset.y,
bBox.offset.z + z);
session, ImageId::FromUInt32(imageId), { 0, 0, z }, bBox.length,
{ bBox.offset.x, bBox.offset.y, bBox.offset.z + z });
if (ps != nullptr)
{
session->WoodenSupportsPrependTo->children = ps;
@ -770,8 +770,8 @@ bool wooden_b_supports_paint_setup(
else
{
paint_struct* paintStruct = PaintAddImageAsOrphan(
session, imageId | imageColourFlags, 0, 0, boundBox.length.x, boundBox.length.y, boundBox.length.z,
baseHeight, boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight);
session, ImageId::FromUInt32(imageId | imageColourFlags), { 0, 0, baseHeight }, boundBox.length,
{ boundBox.offset.x, boundBox.offset.y, boundBox.offset.z + baseHeight });
_9E32B1 = true;
if (paintStruct != nullptr)
{
@ -1292,8 +1292,8 @@ bool path_a_supports_paint_setup(
else
{
paint_struct* paintStruct = PaintAddImageAsOrphan(
session, imageId | imageColourFlags, 0, 0, boundBox.length.y, boundBox.length.x, boundBox.length.z, baseHeight,
boundBox.offset.x, boundBox.offset.y, baseHeight + boundBox.offset.z);
session, ImageId::FromUInt32(imageId | imageColourFlags), { 0, 0, baseHeight }, boundBox.length,
{ boundBox.offset.x, boundBox.offset.y, baseHeight + boundBox.offset.z });
hasSupports = true;
if (paintStruct != nullptr)
{