diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 11c1d8bf6..fcd27f7fd 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -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<= 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< 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 [[ - -<______________________________________________________> + +<___________________________________________________________________> Writes out a full PALETTE.DAT-formatted file named with the base shade table numbered and the base translucency table numbered . 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, . Since alpha +blending tables are assumed to be set up at indices 1 to 2^, +it is also the log2 of their total count. ]] ) diff --git a/polymer/eduke32/source/lunatic/test/sprite_access.con b/polymer/eduke32/source/lunatic/test/sprite_access.con index 334a8324e..58b1197a5 100644 --- a/polymer/eduke32/source/lunatic/test/sprite_access.con +++ b/polymer/eduke32/source/lunatic/test/sprite_access.con @@ -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