In ext. PALETTE.DAT, store log2 of last alpha table index. Handle alpha in classic.

The extended PALETTE.DAT format can now carry a trailing byte, called
'lognumalphatables'. If it is present, the engine assumes that alpha blending
tables are loaded at blend indices 1 to 1<<lognumalphatables and handles
rotatesprite's alpha and spriteext[].alpha accordingly.
The ability to save this new byte is added to engine.lua:savePaletteDat()
and the corresponding convenience functions in shadexfog.lua.

Examples test/screentext.con and test/sprite_access.con are updated for
demonstration purposes.

git-svn-id: https://svn.eduke32.com/eduke32@4426 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2014-04-09 18:51:31 +00:00
parent 1d077db710
commit e1845c8d05
5 changed files with 119 additions and 32 deletions

View file

@ -2467,6 +2467,10 @@ char palfadedelta = 0;
// Internal Engine Functions // Internal Engine Functions
// //
// blendtable[1] to blendtable[numalphatabs] are considered to be
// alpha-blending tables:
static uint8_t numalphatabs;
static char *blendtable[MAXBLENDTABS]; static char *blendtable[MAXBLENDTABS];
void setblendtab(int32_t blend, const char *tab); void setblendtab(int32_t blend, const char *tab);
#define getblendtab(blend) (blendtable[blend]) #define getblendtab(blend) (blendtable[blend])
@ -5609,6 +5613,29 @@ static void drawsprite_opengl(int32_t snum)
//============================================================================= //POLYMOST ENDS //============================================================================= //POLYMOST ENDS
} }
static uint8_t falpha_to_blend(float alpha, int32_t *cstatptr, int32_t transbit1, int32_t transbit2)
{
int32_t blendidx, cstat = *cstatptr;
if (cstat&transbit1)
alpha = 1.0f - (1.0f - alpha) * ((cstat&transbit2) ? 0.33f : 0.66f);
cstat |= transbit1;
cstat &= ~transbit2;
blendidx = max(1, (int32_t)(alpha * (2*numalphatabs))); // [1 .. 2*numalphatabs-1]
if (blendidx > numalphatabs)
{
blendidx = 2*numalphatabs - blendidx;
cstat |= transbit2;
}
// blendidx now in [1 .. numalphatabs]
*cstatptr = cstat;
return blendidx;
}
static void drawsprite_classic(int32_t snum) static void drawsprite_classic(int32_t snum)
{ {
int32_t xoff, yoff, xspan, yspan; int32_t xoff, yoff, xspan, yspan;
@ -5627,6 +5654,9 @@ static void drawsprite_classic(int32_t snum)
int32_t tilenum; int32_t tilenum;
int32_t cstat = tspr->cstat; int32_t cstat = tspr->cstat;
uint8_t blendidx = tspr->blend;
float alpha = spriteext[spritenum].alpha;
if (sec == NULL) if (sec == NULL)
return; return;
@ -5635,13 +5665,17 @@ static void drawsprite_classic(int32_t snum)
DO_TILE_ANIM(tspr->picnum, spritenum+32768); DO_TILE_ANIM(tspr->picnum, spritenum+32768);
#ifdef USE_OPENGL if (alpha > 0.0f)
{ {
// hack pending proper alpha implentation if (alpha >= 1.0f)
// TODO: a real implementation return;
float alpha = spriteext[spritenum].alpha;
if (alpha >= 0.33f) // if alpha is 0 (which is the default) this structure should only necessitate one comparison if (numalphatabs != 0)
{
blendidx = falpha_to_blend(alpha, &cstat, 2, 512);
tspr->cstat = cstat;
}
else if (alpha >= 0.33f)
{ {
if ((cstat&2) && alpha >= 0.5f) // this covers the multiplicative aspect used in the Polymodes if ((cstat&2) && alpha >= 0.5f) // this covers the multiplicative aspect used in the Polymodes
cstat |= 512; cstat |= 512;
@ -5649,17 +5683,11 @@ static void drawsprite_classic(int32_t snum)
cstat |= 2; cstat |= 2;
if (alpha >= 0.66f) if (alpha >= 0.66f)
{
cstat |= 512; cstat |= 512;
if (alpha >= 1.0f)
return;
}
tspr->cstat = cstat; tspr->cstat = cstat;
} }
} }
#endif
tilenum = tspr->picnum; tilenum = tspr->picnum;
@ -5689,7 +5717,7 @@ static void drawsprite_classic(int32_t snum)
globalshade = tspr->shade; globalshade = tspr->shade;
if (cstat&2) if (cstat&2)
setup_blend(tspr->blend, cstat&512); setup_blend(blendidx, cstat&512);
xoff = picanm[tilenum].xofs + tspr->xoffset; xoff = picanm[tilenum].xofs + tspr->xoffset;
yoff = picanm[tilenum].yofs + tspr->yoffset; yoff = picanm[tilenum].yofs + tspr->yoffset;
@ -7396,21 +7424,25 @@ static void dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t
if (palookup[dapalnum] == NULL) dapalnum = 0; if (palookup[dapalnum] == NULL) dapalnum = 0;
palookupoffs = FP_OFF(palookup[dapalnum]) + (getpalookup(0, dashade)<<8); palookupoffs = FP_OFF(palookup[dapalnum]) + (getpalookup(0, dashade)<<8);
// hack pending proper alpha implentation // Alpha handling
// TODO: a real implementation if (daalpha > 0)
if (daalpha > 84) // if alpha is 0 (which is the default) this structure should only necessitate one comparison
{ {
if ((dastat & RS_TRANS1) && daalpha > 127) // this covers the multiplicative aspect used in the Polymodes if (daalpha == 255)
dastat |= RS_TRANS2; return;
dastat |= RS_TRANS1; if (numalphatabs != 0)
if (daalpha > 168)
{ {
dastat |= RS_TRANS2; dablend = falpha_to_blend((float)daalpha / 255.0f, &dastat, RS_TRANS1, RS_TRANS2);
}
else if (daalpha > 84)
{
if ((dastat & RS_TRANS1) && daalpha > 127) // this covers the multiplicative aspect used in the Polymodes
dastat |= RS_TRANS2;
if (daalpha == 255) dastat |= RS_TRANS1;
return;
if (daalpha > 168)
dastat |= RS_TRANS2;
} }
} }
@ -8102,6 +8134,18 @@ static int32_t loadpalette(void)
} }
Bfree(tab); Bfree(tab);
// Read log2 of count of alpha blending tables.
{
uint8_t lognumalphatabs;
if (kread(fil, &lognumalphatabs, 1) == 1)
{
if (!(lognumalphatabs >= 1 && lognumalphatabs <= 7))
return loadpalette_err("invalid lognumalphatabs value, must be in [1 .. 7]");
numalphatabs = 1<<lognumalphatabs;
}
}
} }
} }

