diff --git a/source/blood/src/screen.cpp b/source/blood/src/screen.cpp index d393245d7..de3cb35ba 100644 --- a/source/blood/src/screen.cpp +++ b/source/blood/src/screen.cpp @@ -137,8 +137,8 @@ void scrLoadPalette(void) x = bloodglblend; #endif - initfastcolorlookup_scale(30, 59, 11); - initfastcolorlookup_gridvectors(); + paletteInitClosestColorScale(30, 59, 11); + paletteInitClosestColorGrid(); paletteloaded = 0; initprintf("Loading palettes\n"); for (int i = 0; i < 5; i++) @@ -161,7 +161,7 @@ void scrLoadPalette(void) blendtable[0] = (char*)gSysRes.Lock(pTrans); paletteloaded |= PALETTE_TRANSLUC; - initfastcolorlookup_palette(palette); + paletteInitClosestColorMap(palette); palettePostLoadTables(); } diff --git a/source/build/include/build.h b/source/build/include/build.h index 9439f5e21..d745a7c98 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -618,6 +618,7 @@ EXTERN uint8_t gotpic[(MAXTILES+7)>>3]; EXTERN char gotsector[(MAXSECTORS+7)>>3]; EXTERN char editorcolors[256]; +EXTERN char editorcolorsdef[256]; EXTERN char editwall[(MAXWALLS+7)>>3]; diff --git a/source/build/include/colmatch.h b/source/build/include/colmatch.h index 751ba1a68..7a9077737 100644 --- a/source/build/include/colmatch.h +++ b/source/build/include/colmatch.h @@ -1,15 +1,24 @@ #include "compat.h" -extern void initfastcolorlookup_scale(int32_t rscale, int32_t gscale, int32_t bscale); -extern void initfastcolorlookup_palette(uint8_t const * pal) ATTRIBUTE((nonnull(1))); -extern void initfastcolorlookup_gridvectors(void); +extern void paletteInitClosestColorScale(int32_t rscale, int32_t gscale, int32_t bscale); +extern void paletteInitClosestColorMap(uint8_t const * pal) ATTRIBUTE((nonnull(1))); +extern void paletteInitClosestColorGrid(void); -extern int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); -extern int32_t getclosestcol_nocache_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); -extern void getclosestcol_flush(void); +extern int32_t paletteGetClosestColorWithBlacklist(int32_t r, int32_t g, int32_t b, int32_t lastokcol, uint8_t const * blacklist); +extern int32_t paletteGetClosestColorWithBlacklistNoCache(int32_t r, int32_t g, int32_t b, int32_t lastokcol, uint8_t const * blacklist); +extern void paletteFlushClosestColor(void); + +static FORCE_INLINE int32_t paletteGetClosestColorUpToIndex(int32_t r, int32_t g, int32_t b, int32_t lastokcol) +{ + return paletteGetClosestColorWithBlacklist(r, g, b, lastokcol, NULL); +} +static FORCE_INLINE int32_t paletteGetClosestColorUpToIndexNoCache(int32_t r, int32_t g, int32_t b, int32_t lastokcol) +{ + return paletteGetClosestColorWithBlacklistNoCache(r, g, b, lastokcol, NULL); +} static FORCE_INLINE int32_t paletteGetClosestColor(int32_t r, int32_t g, int32_t b) { - return getclosestcol_lim(r, g, b, 255); + return paletteGetClosestColorUpToIndex(r, g, b, 255); } diff --git a/source/build/include/palette.h b/source/build/include/palette.h index d8b6f0c21..b92140a3a 100644 --- a/source/build/include/palette.h +++ b/source/build/include/palette.h @@ -28,16 +28,17 @@ extern uint8_t curbasepal; #define paletteGetBlendTable(blend) (blendtable[blend]) -extern uint32_t PaletteIndexFullbrights[8]; +extern uint8_t PaletteIndexFullbrights[32]; + inline bool IsPaletteIndexFullbright(uint8_t col) { - return (PaletteIndexFullbrights[col >> 5] & (1u << (col & 31))); + return (PaletteIndexFullbrights[col >> 3] & (1u << (col & 7))); } inline void SetPaletteIndexFullbright(int col) { - PaletteIndexFullbrights[col >> 5] |= (1u << (col & 31)); + PaletteIndexFullbrights[col >> 3] |= (1u << (col & 7)); } struct palette_t diff --git a/source/build/src/colmatch.cpp b/source/build/src/colmatch.cpp index d6c40feeb..401c532f5 100644 --- a/source/build/src/colmatch.cpp +++ b/source/build/src/colmatch.cpp @@ -19,9 +19,9 @@ static uint8_t const * colmatch_palette; #define pow2char(x) (1u << (x)) // -// initfastcolorlookup +// paletteInitClosestColor // -void initfastcolorlookup_scale(int32_t rscale, int32_t gscale, int32_t bscale) +void paletteInitClosestColorScale(int32_t rscale, int32_t gscale, int32_t bscale) { int32_t j = 0; for (bssize_t i=256; i>=0; i--) @@ -33,7 +33,7 @@ void initfastcolorlookup_scale(int32_t rscale, int32_t gscale, int32_t bscale) j += FASTPALRGBDIST-(i<<1); } } -void initfastcolorlookup_palette(uint8_t const * const pal) +void paletteInitClosestColorMap(uint8_t const * const pal) { Bmemset(colhere,0,sizeof(colhere)); Bmemset(colhead,0,sizeof(colhead)); @@ -51,9 +51,9 @@ void initfastcolorlookup_palette(uint8_t const * const pal) colhere[j>>3] |= pow2char(j&7); } - getclosestcol_flush(); + paletteFlushClosestColor(); } -void initfastcolorlookup_gridvectors(void) +void paletteInitClosestColorGrid(void) { int i = 0; int32_t x, y, z; @@ -71,18 +71,20 @@ void initfastcolorlookup_gridvectors(void) #define COLRESULTSIZ 4096 -static uint32_t getclosestcol_results[COLRESULTSIZ]; -static int32_t numclosestcolresults; +static uint32_t colmatchresults[COLRESULTSIZ]; +static int32_t numcolmatchresults; -void getclosestcol_flush(void) +void paletteFlushClosestColor(void) { - Bmemset(getclosestcol_results, 0, COLRESULTSIZ * sizeof(uint32_t)); - numclosestcolresults = 0; + Bmemset(colmatchresults, 0, COLRESULTSIZ * sizeof(uint32_t)); + numcolmatchresults = 0; } +#define checkbitfield(field, idx) ((field)[(idx)>>3] & (1u<<((idx)&7))) + // Finds a color index in [0 .. lastokcol] closest to (r, g, b). // must be in [0 .. 255]. -int32_t getclosestcol_lim(int32_t const r, int32_t const g, int32_t const b, int32_t const lastokcol) +int32_t paletteGetClosestColorWithBlacklist(int32_t const r, int32_t const g, int32_t const b, int32_t const lastokcol, uint8_t const * const blacklist) { #ifdef DEBUGGINGAIDS Bassert(lastokcol >= 0 && lastokcol <= 255); @@ -92,37 +94,41 @@ int32_t getclosestcol_lim(int32_t const r, int32_t const g, int32_t const b, int int mindist = -1; - int const k = (numclosestcolresults > COLRESULTSIZ) ? COLRESULTSIZ : numclosestcolresults; + int const k = (numcolmatchresults > COLRESULTSIZ) ? COLRESULTSIZ : numcolmatchresults; - if (!numclosestcolresults) goto skip; + if (!numcolmatchresults) goto skip; - if (col == (getclosestcol_results[(numclosestcolresults-1) & (COLRESULTSIZ-1)] & 0x00ffffff)) - return getclosestcol_results[(numclosestcolresults-1) & (COLRESULTSIZ-1)]>>24; + if (col == (colmatchresults[(numcolmatchresults-1) & (COLRESULTSIZ-1)] & 0x00ffffff)) + return colmatchresults[(numcolmatchresults-1) & (COLRESULTSIZ-1)]>>24; int i; for (i = 0; i <= k-4; i+=4) { - if (col == (getclosestcol_results[i] & 0x00ffffff)) { mindist = i; break; } - if (col == (getclosestcol_results[i+1] & 0x00ffffff)) { mindist = i+1; break; } - if (col == (getclosestcol_results[i+2] & 0x00ffffff)) { mindist = i+2; break; } - if (col == (getclosestcol_results[i+3] & 0x00ffffff)) { mindist = i+3; break; } + if (col == (colmatchresults[i] & 0x00ffffff)) { mindist = i; break; } + if (col == (colmatchresults[i+1] & 0x00ffffff)) { mindist = i+1; break; } + if (col == (colmatchresults[i+2] & 0x00ffffff)) { mindist = i+2; break; } + if (col == (colmatchresults[i+3] & 0x00ffffff)) { mindist = i+3; break; } } if (mindist == -1) for (; i < k; i++) - if (col == (getclosestcol_results[i] & 0x00ffffff)) { mindist = i; break; } + if (col == (colmatchresults[i] & 0x00ffffff)) { mindist = i; break; } - if (mindist != -1 && getclosestcol_results[mindist]>>24 < (unsigned)lastokcol) - return getclosestcol_results[mindist]>>24; + if (mindist != -1) + { + uint32_t const idx = colmatchresults[mindist]>>24; + if (idx <= (unsigned)lastokcol && (blacklist == nullptr || !checkbitfield(blacklist, idx))) + return idx; + } skip: - i = getclosestcol_nocache_lim(r, g, b, lastokcol); - getclosestcol_results[numclosestcolresults++ & (COLRESULTSIZ-1)] = col | (i << 24); + i = paletteGetClosestColorWithBlacklistNoCache(r, g, b, lastokcol, blacklist); + colmatchresults[numcolmatchresults++ & (COLRESULTSIZ-1)] = col | (i << 24); return i; } -int32_t getclosestcol_nocache_lim(int32_t r, int32_t g, int32_t b, int32_t const lastokcol) +int32_t paletteGetClosestColorWithBlacklistNoCache(int32_t r, int32_t g, int32_t b, int32_t const lastokcol, uint8_t const * const blacklist) { #ifdef DEBUGGINGAIDS Bassert(lastokcol >= 0 && lastokcol <= 255); @@ -158,7 +164,7 @@ int32_t getclosestcol_nocache_lim(int32_t r, int32_t g, int32_t b, int32_t const char const * const pal1 = (char const *)&colmatch_palette[i*3]; int dist = gdist[pal1[1]+g]; - if (dist >= mindist || i > lastokcol) continue; + if (dist >= mindist || i > lastokcol || (blacklist != nullptr && checkbitfield(blacklist, i))) continue; if ((dist += rdist[pal1[0]+r]) >= mindist) continue; if ((dist += bdist[pal1[2]+b]) >= mindist) continue; @@ -173,8 +179,11 @@ int32_t getclosestcol_nocache_lim(int32_t r, int32_t g, int32_t b, int32_t const mindist = INT32_MAX; - for (bssize_t i = 0; i < lastokcol; ++i) + for (bssize_t i = 0; i <= lastokcol; ++i) { + if (blacklist != nullptr && checkbitfield(blacklist, i)) + continue; + char const * const pal1 = (char const *)&colmatch_palette[i*3]; int dist = gdist[pal1[1]+g]; diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 4642b214d..3eff02ce5 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -467,7 +467,10 @@ static int32_t defsparser(scriptfile *script) if (scriptfile_getnumber(script,&idxend)) break; while ((unsigned)col < 256 && idx <= idxend) + { + editorcolorsdef[col] = 1; editorcolors[col++] = idx++; + } } break; case T_FOGPAL: @@ -2713,7 +2716,7 @@ static int32_t defsparser(scriptfile *script) if (didLoadPal && id == 0) { - initfastcolorlookup_palette(palette); + paletteInitClosestColorMap(palette); paletteloaded |= PALETTE_MAIN; } diff --git a/source/build/src/palette.cpp b/source/build/src/palette.cpp index 569ffef40..cc9fa9bf3 100644 --- a/source/build/src/palette.cpp +++ b/source/build/src/palette.cpp @@ -164,8 +164,8 @@ inline bool read_and_test(FileReader& handle, void* buffer, int32_t leng) // void paletteLoadFromDisk(void) { - initfastcolorlookup_scale(30, 59, 11); - initfastcolorlookup_gridvectors(); + paletteInitClosestColorScale(30, 59, 11); + paletteInitClosestColorGrid(); #ifdef USE_OPENGL for (auto & x : glblend) @@ -191,7 +191,7 @@ void paletteLoadFromDisk(void) for (unsigned char & k : palette) k <<= 2; - initfastcolorlookup_palette(palette); + paletteInitClosestColorMap(palette); paletteloaded |= PALETTE_MAIN; @@ -335,7 +335,7 @@ void paletteLoadFromDisk(void) } } -uint32_t PaletteIndexFullbrights[8]; +uint8_t PaletteIndexFullbrights[32]; void palettePostLoadTables(void) { @@ -358,12 +358,6 @@ void palettePostLoadTables(void) whitecol = paletteGetClosestColor(255, 255, 255); redcol = paletteGetClosestColor(255, 0, 0); - for (size_t i = 0; i<16; i++) - { - palette_t *edcol = (palette_t *) &vgapal16[4*i]; - editorcolors[i] = getclosestcol_lim(edcol->b, edcol->g, edcol->r, playing_blood ? 254 : 239); - } - // Bmemset(PaletteIndexFullbrights, 0, sizeof(PaletteIndexFullbrights)); for (bssize_t c = 0; c < 255; ++c) // skipping transparent color { @@ -400,6 +394,15 @@ void palettePostLoadTables(void) PostLoad_FoundShade: ; frealmaxshade = (float)(realmaxshade = s+1); } + + for (size_t i = 0; i<256; i++) + { + if (editorcolorsdef[i]) + continue; + + palette_t *edcol = (palette_t *) &vgapal16[4*i]; + editorcolors[i] = paletteGetClosestColorWithBlacklist(edcol->b, edcol->g, edcol->r, 254, PaletteIndexFullbrights); + } } void paletteFixTranslucencyMask(void) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index ac814d405..a6a570d84 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -5829,7 +5829,7 @@ badindex: { tw = *insptr++; int32_t const rgb = Gv_GetVar(*insptr++); - Gv_SetVar(tw, getclosestcol_lim(rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, Gv_GetVar(*insptr++))); + Gv_SetVar(tw, paletteGetClosestColorUpToIndex(rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, Gv_GetVar(*insptr++))); } dispatch();