diff --git a/src/common/engine/palettecontainer.cpp b/src/common/engine/palettecontainer.cpp index 4cd4a28bc..41a92735d 100644 --- a/src/common/engine/palettecontainer.cpp +++ b/src/common/engine/palettecontainer.cpp @@ -51,7 +51,7 @@ extern uint8_t IcePalette[16][3]; // //---------------------------------------------------------------------------- -void PaletteContainer::Init(int numslots) // This cannot be a constructor!!! +void PaletteContainer::Init(int numslots, const uint8_t* indexmap) // This cannot be a constructor!!! { if (numslots < 1) numslots = 1; Clear(); @@ -63,6 +63,7 @@ void PaletteContainer::Init(int numslots) // This cannot be a constructor!!! TranslationTables.Resize(numslots); StoreTranslation(0, &remap); // make sure that translation ID 0 is the identity. ColorMatcher.SetPalette(BaseColors); + ColorMatcher.SetIndexMap(indexmap); } void PaletteContainer::SetPalette(const uint8_t* colors, int transparent_index) diff --git a/src/common/engine/palettecontainer.h b/src/common/engine/palettecontainer.h index 1103f5c34..10883a374 100644 --- a/src/common/engine/palettecontainer.h +++ b/src/common/engine/palettecontainer.h @@ -116,7 +116,7 @@ private: FMemArena remapArena; TArray> TranslationTables; public: - void Init(int numslots); // This cannot be a constructor!!! + void Init(int numslots, const uint8_t *indexmap); // This cannot be a constructor!!! void SetPalette(const uint8_t* colors, int transparent_index = -1); void Clear(); int DetermineTranslucency(FileReader& file); diff --git a/src/common/models/voxels.cpp b/src/common/models/voxels.cpp index 75acb8dda..12c070b0d 100644 --- a/src/common/models/voxels.cpp +++ b/src/common/models/voxels.cpp @@ -74,7 +74,7 @@ static uint8_t *GetVoxelRemap(const uint8_t *pal) { // The voxel palette uses VGA colors, so we have to expand it // from 6 to 8 bits per component. - remap[i] = BestColor((uint32_t *)GPalette.BaseColors, + remap[i] = ColorMatcher.Pick( (oldpal[i*3 + 0] << 2) | (oldpal[i*3 + 0] >> 4), (oldpal[i*3 + 1] << 2) | (oldpal[i*3 + 1] >> 4), (oldpal[i*3 + 2] << 2) | (oldpal[i*3 + 2] >> 4)); diff --git a/src/common/utility/colormatcher.h b/src/common/utility/colormatcher.h index e17db4b5b..6ec20879a 100644 --- a/src/common/utility/colormatcher.h +++ b/src/common/utility/colormatcher.h @@ -42,23 +42,21 @@ #include "palutil.h" -int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num); +int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num, const uint8_t* indexmap); class FColorMatcher { public: - FColorMatcher () = default; - FColorMatcher (const uint32_t *palette) { Pal = reinterpret_cast(palette); } - FColorMatcher (const FColorMatcher &other) = default; void SetPalette(PalEntry* palette) { Pal = palette; } void SetPalette (const uint32_t *palette) { Pal = reinterpret_cast(palette); } + void SetIndexMap(const uint8_t* index) { indexmap = index; startindex = index ? 0 : 1; } uint8_t Pick (int r, int g, int b) { if (Pal == nullptr) return 1; - return (uint8_t)BestColor ((uint32_t *)Pal, r, g, b, 1, 255); + return (uint8_t)BestColor ((uint32_t *)Pal, r, g, b, startindex, 255, indexmap); } uint8_t Pick (PalEntry pe) @@ -66,10 +64,10 @@ public: return Pick(pe.r, pe.g, pe.b); } - FColorMatcher &operator= (const FColorMatcher &other) = default; - private: - const PalEntry *Pal; + const PalEntry *Pal = nullptr; + const uint8_t* indexmap = nullptr; + int startindex = 1; }; extern FColorMatcher ColorMatcher; diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 28a3cf35c..3b6e71e55 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -46,7 +46,7 @@ /* Palette management stuff */ /****************************/ -int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num) +int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num, const uint8_t* indexmap) { const PalEntry *pal = (const PalEntry *)pal_in; int bestcolor = first; @@ -54,17 +54,18 @@ int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num) for (int color = first; color < num; color++) { - int x = r - pal[color].r; - int y = g - pal[color].g; - int z = b - pal[color].b; + int co = indexmap ? indexmap[color] : color; + int x = r - pal[co].r; + int y = g - pal[co].g; + int z = b - pal[co].b; int dist = x*x + y*y + z*z; if (dist < bestdist) { if (dist == 0) - return color; + return co; bestdist = dist; - bestcolor = color; + bestcolor = co; } } return bestcolor; diff --git a/src/common/utility/palutil.h b/src/common/utility/palutil.h index a2bdeb446..bbd8f9a2d 100644 --- a/src/common/utility/palutil.h +++ b/src/common/utility/palutil.h @@ -7,7 +7,7 @@ struct FScriptPosition; class FScanner; -int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255); +int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255, const uint8_t* indexmap = nullptr); int PTM_BestColor(const uint32_t* pal_in, int r, int g, int b, bool reverselookup, float powtable, int first = 1, int num = 255); void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int b, int a);