Subversion Repositories eduke32

Rev

Rev 4242 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4236 helixhorne 1
 
2
local ffi = require("ffi")
3
local C = ffi.C
4
 
5
local bcarray = require("bcarray")
6
 
7
local error = error
8
local type = type
9
 
10
local decl = assert(decl)  -- comes from above (defs.ilua or defs_m32.lua)
11
 
12
local ismapster32 = (C.LUNATIC_CLIENT == C.LUNATIC_CLIENT_MAPSTER32)
13
 
14
----------
15
 
16
decl[[
17
int32_t getclosestcol(int32_t r, int32_t g, int32_t b);
18
char *palookup[256];  // MAXPALOOKUPS
19
uint8_t palette[768];
20
 
21
int32_t setpalookup(int32_t palnum, const uint8_t *shtab);
22
]]
23
 
24
----------
25
 
26
-- The API table
27
local engine = {}
28
 
29
local pal256_t = bcarray.new("uint8_t", 256, "shade table 256-tuple")
30
-- The shade table type, effectively a bound-checked uint8_t [32][256]:
31
local shtab_t = bcarray.new(pal256_t, 32, "shade table")
32
local SIZEOF_SHTAB = ffi.sizeof(shtab_t)
33
 
34
local RESERVEDPALS = 8  -- KEEPINSYNC build.h: assure that ours is >= theirs
35
engine.RESERVEDPALS = RESERVEDPALS
36
 
37
local function check_palidx(i)
38
    if (type(i) ~= "number" or not (i >= 0 and i <= 255-RESERVEDPALS)) then
39
        error("invalid argument #1: palette index must be in the range [0 .. "..255-RESERVEDPALS.."]", 3)
40
    end
41
end
42
 
43
local function err_uncommon_shade_table(ret)
44
    if (ret == -1) then
45
        error("loaded engine shade tables don't have 32 gradients of shade", 3)
46
    end
47
end
48
 
49
local function palookup_isdefault(palnum)  -- KEEPINSYNC engine.c
50
    return (C.palookup[palnum] == nil or (palnum ~= 0 and C.palookup[palnum] == C.palookup[0]))
51
end
52
 
53
function engine.shadetab()
54
    return shtab_t()
55
end
56
 
57
function engine.getshadetab(palidx)
58
    check_palidx(palidx)
59
    if (palookup_isdefault(palidx)) then
60
        return nil
61
    end
62
 
63
    local ret = C.setpalookup(palidx, nil)
64
    err_uncommon_shade_table(ret)
65
 
66
    local sht = shtab_t()
67
    ffi.copy(sht, C.palookup[palidx], SIZEOF_SHTAB)
68
    return sht
69
end
70
 
71
function engine.setshadetab(palidx, shtab)
72
    if (not ismapster32 and C.g_elFirstTime == 0) then
73
        error("setshadetab() may be run only while LUNATIC_FIRST_TIME is true", 2)
74
    end
75
 
76
    check_palidx(palidx)
77
    if (not ffi.istype(shtab_t, shtab_t)) then
78
        error("invalid argument #2: must be a shade table obtained by shadetab()", 2)
79
    end
80
 
81
    if (not ismapster32 and not palookup_isdefault(palidx)) then
82
        error("attempt to override already defined shade table", 2)
83
    end
84
 
85
    local ret = C.setpalookup(palidx, ffi.cast("uint8_t *", shtab))
86
    err_uncommon_shade_table(ret)
87
end
88
 
89
 
90
local function check_colcomp(a)
91
    if (type(a) ~= "number" or not (a >= 0 and a <= 63)) then
92
        error("color component must be in the range [0 .. 63]", 3)
93
    end
94
end
95
 
96
 
97
-- TODO: other base palettes?
98
function engine.getrgb(colidx)
99
    if (type(colidx) ~= "number" or not (colidx >= 0 and colidx <= 255)) then
100
        error("color index must be in the range [0 .. 255]", 2)
101
    end
102
 
103
    local rgbptr = C.palette + 3*colidx
104
    return rgbptr[0], rgbptr[1], rgbptr[2]
105
end
106
 
107
-- TODO: flag whether fullbrights are OK
108
function engine.nearcolor(r, g, b)
109
    check_colcomp(r)
110
    check_colcomp(g)
111
    check_colcomp(b)
112
    return C.getclosestcol(r, g, b)
113
end
114
 
115
 
116
-- Done!
117
return engine