View file

@ -299,8 +299,9 @@ if (ismapster32) then
return blendnumtab, blendptrtab return blendnumtab, blendptrtab
end end
-- ok, errmsg, nummoreblends = engine.savePaletteDat(filename [, palnum [, blendnum [, moreblends]]]) -- ok, errmsg, nummoreblends = engine.savePaletteDat(
function engine.savePaletteDat(filename, palnum, blendnum, moreblends) -- filename [, palnum [, blendnum [, moreblends [, lognumalphatabs]]]])
function engine.savePaletteDat(filename, palnum, blendnum, moreblends, lognumalphatabs)
local sht = engine.getshadetab(palnum or 0) local sht = engine.getshadetab(palnum or 0)
local tab = engine.getblendtab(blendnum or 0) local tab = engine.getblendtab(blendnum or 0)
@ -313,6 +314,10 @@ if (ismapster32) then
local blendnumtab, blendptrtab = validate_more_blendtabs( local blendnumtab, blendptrtab = validate_more_blendtabs(
moreblends, "blending", C.getblendtab) moreblends, "blending", C.getblendtab)
if (not (type(lognumalphatabs)=="number" and lognumalphatabs >= 1 and lognumalphatabs <= 7)) then
error("invalid argument #5: must be a number in [1 .. 7]", 2)
end
local f, errmsg = io.open(filename, "wb+") local f, errmsg = io.open(filename, "wb+")
if (f == nil) then if (f == nil) then
return nil, errmsg return nil, errmsg
@ -337,6 +342,12 @@ if (ismapster32) then
return nil, "failed writing additional blending table" return nil, "failed writing additional blending table"
end end
end end
if (lognumalphatabs) then
-- XXX: no checking whether these blending tables 1 to
-- 1<<lognumalphatabs have been written.
f:write(string.char(lognumalphatabs))
end
end end
f:close() f:close()

View file

@ -178,6 +178,15 @@ onevent EVENT_DISPLAYREST
xorvar f TEXT_UPPERCASE xorvar f TEXT_UPPERCASE
state increment_line state increment_line
// Calculate periodically cycling alpha value
setvarvar temp totalclock
shiftvarl temp 2
sin alpha temp // alpha is now in [-2^14 .. 2^14]
shiftvarr alpha 7 // [-2^7 .. 2^7]
addvar alpha 128 // [0 .. 256]
ifvarg alpha 255 setvar alpha 255
// divider line // divider line
rotatespritea 240 65 32768 512 WINDOWBORDER1 0 2 0 85 x1 y1 x2 y2 rotatespritea 240 65 32768 512 WINDOWBORDER1 0 2 0 85 x1 y1 x2 y2

