Lunatic: remap16 method for engine.shadetab, 2nd attempt at recreating orig. one.

BUILD_LUNATIC.

git-svn-id: https://svn.eduke32.com/eduke32@4242 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2014-01-05 14:06:14 +00:00
parent ca955899b0
commit 9e968b0093
3 changed files with 138 additions and 7 deletions

View file

@ -19,7 +19,7 @@ local pairs = pairs
local type = type
module(...)
local bcarray = {}
-- Generate C decl for a sequence of <nelts> const struct members.
@ -54,8 +54,9 @@ end
-- named _a1, _a2, ...
-- It also may be a table containing member names at numeric indices 1..#rng.
-- <mtadd>: A table containing functions __index and/or __newindex. They are
-- called first and the bound-checking ones are tail-called then.
function new(basetype, numelts, showname, typename, rng, mtadd)
-- called first and the bound-checking ones are tail-called then. If the
-- custom __index one returns something, it is returned by the composite one.
function bcarray.new(basetype, numelts, showname, typename, rng, mtadd)
local eltptr_t = ffi.typeof("$ *", ffi.typeof(basetype))
local mt = {
@ -83,7 +84,10 @@ function new(basetype, numelts, showname, typename, rng, mtadd)
if (addindexf) then
-- Additional __index metamethod given.
mt.__index = function(ar, idx)
addindexf(ar, idx)
local sth = addindexf(ar, idx)
if (sth ~= nil) then
return sth
end
return curindexf(ar, idx)
end
end
@ -115,3 +119,6 @@ function new(basetype, numelts, showname, typename, rng, mtadd)
return bcarray_t
end
return bcarray

View file

@ -23,12 +23,59 @@ int32_t setpalookup(int32_t palnum, const uint8_t *shtab);
----------
-- The API table
local engine = {}
local shtab_t -- forward-decl
local function cast_u8ptr(pal256)
return ffi.cast("uint8_t *", pal256)
end
local shtab_methods = {
-- Remap consecutive blocks of 16 color indices and return this new shade
-- table.
--
-- <idxs16>: table with idxs16[1] .. idxs16[16] >= 1 and <= 16
-- (i.e. 1-based indices of such 16-tuples)
--
-- For example, the table
-- { [0]=0,1, 2,3, 5,4, 6,7, 8,13, 10,11, 12,9, 14,15 }
-- TODO (...)
remap16 = function(sht, idxs16)
if (type(idxs16) ~= "table" or idxs16[0]==nil or #idxs16 ~= 15) then
error("invalid argument #2: must be a [0]-table with 16 elements", 2)
end
for i=0,15 do
if (not (idxs16[i] >= 0 and idxs16[i] <= 15)) then
error("invalid reordering table: elements must be in [0 .. 15]", 2)
end
end
local newsht = shtab_t()
for sh=0,31 do
for i=0,15 do
ffi.copy(cast_u8ptr(newsht[sh]) + 16*i,
cast_u8ptr(sht[sh]) + 16*idxs16[i], 16)
end
end
return newsht
end,
}
local function shtab_mt__index(sht, idx)
local method = shtab_methods[idx]
if (method) then
return method
end
end
local pal256_t = bcarray.new("uint8_t", 256, "shade table 256-tuple")
-- The shade table type, effectively a bound-checked uint8_t [32][256]:
local shtab_t = bcarray.new(pal256_t, 32, "shade table")
shtab_t = bcarray.new(pal256_t, 32, "shade table", nil, nil, { __index = shtab_mt__index })
local SIZEOF_SHTAB = ffi.sizeof(shtab_t)
local RESERVEDPALS = 8 -- KEEPINSYNC build.h: assure that ours is >= theirs

View file

@ -11,6 +11,7 @@ local error = error
local math = require("math")
local min, max = math.min, math.max
local floor = math.floor
local sector, wall, sprite = sector, wall, sprite
@ -155,10 +156,86 @@ local function create_base_shtab(basesht)
return sht
end
local function create_base_shtab_2(basesht)
local basesht = basesht or engine.getshadetab(0)
local perm16 = { [0]=0,1, 2,3, 5,4, 6,7, 8,13, 10,11, 12,9, 14,15 }
local sht = engine.shadetab():remap16(perm16)
local iperm16 = {}
for i=0,15 do
iperm16[perm16[i]] = i
end
local iperm = {}
for i=0,255 do
iperm[i] = 16*(iperm16[floor(i/16)]) + i%16
end
local baseidx = {}
for i=0,255-16 do
baseidx[i] = i < 192 and 32*floor(i/32) or 16*floor(i/16)
end
for sh=0,31 do
for i=0,255-16 do
local bi = baseidx[i]
local cidx = bi + floor(((31-sh)*(i - bi))/31)
sht[sh][i] = iperm[cidx]
end
for i=255-16+1,255 do
-- fullbrights
sht[sh][i] = basesht[0][i]
end
end
return sht:remap16(iperm16)
end
if (gv.LUNATIC_CLIENT == gv.LUNATIC_CLIENT_MAPSTER32) then
-- NOTE: It shouldn't be assumed that these will stay loadable in the future:
local ffi = require("ffi")
local io = require("io")
ffi.cdef[[size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, void * restrict stream);]]
function shadexfog.save(filename, palnum_or_sht)
local sht = type(palnum_or_sht)~="number" and palnum_or_sht
or engine.getshadetab(palnum_or_sht)
if (sht == nil) then
error("No such shade table")
end
local f, errmsg = io.open(filename, "w+")
if (f == nil) then
error(errmsg, 2)
end
-- XXX: ought to be in engine.lua
local basepal = ffi.new("uint8_t [256][3]")
for i=0,255 do
local r, g, b = engine.getrgb(i)
basepal[i][0], basepal[i][1], basepal[i][2] = r, g, b
end
local n1 = ffi.C.fwrite(basepal, 3, 256, f)
f:write("\032\000")
local n3 = ffi.C.fwrite(sht, 256, 32, f)
f:close()
if (n1 ~= 256 or n3 ~= 32) then
error("didn't fully write out palette file")
end
printf("Wrote base palette + shade table (but NOT transluc table) to '%s'", filename)
end
end
-- Create our (failed) version of the base shade table at set it to palookup
-- number <palnum>.
function shadexfog.create0(palnum)
local sht0 = create_base_shtab()
-- <secver>: use second attempt?
function shadexfog.create0(palnum, secver)
local sht0 = secver and create_base_shtab_2() or create_base_shtab()
engine.setshadetab(palnum, sht0)
end