mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-31 04:20:42 +00:00
Extend PALETTE.DAT format to allow carrying additional blending tables.
Lunatic: also, add an additional argument 'moreblends' to engine.savePaletteDat() and document that function. See test/shadexfog.lua for a "user-friendly" wrapper shadexfog.save() which prints success or errors. git-svn-id: https://svn.eduke32.com/eduke32@4312 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
075d817ed7
commit
846fcdf31c
4 changed files with 155 additions and 23 deletions
|
@ -2471,6 +2471,7 @@ char palfadedelta = 0;
|
|||
//
|
||||
|
||||
static char *blendtable[MAXBLENDTABS];
|
||||
void setblendtab(int32_t blend, const char *tab);
|
||||
#define getblendtab(blend) (blendtable[blend])
|
||||
|
||||
static void setpalettefade_calc(uint8_t offset);
|
||||
|
@ -8042,15 +8043,13 @@ static int32_t loadpalette(void)
|
|||
{
|
||||
int32_t i, j;
|
||||
|
||||
for (i=0; i<256; i++)
|
||||
for (i=0; i<255; i++)
|
||||
{
|
||||
// LameDuke's table doesn't have the last row or column.
|
||||
if (i == 255)
|
||||
continue;
|
||||
// NOTE: LameDuke's table doesn't have the last row or column (i==255).
|
||||
|
||||
// Read the entries above and on the diagonal, if the table is
|
||||
// thought as being row-major.
|
||||
if (kread(fil, &transluc[256*i + i], 256-i-1) < 0)
|
||||
if (kread(fil, &transluc[256*i + i], 256-i-1) != 256-i-1)
|
||||
return loadpalette_err("Failed reading LameDuke translucency table!");
|
||||
|
||||
// Duplicate the entries below the diagonal.
|
||||
|
@ -8060,8 +8059,48 @@ static int32_t loadpalette(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (kread(fil, transluc, 65536) < 0)
|
||||
int32_t i, n;
|
||||
uint8_t magic[12];
|
||||
|
||||
if (kread(fil, transluc, 65536) != 65536)
|
||||
return loadpalette_err("Failed reading translucency table!");
|
||||
|
||||
n = kread(fil, magic, (int32_t)sizeof(magic));
|
||||
if (n == (int32_t)sizeof(magic) && !Bmemcmp(magic, "MoreBlendTab", sizeof(magic)))
|
||||
{
|
||||
// Read in additional blending tables.
|
||||
uint8_t addblendtabs, blendnum;
|
||||
char *tab = (char *)Bmalloc(256*256);
|
||||
|
||||
if (tab == NULL)
|
||||
return loadpalette_err("failed allocating temporary blending table");
|
||||
|
||||
if (kread(fil, &addblendtabs, 1) != 1)
|
||||
return loadpalette_err("failed reading additional blending table count");
|
||||
|
||||
for (i=0; i<addblendtabs; i++)
|
||||
{
|
||||
static char dup_blendnum_errmsg[] = "duplicate blending table index ??? encountered";
|
||||
|
||||
if (kread(fil, &blendnum, 1) != 1)
|
||||
return loadpalette_err("failed reading additional blending table index");
|
||||
|
||||
if (getblendtab(blendnum) != NULL)
|
||||
{
|
||||
char *cp = Bstrchr(dup_blendnum_errmsg, '?');
|
||||
Bsprintf(cp, "%3d", blendnum);
|
||||
cp[3] = ' ';
|
||||
return loadpalette_err(dup_blendnum_errmsg);
|
||||
}
|
||||
|
||||
if (kread(fil, tab, 256*256) != 256*256)
|
||||
return loadpalette_err("failed reading additional blending table");
|
||||
|
||||
setblendtab(blendnum, tab);
|
||||
}
|
||||
|
||||
Bfree(tab);
|
||||
}
|
||||
}
|
||||
|
||||
kclose(fil);
|
||||
|
@ -14685,12 +14724,6 @@ 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)
|
||||
|
@ -14703,6 +14736,12 @@ void setblendtab(int32_t blend, const char *tab)
|
|||
Bmemcpy(blendtable[blend], tab, 256*256);
|
||||
}
|
||||
|
||||
#ifdef LUNATIC
|
||||
const char *(getblendtab)(int32_t blend)
|
||||
{
|
||||
return blendtable[blend];
|
||||
}
|
||||
|
||||
int32_t setpalookup(int32_t palnum, const uint8_t *shtab)
|
||||
{
|
||||
if (numshades != 32)
|
||||
|
|
|
@ -2272,6 +2272,29 @@ restrictions when running in EDuke32:
|
|||
* `setblendtab` may only be called at first initialization time, that is, when
|
||||
the value of `LUNATIC_FIRST_TIME` is *true*.
|
||||
|
||||
Mapster32-only functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
===== `engine.savePaletteDat(filename [, palnum [, blendnum [, moreblends]]])` -> `ok, errmsg`
|
||||
|
||||
Writes out a full PALETTE.DAT-formatted file named `filename` with the base
|
||||
shade table numbered `palnum` and the base translucency table numbered
|
||||
`blendnum`, both defaulting to 0.
|
||||
|
||||
Passing `moreblends` allows to specify additional blending tables to store in
|
||||
EDuke32's extended PALETTE.DAT format. These must have previously been
|
||||
registered with `engine.setblendtab`. The `moreblends` argument must be a
|
||||
sequence table with each element being either
|
||||
|
||||
* a blending table number in the range [1{nbsp}..{nbsp}255]
|
||||
* a table `t` containing a pair of such numbers, in which case it is taken to
|
||||
mean the inclusive range [`t[1]`{nbsp}..{nbsp}`t[2]`]
|
||||
|
||||
There must be no duplicate blending table numbers.
|
||||
|
||||
The function returns a status `ok` which is *true* on success and *nil* on
|
||||
failure. In the latter case, `errmsg` is a diagnostic error message.
|
||||
|
||||
|
||||
The `fs` module -- virtual file system facilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -4,6 +4,7 @@ local C = ffi.C
|
|||
|
||||
local bcarray = require("bcarray")
|
||||
|
||||
local assert = assert
|
||||
local error = error
|
||||
local type = type
|
||||
|
||||
|
@ -230,11 +231,61 @@ end
|
|||
|
||||
if (ismapster32) then
|
||||
local io = require("io")
|
||||
local math = require("math")
|
||||
local string = require("string")
|
||||
|
||||
ffi.cdef[[size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, void * restrict stream);]]
|
||||
|
||||
-- [ok, errmsg] = engine.savePaletteDat(filename [, palnum [, blendnum]])
|
||||
function engine.savePaletteDat(filename, palnum, blendnum)
|
||||
local function validate_more_blendtabs(moreblends)
|
||||
if (moreblends == nil) then
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- Additional blending tables: validate <moreblends> table.
|
||||
if (type(moreblends) ~= "table") then
|
||||
error("invalid argument #4: must be a table", 3)
|
||||
end
|
||||
|
||||
local haveblend = { [0]=true }
|
||||
local blendnumtab, blendptrtab = {}, {}
|
||||
|
||||
for i=1,#moreblends do
|
||||
local tmp = moreblends[i]
|
||||
local blendspec = (type(tmp) == "number") and { tmp, tmp } or tmp
|
||||
|
||||
if (not (type(blendspec) == "table" and #blendspec == 2)) then
|
||||
error("invalid argument #4: must contain numbers or 2-tables", 3)
|
||||
end
|
||||
|
||||
local blend1, blend2 = math.floor(blendspec[1]), math.floor(blendspec[2])
|
||||
|
||||
if (not (type(blend1)=="number" and blend1 >= 1 and blend1 <= 255 and
|
||||
type(blend2)=="number" and blend2 >= 1 and blend2 <= 255)) then
|
||||
error("invalid argument #4: blending table numbers must be in [1 .. 255]", 3)
|
||||
end
|
||||
|
||||
for bi=blend1,blend2 do
|
||||
if (haveblend[bi]) then
|
||||
error("invalid argument #4: duplicate blending table number "..bi, 3)
|
||||
end
|
||||
haveblend[bi] = true
|
||||
|
||||
local ptr = C.getblendtab(bi)
|
||||
if (ptr == nil) then
|
||||
error("invalid argument #4: blending table for number "..bi.." is void", 3)
|
||||
end
|
||||
|
||||
blendnumtab[#blendnumtab+1] = bi
|
||||
blendptrtab[#blendptrtab+1] = ptr
|
||||
end
|
||||
end
|
||||
|
||||
assert(#blendnumtab <= 255)
|
||||
return blendnumtab, blendptrtab
|
||||
end
|
||||
|
||||
-- [ok, errmsg] = engine.savePaletteDat(filename [, palnum [, blendnum [, moreblends]]])
|
||||
function engine.savePaletteDat(filename, palnum, blendnum, moreblends)
|
||||
local sht = engine.getshadetab(palnum or 0)
|
||||
local tab = engine.getblendtab(blendnum or 0)
|
||||
|
||||
|
@ -244,20 +295,35 @@ if (ismapster32) then
|
|||
return nil, "no blending table with number "..blendnum
|
||||
end
|
||||
|
||||
local blendnumtab, blendptrtab = validate_more_blendtabs(moreblends)
|
||||
|
||||
local f, errmsg = io.open(filename, "w+")
|
||||
if (f == nil) then
|
||||
return nil, errmsg
|
||||
end
|
||||
|
||||
local n1 = ffi.C.fwrite(C.palette, 3, 256, f)
|
||||
local n1 = C.fwrite(C.palette, 3, 256, f)
|
||||
f:write("\032\000") -- int16_t numshades
|
||||
local n3 = ffi.C.fwrite(sht, 256, 32, f)
|
||||
local n4 = ffi.C.fwrite(tab, 256, 256, f)
|
||||
local n3 = C.fwrite(sht, 256, 32, f)
|
||||
local n4 = C.fwrite(tab, 256, 256, f)
|
||||
|
||||
if (n1 ~= 256 or n3 ~= 32 or n4 ~= 256) then
|
||||
return nil, "failed writing classic PALETTE.DAT data"
|
||||
end
|
||||
|
||||
if (blendnumtab ~= nil) then
|
||||
f:write("MoreBlendTab")
|
||||
f:write(string.char(#blendnumtab))
|
||||
|
||||
for i=1,#blendnumtab do
|
||||
f:write(string.char(blendnumtab[i]))
|
||||
if (C.fwrite(blendptrtab[i], 256, 256, f) ~= 256) then
|
||||
return nil, "failed writing additional blending table"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
if (n1 ~= 256 or n3 ~= 32 or n4 ~= 256) then
|
||||
return nil, "failed writing enough data"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -197,12 +197,16 @@ 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)
|
||||
local ok, errmsg = engine.savePaletteDat(filename, palnum, blendnum)
|
||||
function shadexfog.save(filename, palnum, blendnum, moreblends)
|
||||
local ok, errmsg = engine.savePaletteDat(filename, palnum, blendnum, moreblends)
|
||||
if (not ok) then
|
||||
error(errmsg)
|
||||
end
|
||||
printf('Wrote base palette, shade and translucency tables to "%s"', filename)
|
||||
|
||||
printf('Wrote base palette, shade and translucency tables to "%s".', filename)
|
||||
if (moreblends ~= nil) then
|
||||
printf(" Also wrote additional translucency tables.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue