diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index c26bba363..4e98af272 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -79,6 +79,7 @@ enum rendmode_t { #define MAXPLAYERS 16 #define MAXBASEPALS 8 #define MAXPALOOKUPS 256 +#define MAXBLENDTABS 256 // Maximum number of defined multi-pskies: #define MAXPSKYMULTIS 8 // Maximum number of component tiles in a multi-psky: @@ -760,6 +761,7 @@ EXTERN int16_t sintable[2048]; EXTERN uint8_t palette[768]; EXTERN int16_t numshades; EXTERN char *palookup[MAXPALOOKUPS]; +EXTERN char *blendtable[MAXBLENDTABS]; EXTERN uint8_t **basepaltableptr; EXTERN char showinvisibility; EXTERN int32_t g_visibility, parallaxvisibility; diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 6ab960b18..740da4ec3 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -2333,6 +2333,7 @@ static int32_t *horizlookup=0, *horizlookup2=0; int32_t globalposx, globalposy, globalposz, globalhoriz; int16_t globalang, globalcursectnum; int32_t globalpal, cosglobalang, singlobalang; +static int32_t globalblend; int32_t cosviewingrangeglobalang, sinviewingrangeglobalang; static char *globalpalwritten; static int32_t globaluclip, globaldclip; @@ -2364,7 +2365,6 @@ int16_t sectorborder[256], sectorbordercnt; int32_t ydim16, qsetmode = 0; int16_t pointhighlight=-1, linehighlight=-1, highlightcnt=0; static int32_t lastx[MAXYDIM]; -static char *transluc; static char paletteloaded = 0; @@ -2469,7 +2469,8 @@ char palfadedelta = 0; // // Internal Engine Functions // -//int32_t cacheresets = 0,cacheinvalidates = 0; + +#define getblendtab(blend) (blendtable[blend]) static void setpalettefade_calc(uint8_t offset); @@ -2488,7 +2489,7 @@ void fade_screen_black(int32_t moreopaquep) begindrawing(); { char *const p = (char *)frameplace; - const char *const trans = transluc; + const char *const trans = getblendtab(0); const int32_t shiftamnt = ((!!moreopaquep)*8); const int32_t dimprod = xdim*ydim; @@ -4123,7 +4124,7 @@ static void nonpow2_thline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_ const char *const buf = (char *)bufplc; const char *const pal = (char *)asm3; - const char *const trans = transluc; + const char *const trans = getblendtab(globalblend); const uint32_t xdiv = globalxspan > 1 ? (uint32_t)ourdivscale32(1, globalxspan) : UINT32_MAX; const uint32_t ydiv = globalyspan > 1 ? (uint32_t)ourdivscale32(1, globalyspan) : UINT32_MAX; @@ -4249,7 +4250,7 @@ static void tslopevlin(uint8_t *p, int32_t i, const intptr_t *slopalptr, int32_t { const char *const buf = ggbuf; const char *const pal = ggpal; - const char *const trans = transluc; + const char *const trans = getblendtab(0); const int32_t bzinc = (asm1>>3), pinc = ggpinc; const int32_t transmode = (globalorientation&128); @@ -5589,6 +5590,18 @@ static void drawsprite_opengl(int32_t snum) //============================================================================= //POLYMOST ENDS } +static void setup_blend(int32_t blend) +{ + if (blendtable[blend] == NULL) + blend = 0; + + if (globalblend != blend) + { + globalblend = blend; + fixtransluscence(FP_OFF(getblendtab(blend))); + } +} + static void drawsprite_classic(int32_t snum) { int32_t xoff, yoff, xspan, yspan; @@ -5668,6 +5681,8 @@ static void drawsprite_classic(int32_t snum) if (palookup[globalpal] == NULL) globalpal = 0; // JBF: fixes null-pointer crash globalshade = tspr->shade; + setup_blend(tspr->filler); + if (cstat&2) { if (cstat&512) settransreverse(); else settransnormal(); @@ -7981,6 +7996,7 @@ static int32_t loadpalette_err(const char *msg) static int32_t loadpalette(void) { int32_t fil, lamedukep=0; + char *transluc; if (paletteloaded != 0) return 0; if ((fil = kopen4load("palette.dat",0)) == -1) @@ -8001,6 +8017,7 @@ static int32_t loadpalette(void) globalpalwritten = palookup[0]; globalpal = 0; setpalookupaddress(globalpalwritten); + blendtable[0] = transluc; fixtransluscence(FP_OFF(transluc)); // Auto-detect LameDuke. Its PALETTE.DAT doesn't have a 'numshades' 16-bit @@ -8719,8 +8736,6 @@ void uninitengine(void) { int32_t i; - //OSD_Printf("cacheresets = %d, cacheinvalidates = %d\n", cacheresets, cacheinvalidates); - #ifdef USE_OPENGL polymost_glreset(); hicinit(); @@ -8737,7 +8752,6 @@ void uninitengine(void) for (i=0; i= theirs engine.RESERVEDPALS = RESERVEDPALS +local MAXBLENDTABS = 256 -- KEEPINSYNC build.h + local function check_palidx(i) if (type(i) ~= "number" or not (i >= 0 and i <= 255-RESERVEDPALS)) then error("invalid argument #1: palette swap index must be in the range [0 .. "..255-RESERVEDPALS.."]", 3) end end +local function check_blendidx(i) + if (type(i) ~= "number" or not (i >= 0 and i <= MAXBLENDTABS-1)) then + error("invalid argument #1: blending table index must be in the range [0 .. ".. MAXBLENDTABS-1 .."]", 3) + end +end + local function err_uncommon_shade_table(ret) if (ret == -1) then error("loaded engine shade tables don't have 32 gradients of shade", 3) @@ -101,6 +115,10 @@ function engine.shadetab() return shtab_t() end +function engine.blendtab() + return blendtab_t() +end + function engine.getshadetab(palidx) check_palidx(palidx) if (palookup_isdefault(palidx)) then @@ -115,13 +133,31 @@ function engine.getshadetab(palidx) return sht end -function engine.setshadetab(palidx, shtab) - if (not ismapster32 and C.g_elFirstTime == 0) then - error("setshadetab() may be run only while LUNATIC_FIRST_TIME is true", 2) +function engine.getblendtab(blendidx) + check_blendidx(blendidx) + + local ptr = C.getblendtab(blendidx) + if (ptr == nil) then + return nil end + local tab = blendtab_t() + ffi.copy(tab, ptr, SIZEOF_BLENDTAB) + return tab +end + + +local function check_first_time() + if (not ismapster32 and C.g_elFirstTime == 0) then + error("may be called only while LUNATIC_FIRST_TIME is true", 3) + end +end + +function engine.setshadetab(palidx, shtab) + check_first_time() check_palidx(palidx) - if (not ffi.istype(shtab_t, shtab_t)) then + + if (not ffi.istype(shtab_t, shtab)) then error("invalid argument #2: must be a shade table obtained by shadetab()", 2) end @@ -129,10 +165,25 @@ function engine.setshadetab(palidx, shtab) error("attempt to override already defined shade table", 2) end - local ret = C.setpalookup(palidx, ffi.cast("uint8_t *", shtab)) + local ret = C.setpalookup(palidx, cast_u8ptr(shtab)) err_uncommon_shade_table(ret) end +function engine.setblendtab(blendidx, tab) + check_first_time() + check_blendidx(blendidx) + + if (not ffi.istype(blendtab_t, tab)) then + error("invalid argument #2: must be a blending table obtained by blendtab()", 2) + end + + if (not ismapster32 and C.getblendtab(blendidx) ~= nil) then + error("attempt to override already defined blending table", 2) + end + + C.setblendtab(blendidx, cast_u8ptr(tab)) +end + local function check_colcomp(a) if (type(a) ~= "number" or not (a >= 0 and a <= 63)) then @@ -147,6 +198,15 @@ function engine.getrgb(colidx) error("color index must be in the range [0 .. 255]", 2) end + -- NOTE: In the game, palette[255*{0..2}] is set to 0 in + -- G_LoadExtraPalettes() via G_Startup(). However, that's after Lua state + -- initialization (i.e. when LUNATIC_FIRST_TIME would be true), and in the + -- editor, it's never changed from the purple color. Therefore, I think + -- it's more useful to always return the fully black color here. + if (colidx == 255) then + return 0, 0, 0 + end + local rgbptr = C.palette + 3*colidx return rgbptr[0], rgbptr[1], rgbptr[2] end diff --git a/polymer/eduke32/source/lunatic/test/shadexfog.lua b/polymer/eduke32/source/lunatic/test/shadexfog.lua index 38ca89287..efbf4903b 100644 --- a/polymer/eduke32/source/lunatic/test/shadexfog.lua +++ b/polymer/eduke32/source/lunatic/test/shadexfog.lua @@ -273,6 +273,44 @@ function shadexfog.test_create0() end end +---------- Blending table tests ---------- + +function shadexfog.create_128_trans(startblendidx) + for alpha=1,128 do + local f = alpha/256 + local F = 1-f + + local tab = engine.blendtab() + + for i=0,255 do + for j=0,255 do + local r,g,b = engine.getrgb(i) + local R,G,B = engine.getrgb(j) + + tab[i][j] = engine.nearcolor(f*r+F*R, f*g+F*G, f*b+F*B) + end + end + + engine.setblendtab(startblendidx + alpha-1, tab) + end +end + +function shadexfog.create_additive_trans(blendidx) + local tab = engine.blendtab() + + for i=0,255 do + for j=0,255 do + 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)) + end + end + + engine.setblendtab(blendidx, tab) +end + + do return shadexfog end