mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
Classic: support for multiple blending tables + Lunatic interfaces.
Currently, sprite[].filler (to be renamed) selects a blending table. If none is installed with that index, the blending table at index 0 is taken (which is read from PALETTE.DAT on engine startup). Thus, for now, the non-Lunatic build will never use a custom blending table because there's no way to register one! But the functionality is there. git-svn-id: https://svn.eduke32.com/eduke32@4301 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
54c74ca78e
commit
330b744a1b
4 changed files with 147 additions and 16 deletions
|
@ -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;
|
||||
|
|
|
@ -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<MAXARTFILES_TOTAL; i++)
|
||||
DO_FREE_AND_NULL(artptrs[i]);
|
||||
|
||||
DO_FREE_AND_NULL(transluc);
|
||||
DO_FREE_AND_NULL(pic);
|
||||
DO_FREE_AND_NULL(lookups);
|
||||
|
||||
|
@ -14659,6 +14673,23 @@ static void maybe_alloc_palookup(int32_t palnum)
|
|||
}
|
||||
|
||||
#ifdef LUNATIC
|
||||
const char *(getblendtab)(int32_t blend)
|
||||
{
|
||||
return blendtable[blend];
|
||||
}
|
||||
|
||||
void setblendtab(int32_t blend, const char *tab)
|
||||
{
|
||||
if (blendtable[blend] == NULL)
|
||||
{
|
||||
blendtable[blend] = Bmalloc(256*256);
|
||||
if (blendtable[blend] == NULL)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Bmemcpy(blendtable[blend], tab, 256*256);
|
||||
}
|
||||
|
||||
int32_t setpalookup(int32_t palnum, const uint8_t *shtab)
|
||||
{
|
||||
if (numshades != 32)
|
||||
|
|
|
@ -18,6 +18,9 @@ int32_t getclosestcol(int32_t r, int32_t g, int32_t b);
|
|||
char *palookup[256]; // MAXPALOOKUPS
|
||||
uint8_t palette[768];
|
||||
|
||||
const char *getblendtab(int32_t blend);
|
||||
void setblendtab(int32_t blend, const char *tab);
|
||||
|
||||
int32_t setpalookup(int32_t palnum, const uint8_t *shtab);
|
||||
]]
|
||||
|
||||
|
@ -30,8 +33,8 @@ local engine = {}
|
|||
|
||||
local shtab_t -- forward-decl
|
||||
|
||||
local function cast_u8ptr(pal256)
|
||||
return ffi.cast("uint8_t *", pal256)
|
||||
local function cast_u8ptr(sth)
|
||||
return ffi.cast("uint8_t *", sth)
|
||||
end
|
||||
|
||||
local shtab_methods = {
|
||||
|
@ -73,20 +76,31 @@ local function shtab_mt__index(sht, idx)
|
|||
end
|
||||
end
|
||||
|
||||
local pal256_t = bcarray.new("uint8_t", 256, "shade table 256-tuple")
|
||||
local pal256_t = bcarray.new("uint8_t", 256, "color index 256-tuple")
|
||||
-- The shade table type, effectively a bound-checked uint8_t [32][256]:
|
||||
shtab_t = bcarray.new(pal256_t, 32, "shade table", nil, nil, { __index = shtab_mt__index })
|
||||
local SIZEOF_SHTAB = ffi.sizeof(shtab_t)
|
||||
|
||||
local blendtab_t = bcarray.new(pal256_t, 256, "blending table")
|
||||
local SIZEOF_BLENDTAB = ffi.sizeof(blendtab_t)
|
||||
|
||||
local RESERVEDPALS = 8 -- KEEPINSYNC build.h: assure that ours is >= 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue