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
//
// blendtable[1] to blendtable[numalphatabs] are considered to be
// alpha-blending tables:
static uint8_t numalphatabs;
static char *blendtable[MAXBLENDTABS];
void setblendtab(int32_t blend, const char *tab);
#define getblendtab(blend) (blendtable[blend])
@ -5609,6 +5613,29 @@ static void drawsprite_opengl(int32_t snum)
//============================================================================= //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)
{
int32_t xoff, yoff, xspan, yspan;
@ -5627,6 +5654,9 @@ static void drawsprite_classic(int32_t snum)
int32_t tilenum;
int32_t cstat = tspr->cstat;
uint8_t blendidx = tspr->blend;
float alpha = spriteext[spritenum].alpha;
if (sec == NULL)
return;
@ -5635,13 +5665,17 @@ static void drawsprite_classic(int32_t snum)
DO_TILE_ANIM(tspr->picnum, spritenum+32768);
#ifdef USE_OPENGL
if (alpha > 0.0f)
{
// hack pending proper alpha implentation
// TODO: a real implementation
float alpha = spriteext[spritenum].alpha;
if (alpha >= 1.0f)
return;
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
cstat |= 512;
@ -5649,17 +5683,11 @@ static void drawsprite_classic(int32_t snum)
cstat |= 2;
if (alpha >= 0.66f)
{
cstat |= 512;
if (alpha >= 1.0f)
return;
}
tspr->cstat = cstat;
}
}
#endif
tilenum = tspr->picnum;
@ -5689,7 +5717,7 @@ static void drawsprite_classic(int32_t snum)
globalshade = tspr->shade;
if (cstat&2)
setup_blend(tspr->blend, cstat&512);
setup_blend(blendidx, cstat&512);
xoff = picanm[tilenum].xofs + tspr->xoffset;
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;
palookupoffs = FP_OFF(palookup[dapalnum]) + (getpalookup(0, dashade)<<8);
// hack pending proper alpha implentation
// TODO: a real implementation
if (daalpha > 84) // if alpha is 0 (which is the default) this structure should only necessitate one comparison
// Alpha handling
if (daalpha > 0)
{
if ((dastat & RS_TRANS1) && daalpha > 127) // this covers the multiplicative aspect used in the Polymodes
dastat |= RS_TRANS2;
if (daalpha == 255)
return;
dastat |= RS_TRANS1;
if (daalpha > 168)
if (numalphatabs != 0)
{
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)
return;
dastat |= RS_TRANS1;
if (daalpha > 168)
dastat |= RS_TRANS2;
}
}
@ -8102,6 +8134,18 @@ static int32_t loadpalette(void)
}
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
end
-- ok, errmsg, nummoreblends = engine.savePaletteDat(filename [, palnum [, blendnum [, moreblends]]])
function engine.savePaletteDat(filename, palnum, blendnum, moreblends)
-- ok, errmsg, nummoreblends = engine.savePaletteDat(
-- filename [, palnum [, blendnum [, moreblends [, lognumalphatabs]]]])
function engine.savePaletteDat(filename, palnum, blendnum, moreblends, lognumalphatabs)
local sht = engine.getshadetab(palnum or 0)
local tab = engine.getblendtab(blendnum or 0)
@ -313,6 +314,10 @@ if (ismapster32) then
local blendnumtab, blendptrtab = validate_more_blendtabs(
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+")
if (f == nil) then
return nil, errmsg
@ -337,6 +342,12 @@ if (ismapster32) then
return nil, "failed writing additional blending table"
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
f:close()

View file

@ -178,6 +178,15 @@ onevent EVENT_DISPLAYREST
xorvar f TEXT_UPPERCASE
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
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
-- Wrapper around engine.savePaletteDat() that errors on unexpected events.
function shadexfog.save(filename, palnum, blendnum, moreblends)
local ok, errmsg, nummoreblends = engine.savePaletteDat(filename, palnum, blendnum, moreblends)
function shadexfog.save(filename, palnum, blendnum, moreblends, lognumalphatabs)
local ok, errmsg, nummoreblends = engine.savePaletteDat(
filename, palnum, blendnum, moreblends, lognumalphatabs)
if (not ok) then
error(errmsg)
end
@ -730,20 +731,31 @@ engine.registerMenuFunc(
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,
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
base shade table numbered <palnum> and the base translucency table
numbered <blendnum>.
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 C2 257 // must be 2*NUMALPHATABS+1
define ALPHA_TABS_BY_EDUKE32 1 // assume alpha->blend handling by EDuke32
onevent EVENT_ANIMATESPRITES
setvarvar tmp totalclock
shiftvarl tmp 2
@ -89,6 +91,15 @@ onevent EVENT_ANIMATESPRITES
addvar alpha 128 // [0 .. 256]
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
{
// clear translucent bits, 0xfdfe == 0xffff-(1+512)
@ -103,7 +114,7 @@ onevent EVENT_ANIMATESPRITES
settspr[THISACTOR].tsprcstat tmp
// 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
{
setvarvar tmp C2