From 0e1517be4f766f2b0dba05ca307280cdf496b80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:48:31 +0200 Subject: [PATCH 1/5] Move GamePalette into ColourPalette.h, use namespace for it also --- .../drawing/engines/opengl/TextureCache.cpp | 3 +- src/openrct2/CommandLineSprite.cpp | 2 +- src/openrct2/core/Imaging.cpp | 2 +- src/openrct2/core/Imaging.h | 3 +- src/openrct2/drawing/ColourPalette.h | 21 +++++++++ src/openrct2/drawing/Drawing.cpp | 4 +- src/openrct2/drawing/Drawing.h | 46 ++----------------- src/openrct2/drawing/IDrawingEngine.h | 2 +- src/openrct2/drawing/ImageImporter.cpp | 4 +- src/openrct2/drawing/ImageImporter.h | 2 +- src/openrct2/drawing/LightFX.cpp | 1 + src/openrct2/drawing/LightFX.h | 5 +- src/openrct2/drawing/NewDrawing.h | 5 +- src/openrct2/interface/Colour.cpp | 6 ++- src/openrct2/interface/Screenshot.cpp | 2 +- src/openrct2/libopenrct2.vcxproj | 1 + 16 files changed, 50 insertions(+), 59 deletions(-) create mode 100644 src/openrct2/drawing/ColourPalette.h diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 57c220001b..2fb3f82887 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -21,6 +21,7 @@ #include using namespace OpenRCT2::Ui; +using namespace OpenRCT2::Drawing; constexpr uint32_t kUnusedIndex = 0xFFFFFFFF; @@ -206,7 +207,7 @@ void TextureCache::CreateTextures() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D( - GL_TEXTURE_2D, 0, GL_R8UI, PALETTE_SIZE, PALETTE_SIZE, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, blendArray); + GL_TEXTURE_2D, 0, GL_R8UI, kGamePaletteSize, kGamePaletteSize, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, blendArray); } _initialized = true; diff --git a/src/openrct2/CommandLineSprite.cpp b/src/openrct2/CommandLineSprite.cpp index 233e21b883..d65583e0ef 100644 --- a/src/openrct2/CommandLineSprite.cpp +++ b/src/openrct2/CommandLineSprite.cpp @@ -214,7 +214,7 @@ static bool SpriteImageExport(const G1Element& spriteElement, u8string_view outP image.Height = dpi.height; image.Depth = 8; image.Stride = dpi.LineStride(); - image.Palette = std::make_unique(StandardPalette); + image.Palette = StandardPalette; image.Pixels = std::vector(pixels8, pixels8 + pixelsLen); Imaging::WriteToFile(outPath, image, IMAGE_FORMAT::PNG); return true; diff --git a/src/openrct2/core/Imaging.cpp b/src/openrct2/core/Imaging.cpp index 4b2b5f0df6..363a6baac3 100644 --- a/src/openrct2/core/Imaging.cpp +++ b/src/openrct2/core/Imaging.cpp @@ -189,7 +189,7 @@ namespace OpenRCT2::Imaging if (image.Depth == 8) { - if (image.Palette == nullptr) + if (!image.Palette.has_value()) { throw std::runtime_error("Expected a palette for 8-bit image."); } diff --git a/src/openrct2/core/Imaging.h b/src/openrct2/core/Imaging.h index 854c7698c9..6515bcda01 100644 --- a/src/openrct2/core/Imaging.h +++ b/src/openrct2/core/Imaging.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ struct Image // Data std::vector Pixels; - std::unique_ptr Palette; + std::optional Palette; uint32_t Stride{}; }; diff --git a/src/openrct2/drawing/ColourPalette.h b/src/openrct2/drawing/ColourPalette.h new file mode 100644 index 0000000000..ee15a1b63c --- /dev/null +++ b/src/openrct2/drawing/ColourPalette.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace OpenRCT2::Drawing +{ + + struct PaletteBGRA + { + uint8_t Blue{}; + uint8_t Green{}; + uint8_t Red{}; + uint8_t Alpha{}; + }; + + constexpr auto kGamePaletteSize = 256u; + + using GamePalette = std::array; + +} // namespace OpenRCT2::Drawing diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index f59f4946dc..6aea394594 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -95,7 +95,7 @@ void PaletteMap::Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, s std::memcpy(&_data[dstIndex], &src._data[srcIndex], copyLength); } -GamePalette gPalette; +OpenRCT2::Drawing::GamePalette gPalette; uint8_t gGamePalette[256 * 4]; uint32_t gPaletteEffectFrame; @@ -1161,4 +1161,4 @@ void DebugDPI(DrawPixelInfo& dpi) const auto str2 = std::to_string(dpi.y); DrawText(dpi, ScreenCoordsXY{ dpi.x, dpi.y + 6 }, { COLOUR_WHITE, FontStyle::Tiny }, str2.c_str()); -} \ No newline at end of file +} diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 5a69037d41..530c876520 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -14,10 +14,12 @@ #include "../interface/Colour.h" #include "../interface/ZoomLevel.h" #include "../world/Location.hpp" +#include "ColourPalette.h" #include "Font.h" #include "ImageId.hpp" #include "Text.h" +#include #include #include #include @@ -26,6 +28,7 @@ struct ScreenCoordsXY; struct ScreenLine; struct ScreenRect; + namespace OpenRCT2 { struct IPlatformEnvironment; @@ -37,47 +40,6 @@ namespace OpenRCT2::Drawing struct IDrawingEngine; } -struct PaletteBGRA -{ - uint8_t Blue{}; - uint8_t Green{}; - uint8_t Red{}; - uint8_t Alpha{}; -}; - -constexpr auto PALETTE_SIZE = 256u; - -struct GamePalette -{ - PaletteBGRA Colour[PALETTE_SIZE]{}; - - PaletteBGRA& operator[](size_t idx) - { - assert(idx < PALETTE_SIZE); - if (idx >= PALETTE_SIZE) - { - static PaletteBGRA dummy; - return dummy; - } - - return Colour[idx]; - } - - const PaletteBGRA operator[](size_t idx) const - { - assert(idx < PALETTE_SIZE); - if (idx >= PALETTE_SIZE) - return {}; - - return Colour[idx]; - } - - explicit operator uint8_t*() - { - return reinterpret_cast(Colour); - } -}; - struct G1Element { uint8_t* offset = nullptr; // 0x00 @@ -528,7 +490,7 @@ constexpr uint8_t kPaletteTotalOffsets = 192; constexpr int8_t kMaxScrollingTextModes = 38; -extern GamePalette gPalette; +extern OpenRCT2::Drawing::GamePalette gPalette; extern uint8_t gGamePalette[256 * 4]; extern uint32_t gPaletteEffectFrame; diff --git a/src/openrct2/drawing/IDrawingEngine.h b/src/openrct2/drawing/IDrawingEngine.h index 3f8751af56..20d8d0d288 100644 --- a/src/openrct2/drawing/IDrawingEngine.h +++ b/src/openrct2/drawing/IDrawingEngine.h @@ -10,6 +10,7 @@ #pragma once #include "./Weather.h" +#include "ColourPalette.h" #include #include @@ -39,7 +40,6 @@ enum DRAWING_ENGINE_FLAGS }; struct DrawPixelInfo; -struct GamePalette; namespace OpenRCT2::Ui { diff --git a/src/openrct2/drawing/ImageImporter.cpp b/src/openrct2/drawing/ImageImporter.cpp index e4573630e3..a71fbeefa3 100644 --- a/src/openrct2/drawing/ImageImporter.cpp +++ b/src/openrct2/drawing/ImageImporter.cpp @@ -306,7 +306,7 @@ namespace OpenRCT2::Drawing { if (!IsTransparentPixel(colour)) { - for (uint32_t i = 0; i < PALETTE_SIZE; i++) + for (uint32_t i = 0; i < kGamePaletteSize; i++) { if (static_cast(palette[i].Red) == colour[0] && static_cast(palette[i].Green) == colour[1] && static_cast(palette[i].Blue) == colour[2]) @@ -364,7 +364,7 @@ namespace OpenRCT2::Drawing { auto smallestError = static_cast(-1); auto bestMatch = PALETTE_TRANSPARENT; - for (uint32_t x = 0; x < PALETTE_SIZE; x++) + for (uint32_t x = 0; x < kGamePaletteSize; x++) { if (IsChangablePixel(x)) { diff --git a/src/openrct2/drawing/ImageImporter.h b/src/openrct2/drawing/ImageImporter.h index 20fefbb07c..b57ca39120 100644 --- a/src/openrct2/drawing/ImageImporter.h +++ b/src/openrct2/drawing/ImageImporter.h @@ -93,7 +93,7 @@ namespace OpenRCT2::Drawing ImageImportMeta createImageImportMetaFromJson(json_t& input); } // namespace OpenRCT2::Drawing -constexpr GamePalette StandardPalette = { { +constexpr OpenRCT2::Drawing::GamePalette StandardPalette = { { // 0 (Unused/Transparent) { 0, 0, 0, 255 }, diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index b1ee8e3cac..ae5fe1d6de 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -29,6 +29,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; static uint8_t _bakedLightTexture_lantern_0[32 * 32]; static uint8_t _bakedLightTexture_lantern_1[64 * 64]; diff --git a/src/openrct2/drawing/LightFX.h b/src/openrct2/drawing/LightFX.h index 1c869f59ff..1d42ff4729 100644 --- a/src/openrct2/drawing/LightFX.h +++ b/src/openrct2/drawing/LightFX.h @@ -9,12 +9,13 @@ #pragma once +#include "ColourPalette.h" + #include struct CoordsXY; struct Vehicle; struct DrawPixelInfo; -struct GamePalette; struct CoordsXYZ; struct EntityBase; @@ -56,7 +57,7 @@ void LightFXRenderLightsToFrontBuffer(); void LightFXUpdateViewportSettings(); void* LightFXGetFrontBuffer(); -const GamePalette& LightFXGetPalette(); +const OpenRCT2::Drawing::GamePalette& LightFXGetPalette(); void LightFXAdd3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType); diff --git a/src/openrct2/drawing/NewDrawing.h b/src/openrct2/drawing/NewDrawing.h index cd71c7b3bf..4b693f3ef0 100644 --- a/src/openrct2/drawing/NewDrawing.h +++ b/src/openrct2/drawing/NewDrawing.h @@ -10,9 +10,10 @@ #pragma once #include "../localisation/StringIdType.h" +#include "ColourPalette.h" struct DrawPixelInfo; -struct GamePalette; +struct PaletteBGRA; enum class DrawingEngine : int32_t; extern StringId DrawingEngineStringIds[3]; @@ -21,7 +22,7 @@ DrawingEngine drawing_engine_get_type(); bool DrawingEngineRequiresNewWindow(DrawingEngine srcEngine, DrawingEngine dstEngine); void DrawingEngineInit(); void DrawingEngineResize(); -void DrawingEngineSetPalette(const GamePalette& colours); +void DrawingEngineSetPalette(const OpenRCT2::Drawing::GamePalette& colours); void DrawingEngineCopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy); void DrawingEngineDispose(); diff --git a/src/openrct2/interface/Colour.cpp b/src/openrct2/interface/Colour.cpp index 2060010cba..0c6e9ec027 100644 --- a/src/openrct2/interface/Colour.cpp +++ b/src/openrct2/interface/Colour.cpp @@ -16,6 +16,8 @@ #include +using namespace OpenRCT2::Drawing; + ColourShadeMap ColourMapA[COLOUR_COUNT] = {}; static constexpr uint8_t kLegacyColourMaskBase = 0x1F; @@ -169,9 +171,9 @@ static uint8_t FindClosestPaletteIndex(uint8_t red, uint8_t green, uint8_t blue) static void InitBlendColourMap() { - for (size_t i = 0; i < PALETTE_SIZE; i++) + for (size_t i = 0; i < kGamePaletteSize; i++) { - for (size_t j = i; j < PALETTE_SIZE; j++) + for (size_t j = i; j < kGamePaletteSize; j++) { uint8_t red = (gPalette[i].Red + gPalette[j].Red) / 2; uint8_t green = (gPalette[i].Green + gPalette[j].Green) / 2; diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index da464d4079..583f6d007c 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -63,7 +63,7 @@ static bool WriteDpiToFile(std::string_view path, const DrawPixelInfo& dpi, cons image.Height = dpi.height; image.Depth = 8; image.Stride = dpi.LineStride(); - image.Palette = std::make_unique(palette); + image.Palette = palette; image.Pixels = std::vector(pixels8, pixels8 + pixelsLen); Imaging::WriteToFile(path, image, IMAGE_FORMAT::PNG); return true; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 86d0c493c7..d45b938b9d 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -237,6 +237,7 @@ + From 6cb6e0a621c4fcb5be1892ed59935500d8cc2855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:27:47 +0200 Subject: [PATCH 2/5] Remove wrong forward declaration --- src/openrct2/drawing/NewDrawing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/drawing/NewDrawing.h b/src/openrct2/drawing/NewDrawing.h index 4b693f3ef0..0e1c9dc760 100644 --- a/src/openrct2/drawing/NewDrawing.h +++ b/src/openrct2/drawing/NewDrawing.h @@ -13,7 +13,7 @@ #include "ColourPalette.h" struct DrawPixelInfo; -struct PaletteBGRA; + enum class DrawingEngine : int32_t; extern StringId DrawingEngineStringIds[3]; From c23071f67feafb5d590835dc0169abeb07f53ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:38:00 +0200 Subject: [PATCH 3/5] Use GamePalette instead of raw byte array --- src/openrct2/drawing/Drawing.cpp | 94 ++++++++++++++++---------------- src/openrct2/drawing/Drawing.h | 5 +- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 6aea394594..6b5d31ccdc 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -96,7 +96,7 @@ void PaletteMap::Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, s } OpenRCT2::Drawing::GamePalette gPalette; -uint8_t gGamePalette[256 * 4]; +OpenRCT2::Drawing::GamePalette gGamePalette; uint32_t gPaletteEffectFrame; ImageId gPickupPeepImage; @@ -717,16 +717,17 @@ void GfxTransposePalette(int32_t pal, uint8_t product) { int32_t width = g1->width; int32_t x = g1->x_offset; - uint8_t* dest_pointer = &gGamePalette[x * 4]; uint8_t* source_pointer = g1->offset; for (; width > 0; width--) { - dest_pointer[0] = (source_pointer[0] * product) >> 8; - dest_pointer[1] = (source_pointer[1] * product) >> 8; - dest_pointer[2] = (source_pointer[2] * product) >> 8; + auto& dest_pointer = gGamePalette[x]; + dest_pointer.Blue = (source_pointer[0] * product) >> 8; + dest_pointer.Green = (source_pointer[1] * product) >> 8; + dest_pointer.Red = (source_pointer[2] * product) >> 8; source_pointer += 3; - dest_pointer += 4; + + x++; } UpdatePalette(gGamePalette, 10, 236); } @@ -758,14 +759,14 @@ void LoadPalette() int32_t width = g1->width; int32_t x = g1->x_offset; uint8_t* src = g1->offset; - uint8_t* dst = &gGamePalette[x * 4]; for (; width > 0; width--) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; + auto& dst = gGamePalette[x]; + dst.Blue = src[0]; + dst.Green = src[1]; + dst.Red = src[2]; src += 3; - dst += 4; + x++; } } UpdatePalette(gGamePalette, 10, 236); @@ -910,15 +911,14 @@ FilterPaletteID GetGlassPaletteId(colour_t c) return GlassPaletteIds[c]; } -void UpdatePalette(const uint8_t* colours, int32_t start_index, int32_t num_colours) +void UpdatePalette(std::span palette, int32_t start_index, int32_t num_colours) { - colours += start_index * 4; - for (int32_t i = start_index; i < num_colours + start_index; i++) { - uint8_t r = colours[2]; - uint8_t g = colours[1]; - uint8_t b = colours[0]; + const auto& colour = palette[i]; + uint8_t b = colour.Blue; + uint8_t g = colour.Green; + uint8_t r = colour.Red; if (LightFXIsAvailable()) { @@ -935,18 +935,17 @@ void UpdatePalette(const uint8_t* colours, int32_t start_index, int32_t num_colo } } - gPalette[i].Red = r; - gPalette[i].Green = g; gPalette[i].Blue = b; + gPalette[i].Green = g; + gPalette[i].Red = r; gPalette[i].Alpha = 0; - colours += 4; } // Fix #1749 and #6535: rainbow path, donut shop and pause button contain black spots that should be white. - gPalette[255].Alpha = 0; - gPalette[255].Red = 255; - gPalette[255].Green = 255; gPalette[255].Blue = 255; + gPalette[255].Green = 255; + gPalette[255].Red = 255; + gPalette[255].Alpha = 0; if (!gOpenRCT2Headless) { @@ -989,14 +988,15 @@ void UpdatePaletteEffects() if (g1 != nullptr) { int32_t xoffset = g1->x_offset; - xoffset = xoffset * 4; - uint8_t* paletteOffset = gGamePalette + xoffset; + for (int32_t i = 0; i < g1->width; i++) { - paletteOffset[(i * 4) + 0] = -((0xFF - g1->offset[(i * 3) + 0]) / 2) - 1; - paletteOffset[(i * 4) + 1] = -((0xFF - g1->offset[(i * 3) + 1]) / 2) - 1; - paletteOffset[(i * 4) + 2] = -((0xFF - g1->offset[(i * 3) + 2]) / 2) - 1; + auto& paletteOffset = gGamePalette[xoffset + i]; + paletteOffset.Blue = -((0xFF - g1->offset[(i * 3) + 0]) / 2) - 1; + paletteOffset.Green = -((0xFF - g1->offset[(i * 3) + 1]) / 2) - 1; + paletteOffset.Red = -((0xFF - g1->offset[(i * 3) + 2]) / 2) - 1; } + UpdatePalette(gGamePalette, kPaletteOffsetDynamic, kPaletteLengthDynamic); } gClimateLightningFlash++; @@ -1017,13 +1017,13 @@ void UpdatePaletteEffects() if (g1 != nullptr) { int32_t xoffset = g1->x_offset; - xoffset = xoffset * 4; - uint8_t* paletteOffset = gGamePalette + xoffset; + for (int32_t i = 0; i < g1->width; i++) { - paletteOffset[(i * 4) + 0] = g1->offset[(i * 3) + 0]; - paletteOffset[(i * 4) + 1] = g1->offset[(i * 3) + 1]; - paletteOffset[(i * 4) + 2] = g1->offset[(i * 3) + 2]; + auto& paletteOffset = gGamePalette[xoffset + i]; + paletteOffset.Blue = g1->offset[(i * 3) + 0]; + paletteOffset.Green = g1->offset[(i * 3) + 1]; + paletteOffset.Red = g1->offset[(i * 3) + 2]; } } } @@ -1053,19 +1053,18 @@ void UpdatePaletteEffects() if (g1 != nullptr) { uint8_t* vs = &g1->offset[j * 3]; - uint8_t* vd = &gGamePalette[kPaletteOffsetWaterWaves * 4]; int32_t n = kPaletteLengthWaterWaves; for (int32_t i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; + auto& vd = gGamePalette[kPaletteOffsetWaterWaves + i]; + vd.Blue = vs[0]; + vd.Green = vs[1]; + vd.Red = vs[2]; vs += 9; if (vs >= &g1->offset[9 * n]) { vs -= 9 * n; } - vd += 4; } } @@ -1074,23 +1073,23 @@ void UpdatePaletteEffects() { waterId = water_type->palette_index_2; } + g1 = GfxGetG1Element(shade + waterId); if (g1 != nullptr) { uint8_t* vs = &g1->offset[j * 3]; - uint8_t* vd = &gGamePalette[kPaletteOffsetWaterSparkles * 4]; int32_t n = kPaletteLengthWaterSparkles; for (int32_t i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; + auto& vd = gGamePalette[kPaletteOffsetWaterSparkles]; + vd.Blue = vs[0]; + vd.Green = vs[1]; + vd.Red = vs[2]; vs += 9; if (vs >= &g1->offset[9 * n]) { vs -= 9 * n; } - vd += 4; } } @@ -1100,19 +1099,18 @@ void UpdatePaletteEffects() if (g1 != nullptr) { uint8_t* vs = &g1->offset[j * 3]; - uint8_t* vd = &gGamePalette[PALETTE_INDEX_243 * 4]; int32_t n = 3; for (int32_t i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; + auto& vd = gGamePalette[PALETTE_INDEX_243 + i]; + vd.Blue = vs[0]; + vd.Green = vs[1]; + vd.Red = vs[2]; vs += 3; if (vs >= &g1->offset[3 * n]) { vs -= 3 * n; } - vd += 4; } } diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 530c876520..264888d397 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -23,6 +23,7 @@ #include #include #include +#include #include struct ScreenCoordsXY; @@ -491,7 +492,7 @@ constexpr uint8_t kPaletteTotalOffsets = 192; constexpr int8_t kMaxScrollingTextModes = 38; extern OpenRCT2::Drawing::GamePalette gPalette; -extern uint8_t gGamePalette[256 * 4]; +extern OpenRCT2::Drawing::GamePalette gGamePalette; extern uint32_t gPaletteEffectFrame; extern uint8_t gTextPalette[]; @@ -604,7 +605,7 @@ void MaskFn( std::optional GetPaletteG1Index(colour_t paletteId); std::optional GetPaletteMapForColour(colour_t paletteId); -void UpdatePalette(const uint8_t* colours, int32_t start_index, int32_t num_colours); +void UpdatePalette(std::span palette, int32_t start_index, int32_t num_colours); void UpdatePaletteEffects(); void RefreshVideo(); From d352c31991e5e77fbc0476a0aab28f25515629d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Fri, 6 Dec 2024 00:57:05 +0200 Subject: [PATCH 4/5] Refactor PaletteMap, this is just a view of data --- src/openrct2/drawing/Drawing.cpp | 49 ++++++++------------------------ src/openrct2/drawing/Drawing.h | 36 +++++++++++------------ 2 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 6b5d31ccdc..9d7eace2fc 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -25,56 +25,31 @@ #include "../world/Location.hpp" #include "LightFX.h" +#include #include #include +#include using namespace OpenRCT2; -const PaletteMap& PaletteMap::GetDefault() -{ - static bool initialised = false; - static uint8_t data[256]; - static PaletteMap defaultMap(data); - if (!initialised) - { - for (size_t i = 0; i < sizeof(data); i++) - { - data[i] = static_cast(i); - } - initialised = true; - } - return defaultMap; -} +static auto _defaultPaletteMapping = []() { + std::array res; + std::iota(res.begin(), res.end(), 0); + return res; +}(); -bool PaletteMap::operator==(const PaletteMap& lhs) const +PaletteMap PaletteMap::GetDefault() { - return _data == lhs._data && _dataLength == lhs._dataLength && _numMaps == lhs._numMaps && _mapLength == lhs._mapLength; + return PaletteMap(_defaultPaletteMapping); } uint8_t& PaletteMap::operator[](size_t index) { - assert(index < _dataLength); - - // Provide safety in release builds - if (index >= _dataLength) - { - static uint8_t dummy; - return dummy; - } - return _data[index]; } uint8_t PaletteMap::operator[](size_t index) const { - assert(index < _dataLength); - - // Provide safety in release builds - if (index >= _dataLength) - { - return 0; - } - return _data[index]; } @@ -84,15 +59,15 @@ uint8_t PaletteMap::Blend(uint8_t src, uint8_t dst) const assert(src != 0 && (src - 1) < _numMaps); assert(dst < _mapLength); auto idx = ((src - 1) * 256) + dst; - return (*this)[idx]; + return _data[idx]; } void PaletteMap::Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, size_t length) { - auto maxLength = std::min(_mapLength - srcIndex, _mapLength - dstIndex); + auto maxLength = std::min(_data.size() - srcIndex, _data.size() - dstIndex); assert(length <= maxLength); auto copyLength = std::min(length, maxLength); - std::memcpy(&_data[dstIndex], &src._data[srcIndex], copyLength); + std::copy(src._data.begin() + srcIndex, src._data.begin() + srcIndex + copyLength, _data.begin() + dstIndex); } OpenRCT2::Drawing::GamePalette gPalette; diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 264888d397..0598f3b854 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -351,39 +351,39 @@ struct TranslucentWindowPalette struct PaletteMap { private: - uint8_t* _data{}; - uint32_t _dataLength{}; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-private-field" - uint16_t _numMaps; -#pragma clang diagnostic pop - uint16_t _mapLength; + std::span _data{}; +#ifdef _DEBUG + // We only require those fields for the asserts in debug builds. + size_t _numMaps{}; + size_t _mapLength{}; +#endif public: - static const PaletteMap& GetDefault(); + static PaletteMap GetDefault(); - PaletteMap() = default; + constexpr PaletteMap() = default; - PaletteMap(uint8_t* data, uint16_t numMaps, uint16_t mapLength) - : _data(data) - , _dataLength(numMaps * mapLength) + constexpr PaletteMap(uint8_t* data, size_t numMaps, size_t mapLength) + : _data{ data, numMaps * mapLength } +#ifdef _DEBUG , _numMaps(numMaps) , _mapLength(mapLength) +#endif { } - template - PaletteMap(uint8_t (&map)[TSize]) + constexpr PaletteMap(std::span map) : _data(map) - , _dataLength(static_cast(std::size(map))) +#ifdef _DEBUG , _numMaps(1) - , _mapLength(static_cast(std::size(map))) + , _mapLength(map.size()) +#endif { } - bool operator==(const PaletteMap& lhs) const; uint8_t& operator[](size_t index); uint8_t operator[](size_t index) const; + uint8_t Blend(uint8_t src, uint8_t dst) const; void Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, size_t length); }; @@ -391,7 +391,7 @@ public: struct DrawSpriteArgs { ImageId Image; - const PaletteMap& PalMap; + PaletteMap PalMap; const G1Element& SourceImage; int32_t SrcX; int32_t SrcY; From 5765bf328197edd0ce2a6473047007846c1a85c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:24:40 +0200 Subject: [PATCH 5/5] Wrap asserts with _DEBUG as the variables don't exist for debug builds --- src/openrct2/drawing/Drawing.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 9d7eace2fc..65fafd5b72 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -55,9 +55,11 @@ uint8_t PaletteMap::operator[](size_t index) const uint8_t PaletteMap::Blend(uint8_t src, uint8_t dst) const { +#ifdef _DEBUG // src = 0 would be transparent so there is no blend palette for that, hence (src - 1) assert(src != 0 && (src - 1) < _numMaps); assert(dst < _mapLength); +#endif auto idx = ((src - 1) * 256) + dst; return _data[idx]; }