From c8106a7f6d235041b5ce156c20109a3c90364245 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 2 Jun 2025 06:19:45 +0100 Subject: [PATCH] Palette blending: minor cleanups 1. Removes stray comments. 2. Loops only over half of the matrix. 3. Adds tests for `paletteTransparencyLookupBlack16`. --- Source/engine/palette.cpp | 13 ----------- Source/utils/palette_blending.cpp | 36 +++++++++++++++++-------------- test/palette_blending_test.cpp | 19 ++++++++++++++++ 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Source/engine/palette.cpp b/Source/engine/palette.cpp index 7a73d9a57..04935feb8 100644 --- a/Source/engine/palette.cpp +++ b/Source/engine/palette.cpp @@ -39,19 +39,6 @@ void LoadBrightness() GetOptions().Graphics.brightness.SetValue(brightnessValue - brightnessValue % 5); } -/** - * @brief Generate lookup table for transparency - * - * This is based of the same technique found in Quake2. - * - * To mimic 50% transparency we figure out what colors in the existing palette are the best match for the combination of any 2 colors. - * We save this into a lookup table for use during rendering. - * - * @param palette The colors to operate on - * @param skipFrom Do not use colors between this index and skipTo - * @param skipTo Do not use colors between skipFrom and this index - * @param toUpdate Only update the first n colors - */ /** * @brief Cycle the given range of colors in the palette * @param from First color index of the range diff --git a/Source/utils/palette_blending.cpp b/Source/utils/palette_blending.cpp index 6b22051cc..e6af27090 100644 --- a/Source/utils/palette_blending.cpp +++ b/Source/utils/palette_blending.cpp @@ -53,20 +53,25 @@ RGB BlendColors(const SDL_Color &a, const SDL_Color &b) }; } +#if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT +void SetPaletteTransparencyLookupBlack16(unsigned i, unsigned j) +{ + paletteTransparencyLookupBlack16[i | (j << 8U)] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8U); +} +#endif + } // namespace void GenerateBlendedLookupTable(SDL_Color palette[256], int skipFrom, int skipTo) { for (unsigned i = 0; i < 256; i++) { - for (unsigned j = 0; j < 256; j++) { - if (i == j) { // No need to calculate transparency between 2 identical colors - paletteTransparencyLookup[i][j] = j; - continue; - } - if (i > j) { // Half the blends will be mirror identical ([i][j] is the same as [j][i]), so simply copy the existing combination. - paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i]; - continue; - } + paletteTransparencyLookup[i][i] = i; + unsigned j = 0; + for (; j < i; j++) { + paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i]; + } + ++j; + for (; j < 256; j++) { const uint8_t best = FindBestMatchForColor(palette, BlendColors(palette[i], palette[j]), skipFrom, skipTo); paletteTransparencyLookup[i][j] = best; } @@ -74,9 +79,10 @@ void GenerateBlendedLookupTable(SDL_Color palette[256], int skipFrom, int skipTo #if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT for (unsigned i = 0; i < 256; ++i) { - for (unsigned j = 0; j < 256; ++j) { - const uint16_t index = i | (j << 8U); - paletteTransparencyLookupBlack16[index] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8); + SetPaletteTransparencyLookupBlack16(i, i); + for (unsigned j = 0; j < i; ++j) { + SetPaletteTransparencyLookupBlack16(i, j); + SetPaletteTransparencyLookupBlack16(j, i); } } #endif @@ -104,10 +110,8 @@ void UpdateTransparencyLookupBlack16(unsigned from, unsigned to) { for (unsigned i = from; i <= to; i++) { for (unsigned j = 0; j < 256; j++) { - const uint16_t index = i | (j << 8U); - const uint16_t reverseIndex = j | (i << 8U); - paletteTransparencyLookupBlack16[index] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8); - paletteTransparencyLookupBlack16[reverseIndex] = paletteTransparencyLookup[0][j] | (paletteTransparencyLookup[0][i] << 8); + SetPaletteTransparencyLookupBlack16(i, j); + SetPaletteTransparencyLookupBlack16(j, i); } } } diff --git a/test/palette_blending_test.cpp b/test/palette_blending_test.cpp index 73b0d79fc..984062878 100644 --- a/test/palette_blending_test.cpp +++ b/test/palette_blending_test.cpp @@ -47,6 +47,8 @@ TEST(GenerateBlendedLookupTableTest, BasicTest) GenerateBlendedLookupTable(palette, /*skipFrom=*/-1, /*skipTo=*/-1); + EXPECT_EQ(paletteTransparencyLookup[100][100], 100); + EXPECT_THAT(palette[17], ColorIs(17, 0, 34)); EXPECT_THAT(palette[150], ColorIs(44, 44, 44)); EXPECT_THAT(palette[86], ColorIs(22, 22, 44)); @@ -58,6 +60,23 @@ TEST(GenerateBlendedLookupTableTest, BasicTest) EXPECT_THAT(palette[15], ColorIs(15, 0, 30)); EXPECT_EQ(paletteTransparencyLookup[27][130], 15); EXPECT_EQ(paletteTransparencyLookup[130][27], 15); + + EXPECT_THAT(palette[0], ColorIs(0, 0, 0)); + EXPECT_THAT(palette[100], ColorIs(36, 36, 72)); + EXPECT_THAT(palette[82], ColorIs(18, 18, 36)); + EXPECT_EQ(paletteTransparencyLookup[0][100], 82); + EXPECT_EQ(paletteTransparencyLookup[100][0], 82); + + EXPECT_THAT(palette[0], ColorIs(0, 0, 0)); + EXPECT_THAT(palette[200], ColorIs(24, 24, 16)); + EXPECT_THAT(palette[196], ColorIs(12, 12, 8)); + EXPECT_EQ(paletteTransparencyLookup[0][200], 196); + EXPECT_EQ(paletteTransparencyLookup[200][0], 196); + +#if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT + EXPECT_EQ(paletteTransparencyLookupBlack16[100 | (100 << 8)], 82 | (82 << 8)); + EXPECT_EQ(paletteTransparencyLookupBlack16[100 | (200 << 8)], 82 | (196 << 8)); +#endif } } // namespace