diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index 7c215564e..c7690c017 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -35,7 +35,7 @@ UTIL_LIBS= -lm # -lpthread ENGINE_OBJ=$(ENGINE_ROOT)/$(obj) -ENGINE_OBJS=baselayer cache1d common compat crc32 defs engine polymost texcache dxtfilter hightile textfont smalltextfont kplib lz4 osd pragmas scriptfile mmulti_null mutex xxhash md4 +ENGINE_OBJS=baselayer cache1d common compat crc32 defs engine polymost texcache dxtfilter hightile textfont smalltextfont kplib lz4 osd pragmas scriptfile mmulti_null mutex xxhash md4 colmatch ENGINE_EDITOR_OBJS=build config defs ifeq (0,$(NOASM)) ENGINE_OBJS+= a diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index aef67fc2d..7c131495d 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -1247,13 +1247,6 @@ FORCE_INLINE int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsotil int32_t screencapture(const char *filename, char inverseit, const char *versionstr) ATTRIBUTE((nonnull(1))); -int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); - -FORCE_INLINE int32_t getclosestcol(int32_t r, int32_t g, int32_t b) -{ - return getclosestcol_lim(r, g, b, 255); -} - // PLAG: line utility functions typedef struct s_equation { float a, b, c; diff --git a/polymer/eduke32/build/include/colmatch.h b/polymer/eduke32/build/include/colmatch.h new file mode 100644 index 000000000..cf8ae0adc --- /dev/null +++ b/polymer/eduke32/build/include/colmatch.h @@ -0,0 +1,22 @@ + +#include "compat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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 int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); +extern void getclosestcol_flush(void); + +FORCE_INLINE int32_t getclosestcol(int32_t r, int32_t g, int32_t b) +{ + return getclosestcol_lim(r, g, b, 255); +} + +#ifdef __cplusplus +} +#endif diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index a52e9852f..2d0f11c4e 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -12,6 +12,7 @@ #include "cache1d.h" #include "editor.h" #include "common.h" +#include "colmatch.h" #include "baselayer.h" #include "renderlayer.h" diff --git a/polymer/eduke32/build/src/colmatch.c b/polymer/eduke32/build/src/colmatch.c new file mode 100644 index 000000000..a8c8750a2 --- /dev/null +++ b/polymer/eduke32/build/src/colmatch.c @@ -0,0 +1,183 @@ + +#include "colmatch.h" + +#define FASTPALCOLDEPTH 256 +#define FASTPALRIGHTSHIFT 3 +#define FASTPALRGBDIST (FASTPALCOLDEPTH*2+1) +static int32_t rdist[FASTPALRGBDIST], gdist[FASTPALRGBDIST], bdist[FASTPALRGBDIST]; +#define FASTPALGRIDSIZ (FASTPALCOLDEPTH>>FASTPALRIGHTSHIFT) +static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3]; +static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)]; +static int32_t colnext[256]; +#define FASTPALCOLDIST (1<=0; i--) + { + //j = (i-64)*(i-64); + rdist[i] = rdist[FASTPALCOLDEPTH*2-i] = j*rscale; + gdist[i] = gdist[FASTPALCOLDEPTH*2-i] = j*gscale; + bdist[i] = bdist[FASTPALCOLDEPTH*2-i] = j*bscale; + j += FASTPALRGBDIST-(i<<1); + } +} +void initfastcolorlookup_palette(uint8_t const * const pal) +{ + Bmemset(colhere,0,sizeof(colhere)); + Bmemset(colhead,0,sizeof(colhead)); + + colmatch_palette = pal; + + char const *pal1 = (char *)&pal[768-3]; + for (int i=255; i>=0; i--,pal1-=3) + { + int32_t const j = (pal1[0]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ + + (pal1[1]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (pal1[2]>>FASTPALRIGHTSHIFT) + + FASTPALGRIDSIZ*FASTPALGRIDSIZ + FASTPALGRIDSIZ + 1; + if (colhere[j>>3]&pow2char(j&7)) colnext[i] = colhead[j]; else colnext[i] = -1; + colhead[j] = i; + colhere[j>>3] |= pow2char(j&7); + } +} +void initfastcolorlookup_gridvectors(void) +{ + int i = 0; + int32_t x, y, z; + for (x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ; x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ; x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ) + for (y=-FASTPALGRIDSIZ; y<=FASTPALGRIDSIZ; y+=FASTPALGRIDSIZ) + for (z=-1; z<=1; z++) + colscan[i++] = x+y+z; + i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i; + + for (i = 0; i < FASTPALCOLDIST/2; i++) + coldist[i] = i; + for (; i < FASTPALCOLDIST; i++) + coldist[i] = FASTPALCOLDIST-i; +} + +#define COLRESULTSIZ 4096 + +static uint32_t getclosestcol_results[COLRESULTSIZ]; +static int32_t numclosestcolresults; + +void getclosestcol_flush(void) +{ + Bmemset(getclosestcol_results, 0, COLRESULTSIZ * sizeof(uint32_t)); + numclosestcolresults = 0; +} + +// Finds a color index in [0 .. lastokcol] closest to (r, g, b). +// must be in [0 .. 255]. +int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol) +{ + const int j = (r>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ + + (g>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (b>>FASTPALRIGHTSHIFT) + + FASTPALGRIDSIZ*FASTPALGRIDSIZ + + FASTPALGRIDSIZ + 1; + +#ifdef DEBUGGINGAIDS + Bassert(lastokcol >= 0 && lastokcol <= 255); +#endif + + uint32_t const col = r | (g<<8) | (b<<16); + + int mindist = -1; + + int const k = (numclosestcolresults > COLRESULTSIZ) ? (COLRESULTSIZ-4) : (numclosestcolresults-4); + + if (!numclosestcolresults) goto skip; + + if (col == (getclosestcol_results[(numclosestcolresults-1) & (COLRESULTSIZ-1)] & 0x00ffffff)) + return getclosestcol_results[(numclosestcolresults-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 (mindist == -1) + for (; i < k; i++) + if (col == (getclosestcol_results[i] & 0x00ffffff)) { mindist = i; break; } + + if (mindist != -1 && getclosestcol_results[mindist]>>24 < (unsigned)lastokcol) + return getclosestcol_results[mindist]>>24; + +skip: + getclosestcol_results[numclosestcolresults & (COLRESULTSIZ-1)] = col; + + int const minrdist = rdist[coldist[r&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; + int const mingdist = gdist[coldist[g&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; + int const minbdist = bdist[coldist[b&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; + + mindist = min(minrdist, mingdist); + mindist = min(mindist, minbdist) + 1; + + r = FASTPALCOLDEPTH-r, g = FASTPALCOLDEPTH-g, b = FASTPALCOLDEPTH-b; + + int retcol = -1; + + for (int k=26; k>=0; k--) + { + i = colscan[k]+j; + + if ((colhere[i>>3]&pow2char(i&7)) == 0) + continue; + + i = colhead[i]; + + do + { + char const * const pal1 = (char *)&colmatch_palette[i*3]; + int dist = gdist[pal1[1]+g]; + + if (dist >= mindist || i > lastokcol) continue; + if ((dist += rdist[pal1[0]+r]) >= mindist) continue; + if ((dist += bdist[pal1[2]+b]) >= mindist) continue; + + mindist = dist; + retcol = i; + } + while ((i = colnext[i]) >= 0); + } + + if (retcol >= 0) + { + getclosestcol_results[numclosestcolresults++ & (COLRESULTSIZ-1)] |= retcol<<24; + return retcol; + } + + mindist = INT32_MAX; + + for (i=lastokcol; i>=0; i--) + { + char const * const pal1 = (char *)&colmatch_palette[i*3]; + int dist = gdist[pal1[1]+g]; + + if (dist >= mindist) continue; + if ((dist += rdist[pal1[0]+r]) >= mindist) continue; + if ((dist += bdist[pal1[2]+b]) >= mindist) continue; + + mindist = dist; + retcol = i; + } + + getclosestcol_results[numclosestcolresults++ & (COLRESULTSIZ-1)] |= retcol<<24; + return retcol; +} diff --git a/polymer/eduke32/build/src/defs.c b/polymer/eduke32/build/src/defs.c index dd64e7d59..0ffe4f05f 100644 --- a/polymer/eduke32/build/src/defs.c +++ b/polymer/eduke32/build/src/defs.c @@ -15,6 +15,7 @@ #include "lz4.h" #include "common.h" #include "mdsprite.h" // md3model_t +#include "colmatch.h" #ifdef USE_OPENGL # include "hightile.h" @@ -187,8 +188,6 @@ static int32_t check_tile(const char *defcmd, int32_t tile, const scriptfile *sc return 0; } -extern void getclosestcol_flush(void); - static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t alphacut) { const vec2_t siz = tilesiz[tile]; @@ -2846,7 +2845,7 @@ static int32_t defsparser(scriptfile *script) if (didLoadPal && id == 0) { - initfastcolorlookup_palette(); + initfastcolorlookup_palette(palette); paletteloaded |= PALETTE_MAIN; } diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 16341e35f..d3bd03906 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -21,6 +21,7 @@ #include "crc32.h" #include "xxhash.h" #include "lz4.h" +#include "colmatch.h" #include "baselayer.h" #include "scriptfile.h" @@ -2330,19 +2331,6 @@ static int32_t *lastx; int32_t halfxdim16, midydim16; -#define FASTPALCOLDEPTH 256 -#define FASTPALRIGHTSHIFT 3 -#define FASTPALRGBDIST (FASTPALCOLDEPTH*2+1) -static int32_t rdist[FASTPALRGBDIST], gdist[FASTPALRGBDIST], bdist[FASTPALRGBDIST]; -#define FASTPALGRIDSIZ (FASTPALCOLDEPTH>>FASTPALRIGHTSHIFT) -static char colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3]; -static char colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)]; -static int32_t colnext[256]; -#define FASTPALCOLDIST (1<=0; i--) - { - //j = (i-64)*(i-64); - rdist[i] = rdist[FASTPALCOLDEPTH*2-i] = j*rscale; - gdist[i] = gdist[FASTPALCOLDEPTH*2-i] = j*gscale; - bdist[i] = bdist[FASTPALCOLDEPTH*2-i] = j*bscale; - j += FASTPALRGBDIST-(i<<1); - } -} -void initfastcolorlookup_palette(void) -{ - Bmemset(colhere,0,sizeof(colhere)); - Bmemset(colhead,0,sizeof(colhead)); - - char const *pal1 = (char *)&palette[768-3]; - for (int i=255; i>=0; i--,pal1-=3) - { - int32_t const j = (pal1[0]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ - + (pal1[1]>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (pal1[2]>>FASTPALRIGHTSHIFT) - + FASTPALGRIDSIZ*FASTPALGRIDSIZ + FASTPALGRIDSIZ + 1; - if (colhere[j>>3]&pow2char[j&7]) colnext[i] = colhead[j]; else colnext[i] = -1; - colhead[j] = i; - colhere[j>>3] |= pow2char[j&7]; - } -} -static void initfastcolorlookup_gridvectors(void) -{ - int i = 0; - int32_t x, y, z; - for (x=-FASTPALGRIDSIZ*FASTPALGRIDSIZ; x<=FASTPALGRIDSIZ*FASTPALGRIDSIZ; x+=FASTPALGRIDSIZ*FASTPALGRIDSIZ) - for (y=-FASTPALGRIDSIZ; y<=FASTPALGRIDSIZ; y+=FASTPALGRIDSIZ) - for (z=-1; z<=1; z++) - colscan[i++] = x+y+z; - i = colscan[13]; colscan[13] = colscan[26]; colscan[26] = i; - - for (i = 0; i < FASTPALCOLDIST/2; i++) - coldist[i] = i; - for (; i < FASTPALCOLDIST; i++) - coldist[i] = FASTPALCOLDIST-i; -} - - static void alloc_palookup(int32_t pal) { #if defined ENGINE_USING_A_C || (defined CLASSIC_NONPOW2_YSIZE_WALLS && defined CLASSIC_NONPOW2_YSIZE_SPRITES) @@ -8335,7 +8275,7 @@ static void loadpalette(void) for (int k = 0; k < 768; k++) palette[k] <<= 2; - initfastcolorlookup_palette(); + initfastcolorlookup_palette(palette); paletteloaded |= PALETTE_MAIN; @@ -8596,121 +8536,6 @@ void fillemptylookups(void) makepalookup(j, NULL, 0,0,0, 1); } -#define COLRESULTSIZ 4096 - -static uint32_t getclosestcol_results[COLRESULTSIZ]; -static int32_t numclosestcolresults; - -void getclosestcol_flush(void) -{ - Bmemset(getclosestcol_results, 0, COLRESULTSIZ * sizeof(uint32_t)); - numclosestcolresults = 0; -} - -// Finds a color index in [0 .. lastokcol] closest to (r, g, b). -// must be in [0 .. 255]. -int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol) -{ - const int j = (r>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ*FASTPALGRIDSIZ - + (g>>FASTPALRIGHTSHIFT)*FASTPALGRIDSIZ + (b>>FASTPALRIGHTSHIFT) - + FASTPALGRIDSIZ*FASTPALGRIDSIZ - + FASTPALGRIDSIZ + 1; - -#ifdef DEBUGGINGAIDS - Bassert(lastokcol >= 0 && lastokcol <= 255); -#endif - - uint32_t const col = r | (g<<8) | (b<<16); - - int mindist = -1; - - int const k = (numclosestcolresults > COLRESULTSIZ) ? (COLRESULTSIZ-4) : (numclosestcolresults-4); - - if (!numclosestcolresults) goto skip; - - if (col == (getclosestcol_results[(numclosestcolresults-1) & (COLRESULTSIZ-1)] & 0x00ffffff)) - return getclosestcol_results[(numclosestcolresults-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 (mindist == -1) - for (; i < k; i++) - if (col == (getclosestcol_results[i] & 0x00ffffff)) { mindist = i; break; } - - if (mindist != -1 && getclosestcol_results[mindist]>>24 < (unsigned)lastokcol) - return getclosestcol_results[mindist]>>24; - -skip: - getclosestcol_results[numclosestcolresults & (COLRESULTSIZ-1)] = col; - - int const minrdist = rdist[coldist[r&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; - int const mingdist = gdist[coldist[g&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; - int const minbdist = bdist[coldist[b&FASTPALCOLDISTMASK]+FASTPALCOLDEPTH]; - - mindist = min(minrdist, mingdist); - mindist = min(mindist, minbdist) + 1; - - r = FASTPALCOLDEPTH-r, g = FASTPALCOLDEPTH-g, b = FASTPALCOLDEPTH-b; - - int retcol = -1; - - for (int k=26; k>=0; k--) - { - i = colscan[k]+j; - - if ((colhere[i>>3]&pow2char[i&7]) == 0) - continue; - - i = colhead[i]; - - do - { - char const * const pal1 = (char *)&palette[i*3]; - int dist = gdist[pal1[1]+g]; - - if (dist >= mindist || i > lastokcol) continue; - if ((dist += rdist[pal1[0]+r]) >= mindist) continue; - if ((dist += bdist[pal1[2]+b]) >= mindist) continue; - - mindist = dist; - retcol = i; - } - while ((i = colnext[i]) >= 0); - } - - if (retcol >= 0) - { - getclosestcol_results[numclosestcolresults++ & (COLRESULTSIZ-1)] |= retcol<<24; - return retcol; - } - - mindist = INT32_MAX; - - for (i=lastokcol; i>=0; i--) - { - char const * const pal1 = (char *)&palette[i*3]; - int dist = gdist[pal1[1]+g]; - - if (dist >= mindist) continue; - if ((dist += rdist[pal1[0]+r]) >= mindist) continue; - if ((dist += bdist[pal1[2]+b]) >= mindist) continue; - - mindist = dist; - retcol = i; - } - - getclosestcol_results[numclosestcolresults++ & (COLRESULTSIZ-1)] |= retcol<<24; - return retcol; -} - ////////// SPRITE LIST MANIPULATION FUNCTIONS ////////// diff --git a/polymer/eduke32/build/src/engine_priv.h b/polymer/eduke32/build/src/engine_priv.h index 4fc7c147d..fd359ee6d 100644 --- a/polymer/eduke32/build/src/engine_priv.h +++ b/polymer/eduke32/build/src/engine_priv.h @@ -237,8 +237,6 @@ FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t const globalposz = z, fglobalposz = (float)z; } -extern void initfastcolorlookup_palette(void); - #ifdef __cplusplus } #endif diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index 32c966dc8..3ca547b5b 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "macros.h" #include "lz4.h" +#include "colmatch.h" #include "m32script.h" #include "m32def.h" diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 7f0e72d87..2e6601d68 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -58,6 +58,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "common_game.h" #include "input.h" #include "compat.h" +#include "colmatch.h" #ifdef __ANDROID__ #include "android.h" diff --git a/polymer/eduke32/source/m32exec.c b/polymer/eduke32/source/m32exec.c index dc1765329..714fbcda9 100644 --- a/polymer/eduke32/source/m32exec.c +++ b/polymer/eduke32/source/m32exec.c @@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "keys.h" #include "common.h" +#include "colmatch.h" + // from macros.h #define rnd(X) ((krand()>>8)>=(255-(X)))