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
This commit is contained in:
helixhorned 2014-02-08 14:37:58 +00:00
parent 5726a15bb3
commit a9fb9e6356
5 changed files with 61 additions and 24 deletions

View file

@ -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 {

View file

@ -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).
// <lastokcol> 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;
}

View file

@ -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
^^^^^^^^^^^^^^^^^^^^^^

View file

@ -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 <lastokcol>: must be in the range [0 .. 255]", 2)
end
return C.getclosestcol_lim(r, g, b, lastokcol)
end

View file

@ -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