From a9fb9e6356254cd6c619992556f85f7747493193 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 8 Feb 2014 14:37:58 +0000 Subject: [PATCH] Lunatic: add a 'lastokcol' argument to engine.nearcolor() and document it. On the C side, slightly rewrite (now) getclosestcol_lim() for clarity. git-svn-id: https://svn.eduke32.com/eduke32@4308 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/build.h | 7 ++- polymer/eduke32/build/src/engine.c | 48 ++++++++++++------- .../eduke32/source/lunatic/doc/lunatic.txt | 14 ++++++ polymer/eduke32/source/lunatic/engine.lua | 14 ++++-- .../eduke32/source/lunatic/test/shadexfog.lua | 2 +- 5 files changed, 61 insertions(+), 24 deletions(-) diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index fd1aa5c89..74d2e9420 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -1244,7 +1244,12 @@ static inline int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsoti int32_t screencapture(const char *filename, char inverseit, const char *versionstr) ATTRIBUTE((nonnull(1))); -int32_t getclosestcol(int32_t r, int32_t g, int32_t b); +static inline int32_t getclosestcol(int32_t r, int32_t g, int32_t b) +{ + extern int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); + + return getclosestcol_lim(r, g, b, 255); +} // PLAG: line utility functions typedef struct s_equation { diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 09d9c424f..dec0d7382 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -8104,34 +8104,39 @@ static int32_t loadpalette(void) } -// -// getclosestcol -// -int32_t getclosestcol(int32_t r, int32_t g, int32_t b) +// 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) { - int32_t i, j, k, dist, mindist, retcol; - const char *pal1; + int32_t i, k, retcol = -1; - j = (r>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ + const int32_t j = (r>>3)*FASTPALGRIDSIZ*FASTPALGRIDSIZ + (g>>3)*FASTPALGRIDSIZ + (b>>3) + FASTPALGRIDSIZ*FASTPALGRIDSIZ + FASTPALGRIDSIZ+1; - mindist = min(rdist[coldist[r&7]+64+8],gdist[coldist[g&7]+64+8]); + + int32_t mindist = min(rdist[coldist[r&7]+64+8],gdist[coldist[g&7]+64+8]); mindist = min(mindist,bdist[coldist[b&7]+64+8]); mindist++; + Bassert(lastokcol >= 0 && lastokcol <= 255); + r = 64-r; g = 64-g; b = 64-b; - retcol = -1; for (k=26; k>=0; k--) { - i = colscan[k]+j; if ((colhere[i>>3]&pow2char[i&7]) == 0) continue; + i = colscan[k]+j; + if ((colhere[i>>3]&pow2char[i&7]) == 0) + continue; + i = colhead[i]; + do { - pal1 = (char *)&palette[i*3]; - dist = gdist[pal1[1]+g]; - if (dist < mindist) + const char *pal1 = (char *)&palette[i*3]; + int32_t dist = gdist[pal1[1]+g]; + + if (dist < mindist && i <= lastokcol) { dist += rdist[pal1[0]+r]; if (dist < mindist) @@ -8140,22 +8145,29 @@ int32_t getclosestcol(int32_t r, int32_t g, int32_t b) if (dist < mindist) { mindist = dist; retcol = i; } } } + i = colnext[i]; } while (i >= 0); } - if (retcol >= 0) return(retcol); + + if (retcol >= 0) + return retcol; mindist = INT32_MAX; - pal1 = (char *)&palette[768-3]; - for (i=255; i>=0; i--,pal1-=3) + + for (i=lastokcol; i>=0; i--) { - dist = gdist[pal1[1]+g]; if (dist >= mindist) continue; + const char *pal1 = (char *)&palette[i*3]; + + int32_t dist = gdist[pal1[1]+g]; if (dist >= mindist) continue; dist += rdist[pal1[0]+r]; if (dist >= mindist) continue; dist += bdist[pal1[2]+b]; if (dist >= mindist) continue; + mindist = dist; retcol = i; } - return(retcol); + + return retcol; } diff --git a/polymer/eduke32/source/lunatic/doc/lunatic.txt b/polymer/eduke32/source/lunatic/doc/lunatic.txt index 7bdd7ca85..90d21a1c0 100644 --- a/polymer/eduke32/source/lunatic/doc/lunatic.txt +++ b/polymer/eduke32/source/lunatic/doc/lunatic.txt @@ -2065,6 +2065,20 @@ for color index `i`. The color components are in the range [0 .. 63]. If `i` is 255, `r`, `g` and `b` are all returned as 0, even if the actual base palette may contain different values for that index. +`i = engine.nearcolor(r, g, b [, lastokcol])`:: + +Given the red, green and blue components `r`, `g` and `b` of a query color, +returns the color index `i` whose color in the default base palette is closest +to the query color. ``Closeness'' is established using an Euclidean distance +with a weighting on the color components. ++ +The optional argument `lastokcol` can be used to restrict the range of color +indices to search: the returned color index is guaranteed to be in the range +[0{nbsp}..{nbsp}`lastokcol`]. It defaults 255, so that all colors are +searched.footnote:[For example, it may be desirable to omit ``fullbright'' +colors from being returned. The shade table loaded from Duke3D's PALETTE.DAT +makes color indices 240--254 fullbright, so passing 239 to `lastokcol` achieves +the mentioned filtering.] Shade table interfaces ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/polymer/eduke32/source/lunatic/engine.lua b/polymer/eduke32/source/lunatic/engine.lua index 7b7cf7e27..94ae629bb 100644 --- a/polymer/eduke32/source/lunatic/engine.lua +++ b/polymer/eduke32/source/lunatic/engine.lua @@ -14,7 +14,7 @@ local ismapster32 = (C.LUNATIC_CLIENT == C.LUNATIC_CLIENT_MAPSTER32) ---------- decl[[ -int32_t getclosestcol(int32_t r, int32_t g, int32_t b); +int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol); char *palookup[256]; // MAXPALOOKUPS uint8_t palette[768]; @@ -211,12 +211,18 @@ function engine.getrgb(colidx) return rgbptr[0], rgbptr[1], rgbptr[2] end --- TODO: flag whether fullbrights are OK -function engine.nearcolor(r, g, b) +function engine.nearcolor(r, g, b, lastokcol) check_colcomp(r) check_colcomp(g) check_colcomp(b) - return C.getclosestcol(r, g, b) + + if (lastokcol == nil) then + lastokcol = 255 + elseif (type(lastokcol)~="number" or not (lastokcol >= 0 and lastokcol <= 255)) then + error("invalid argument #4 : must be in the range [0 .. 255]", 2) + end + + return C.getclosestcol_lim(r, g, b, lastokcol) end diff --git a/polymer/eduke32/source/lunatic/test/shadexfog.lua b/polymer/eduke32/source/lunatic/test/shadexfog.lua index efbf4903b..e95cff2d3 100644 --- a/polymer/eduke32/source/lunatic/test/shadexfog.lua +++ b/polymer/eduke32/source/lunatic/test/shadexfog.lua @@ -303,7 +303,7 @@ function shadexfog.create_additive_trans(blendidx) local r,g,b = engine.getrgb(i) local R,G,B = engine.getrgb(j) - tab[i][j] = engine.nearcolor(min(r+R, 63), min(g+G, 63), min(b+B, 63)) + tab[i][j] = engine.nearcolor(min(r+R, 63), min(g+G, 63), min(b+B, 63), 255-16) end end