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:
helixhorned 2014-02-09 19:22:35 +00:00
parent 075d817ed7
commit 846fcdf31c
4 changed files with 155 additions and 23 deletions

View file

@ -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)

View file

@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -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

View file

@ -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