View file

@ -269,8 +269,9 @@ end
if (gv.LUNATIC_CLIENT == gv.LUNATIC_CLIENT_MAPSTER32) then if (gv.LUNATIC_CLIENT == gv.LUNATIC_CLIENT_MAPSTER32) then
-- Wrapper around engine.savePaletteDat() that errors on unexpected events. -- Wrapper around engine.savePaletteDat() that errors on unexpected events.
function shadexfog.save(filename, palnum, blendnum, moreblends) function shadexfog.save(filename, palnum, blendnum, moreblends, lognumalphatabs)
local ok, errmsg, nummoreblends = engine.savePaletteDat(filename, palnum, blendnum, moreblends) local ok, errmsg, nummoreblends = engine.savePaletteDat(
filename, palnum, blendnum, moreblends, lognumalphatabs)
if (not ok) then if (not ok) then
error(errmsg) error(errmsg)
end end
@ -730,20 +731,31 @@ engine.registerMenuFunc(
end end
end end
shadexfog.save(filename, palnum, blendnum, moreblends) local lognumalphatabs
if (#moreblends > 0) then
lognumalphatabs = getnumber16("log2 of last alpha blending table index (1-7, 0: none): ", 0, 7)
if (lognumalphatabs < 0) then return end
if (lognumalphatabs == 0) then lognumalphatabs = nil end
end
shadexfog.save(filename, palnum, blendnum, moreblends, lognumalphatabs)
end, end,
formatHelp formatHelp
[[ [[
<shadexfog.save(filename, palnum, blendnum, moreblends)> <shadexfog.save(filename, palnum, blendnum, moreblends, lognumalpha)>
<______________________________________________________> <___________________________________________________________________>
Writes out a full PALETTE.DAT-formatted file named <filename> with the Writes out a full PALETTE.DAT-formatted file named <filename> with the
base shade table numbered <palnum> and the base translucency table base shade table numbered <palnum> and the base translucency table
numbered <blendnum>. numbered <blendnum>.
Finally, you are asked to specify additional blending tables that can Finally, you are asked to specify additional blending tables that can
be stored in EDuke32's extended PALETTE.DAT format. be stored in EDuke32's extended PALETTE.DAT format. If one or more
additional blending table is specified, you are also queried for the
log2 of the last alpha blending table index, <lognumalpha>. Since alpha
blending tables are assumed to be set up at indices 1 to 2^<lognumalpha>,
it is also the log2 of their total count.
]] ]]
) )

View file

@ -80,6 +80,8 @@ define NUMALPHATABS 128
define C1 0 //must be log2(128/NUMALPHATABS) define C1 0 //must be log2(128/NUMALPHATABS)
define C2 257 // must be 2*NUMALPHATABS+1 define C2 257 // must be 2*NUMALPHATABS+1
define ALPHA_TABS_BY_EDUKE32 1 // assume alpha->blend handling by EDuke32
onevent EVENT_ANIMATESPRITES onevent EVENT_ANIMATESPRITES
setvarvar tmp totalclock setvarvar tmp totalclock
shiftvarl tmp 2 shiftvarl tmp 2
@ -89,6 +91,15 @@ onevent EVENT_ANIMATESPRITES
addvar alpha 128 // [0 .. 256] addvar alpha 128 // [0 .. 256]
shiftvarr alpha C1 // [0 .. 2*NUMALPHATABS] shiftvarr alpha C1 // [0 .. 2*NUMALPHATABS]
ifvarn ALPHA_TABS_BY_EDUKE32 0
{
subvar alpha 1
ifvarl alpha 0 setvar alpha 0
setactor[THISACTOR].alpha alpha
break
}
ifvare alpha 0 ifvare alpha 0
{ {
// clear translucent bits, 0xfdfe == 0xffff-(1+512) // clear translucent bits, 0xfdfe == 0xffff-(1+512)
@ -103,7 +114,7 @@ onevent EVENT_ANIMATESPRITES
settspr[THISACTOR].tsprcstat tmp settspr[THISACTOR].tsprcstat tmp
// Assume blending tables [1 .. NUMALPHATABS] are installed, like // Assume blending tables [1 .. NUMALPHATABS] are installed, like
// generated by shadexfog.lua:create_128_trans(1, NUMALPHATABS). // generated by shadexfog.lua:create_alpha_trans(1, NUMALPHATABS).
ifvarg alpha NUMALPHATABS ifvarg alpha NUMALPHATABS
{ {
setvarvar tmp C2 setvarvar tmp C2