mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
Lunatic: drowning in code.
git-svn-id: https://svn.eduke32.com/eduke32@3259 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
5c06ef08bf
commit
1588a80442
8 changed files with 340 additions and 32 deletions
|
@ -9910,10 +9910,12 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice);
|
||||||
#ifdef LUNATIC
|
#ifdef LUNATIC
|
||||||
const char *g_sizes_of_what[] = {
|
const char *g_sizes_of_what[] = {
|
||||||
"sectortype", "walltype", "spritetype",
|
"sectortype", "walltype", "spritetype",
|
||||||
"actor_t", "DukePlayer_t", "playerdata_t", "user_defs" };
|
"actor_t", "DukePlayer_t", "playerdata_t",
|
||||||
|
"user_defs", "tiledata_t" };
|
||||||
int32_t g_sizes_of[] = {
|
int32_t g_sizes_of[] = {
|
||||||
sizeof(sectortype), sizeof(walltype), sizeof(spritetype),
|
sizeof(sectortype), sizeof(walltype), sizeof(spritetype),
|
||||||
sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t), sizeof(user_defs) };
|
sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t),
|
||||||
|
sizeof(user_defs), sizeof(tiledata_t) };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32_t app_main(int32_t argc, const char **argv)
|
int32_t app_main(int32_t argc, const char **argv)
|
||||||
|
|
|
@ -19,8 +19,6 @@ MAXSKILLS = 7
|
||||||
|
|
||||||
MAXSOUNDS = 4096
|
MAXSOUNDS = 4096
|
||||||
|
|
||||||
SLEEPTIME = 1536
|
|
||||||
|
|
||||||
|
|
||||||
-- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective
|
-- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective
|
||||||
-- defines. These are exported to the ffi.C namespace and as literal defines
|
-- defines. These are exported to the ffi.C namespace and as literal defines
|
||||||
|
|
|
@ -171,6 +171,20 @@ end
|
||||||
--- expose the functionality in a better fashion than merely giving access to
|
--- expose the functionality in a better fashion than merely giving access to
|
||||||
--- the C functions.)
|
--- the C functions.)
|
||||||
|
|
||||||
|
local D = {
|
||||||
|
-- TODO: dynamic tile remapping
|
||||||
|
ACTIVATOR = 2,
|
||||||
|
APLAYER = 1405,
|
||||||
|
|
||||||
|
FIRSTAID = 53,
|
||||||
|
STEROIDS = 55,
|
||||||
|
AIRTANK = 56,
|
||||||
|
JETPACK = 57,
|
||||||
|
HEATSENSOR = 59,
|
||||||
|
BOOTS = 61,
|
||||||
|
HOLODUKE = 1348,
|
||||||
|
}
|
||||||
|
|
||||||
local function check_sprite_idx(i)
|
local function check_sprite_idx(i)
|
||||||
if (i >= ffiC.MAXSPRITES+0ULL) then
|
if (i >= ffiC.MAXSPRITES+0ULL) then
|
||||||
error("invalid argument: must be a valid sprite index", 3)
|
error("invalid argument: must be a valid sprite index", 3)
|
||||||
|
@ -186,7 +200,6 @@ end
|
||||||
function _A_Shoot(i, atwith)
|
function _A_Shoot(i, atwith)
|
||||||
check_sprite_idx(i)
|
check_sprite_idx(i)
|
||||||
check_tile_idx(atwith)
|
check_tile_idx(atwith)
|
||||||
|
|
||||||
return ffiC.A_Shoot(i, atwith)
|
return ffiC.A_Shoot(i, atwith)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -235,6 +248,13 @@ function _pstomp(ps, i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _pkick(ps, spr)
|
||||||
|
-- TODO: multiplayer branch
|
||||||
|
if (spr.picnum~=D.APLAYER and ps.quick_kick==0) then
|
||||||
|
ps.quick_kick = 14
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function _VM_ResetPlayer2(snum)
|
function _VM_ResetPlayer2(snum)
|
||||||
local bound_check = player[snum]
|
local bound_check = player[snum]
|
||||||
return (ffiC.VM_ResetPlayer2(snum)~=0)
|
return (ffiC.VM_ResetPlayer2(snum)~=0)
|
||||||
|
@ -272,10 +292,10 @@ end
|
||||||
|
|
||||||
-- For GET_ACCESS: returns logical: whether player has card given by PAL
|
-- For GET_ACCESS: returns logical: whether player has card given by PAL
|
||||||
-- Else: returns inventory amount
|
-- Else: returns inventory amount
|
||||||
function _getinventory(ps, inv, pal)
|
function _getinventory(ps, inv, i)
|
||||||
if (inv == ffiC.GET_ACCESS) then
|
if (inv == ffiC.GET_ACCESS) then
|
||||||
if (PALBITS[pal]) then
|
if (PALBITS[sprite[i].pal]) then
|
||||||
return (bit.band(ps.got_access, PALBITS[pal])~=0)
|
return (bit.band(ps.got_access, PALBITS[sprite[i].pal])~=0)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
else
|
else
|
||||||
|
@ -345,9 +365,7 @@ function _operate(spritenum)
|
||||||
if (lotag==23 or sect.floorz==sect.ceilingz) then
|
if (lotag==23 or sect.floorz==sect.ceilingz) then
|
||||||
if (bit.band(lotag, 32768+16384) == 0) then
|
if (bit.band(lotag, 32768+16384) == 0) then
|
||||||
for j in spritesofsect(tag.sector) do
|
for j in spritesofsect(tag.sector) do
|
||||||
if (sprite[j].picnum==2) then
|
if (sprite[j].picnum==D.ACTIVATOR) then
|
||||||
-- TODO: ^^^ actually ACTIVATOR. Make the
|
|
||||||
-- dynamic name->tilenum mappings work.
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -381,15 +399,144 @@ function _awayfromwall(spr, d)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function krandand(mask)
|
||||||
|
return bit.band(ffiC.krand(), mask)
|
||||||
|
end
|
||||||
|
|
||||||
|
local BANG2RAD = math.pi/1024
|
||||||
|
|
||||||
|
local function cossinb(bang)
|
||||||
|
-- XXX: better use the precalc'd arrays instead?
|
||||||
|
local ang = BANG2RAD*(bang)
|
||||||
|
return 16384*math.cos(ang), 16384*math.sin(ang)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function manhatdist(v1, v2)
|
||||||
|
return math.abs(v1.x-v2.x) + math.abs(v1.y-v2.y)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- "otherspr" is either player or holoduke sprite
|
||||||
|
local function A_GetFurthestVisiblePoint(aci, otherspr)
|
||||||
|
if (bit.band(actor[aci].get_t_data(0), 63) ~= 0) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local angincs = (ud.player_skill < 3) and 1024 or 2048/(1+krandand(1))
|
||||||
|
|
||||||
|
local j = 0
|
||||||
|
repeat
|
||||||
|
local c, s = cossinb(otherspr.ang + j)
|
||||||
|
local hit = hitscan(otherspr^(16*256), otherspr.sectnum,
|
||||||
|
c, s, 16384-krandand(32767), ffiC.CLIPMASK1)
|
||||||
|
local dother = manhatdist(hit.pos, otherspr)
|
||||||
|
local dactor = manhatdist(hit.pos, spr)
|
||||||
|
|
||||||
|
if (dother < dactor and hit.sect >= 0) then
|
||||||
|
if (cansee(hit.pos, hit.sect, otherspr^(16*256), otherspr.sectnum)) then
|
||||||
|
return hit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
j = j + (angincs - krandand(511))
|
||||||
|
until (j >= 2048)
|
||||||
|
end
|
||||||
|
|
||||||
|
local SLEEPTIME = 1536
|
||||||
|
|
||||||
|
function _cansee(aci, ps)
|
||||||
|
-- Select sprite for monster to target.
|
||||||
|
local spr = sprite[aci]
|
||||||
|
local s = sprite[ps.i]
|
||||||
|
|
||||||
|
if (ps.holoduke_on) then
|
||||||
|
-- If holoduke is on, let them target holoduke first.
|
||||||
|
local hs = sprite[ps.holoduke_on]
|
||||||
|
|
||||||
|
if (cansee(spr^krandand(8191), spr.sectnum, s, s.sectnum)) then
|
||||||
|
s = hs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Can they see player (or player's holoduke)?
|
||||||
|
local can = cansee(spr^krandand(47*256), spr.sectnum, s^(24*256), s.sectnum)
|
||||||
|
|
||||||
|
if (not can) then
|
||||||
|
-- Search around for target player.
|
||||||
|
local hit = A_GetFurthestVisiblePoint(aci, s)
|
||||||
|
if (hit ~= nil) then
|
||||||
|
can = true
|
||||||
|
actor[aci].lastvx = hit.pos.x
|
||||||
|
actor[aci].lastvy = hit.pos.y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Else, they did see it. Save where we were looking...
|
||||||
|
actor[aci].lastvx = s.x
|
||||||
|
actor[aci].lastvy = s.y
|
||||||
|
end
|
||||||
|
|
||||||
|
if (can and (spr.statnum==ffiC.STAT_ACTOR or spr.statnum==ffiC.STAT_STANDABLE)) then
|
||||||
|
actor[aci].timetosleep = SLEEPTIME
|
||||||
|
end
|
||||||
|
|
||||||
|
return can
|
||||||
|
end
|
||||||
|
|
||||||
function _canseetarget(spr, ps)
|
function _canseetarget(spr, ps)
|
||||||
-- NOTE: &41 ?
|
-- NOTE: &41 ?
|
||||||
return cansee(spr^(bit.band(ffiC.krand(),41)), spr.sectnum,
|
return cansee(spr^krandand(41), spr.sectnum,
|
||||||
ps.pos, sprite[ps.i].sectnum)
|
ps.pos, sprite[ps.i].sectnum)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function A_CheckHitSprite(spr, angadd)
|
||||||
|
local zoff = (spr:isenemy() and 42*256) or (spr.picnum==D.APLAYER and 39*256) or 0
|
||||||
|
|
||||||
|
local c, s = cossinb(spr.ang+angadd)
|
||||||
|
local hit = hitscan(spr^zoff, spr.sectnum, c, s, 0, ffiC.CLIPMASK1)
|
||||||
|
if (hit.wall >= 0 and wall[hit.wall]:ismasked() and spr:isenemy()) then
|
||||||
|
return -1, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local dx = hit.pos.x-spr.x
|
||||||
|
local dy = hit.pos.y-spr.y
|
||||||
|
return hit.sprite, math.sqrt(dx*dx+dy*dy) -- TODO: use "ldist" approximation for authenticity
|
||||||
|
end
|
||||||
|
|
||||||
|
function _canshoottarget(dist, aci)
|
||||||
|
if (dist > 1024) then
|
||||||
|
local spr = sprite[aci]
|
||||||
|
|
||||||
|
local hitspr, hitdist = A_CheckHitSprite(spr, 0)
|
||||||
|
if (hitdist == nil) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local bigenemy = (spr:isenemy() and spr.xrepeat > 56)
|
||||||
|
|
||||||
|
local sclip = bigenemy and 3084 or 768
|
||||||
|
local angdif = bigenemy and 48 or 16
|
||||||
|
|
||||||
|
local sclips = { sclip, sclip, 768 }
|
||||||
|
local angdifs = { 0, angdif, -angdif }
|
||||||
|
|
||||||
|
for i=1,3 do
|
||||||
|
if (i > 1) then
|
||||||
|
hitspr, hitdist = A_CheckHitSprite(aci, angdifs[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
if (hitspr >= 0 and sprite[hitspr].picnum == spr.picnum) then
|
||||||
|
if (hitdist > sclips[i]) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
function _getlastpal(spritenum)
|
function _getlastpal(spritenum)
|
||||||
local spr = sprite[spritenum]
|
local spr = sprite[spritenum]
|
||||||
if (spr.picnum == 1405) then -- TODO: APLAYER
|
if (spr.picnum == D.APLAYER) then
|
||||||
spr.pal = player[spr.yvel].palookup
|
spr.pal = player[spr.yvel].palookup
|
||||||
else
|
else
|
||||||
if (spr.pal == 1 and spr.extra == 0) then -- hack for frozen
|
if (spr.pal == 1 and spr.extra == 0) then -- hack for frozen
|
||||||
|
@ -415,6 +562,94 @@ function _angdiffabs(a1, a2)
|
||||||
return math.abs(a2-a1)
|
return math.abs(a2-a1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local SK = {
|
||||||
|
CROUCH = 1,
|
||||||
|
RUN = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function _ifp(flags, pli, aci)
|
||||||
|
local l = flags
|
||||||
|
local ps = player[pli]
|
||||||
|
local vel = sprite[ps.i].xvel
|
||||||
|
local band = bit.band
|
||||||
|
local j = false
|
||||||
|
|
||||||
|
if (band(l,8)~=0 and ps.on_ground and _testkey(pli, SK.CROUCH)) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,16)~=0 and ps.jumping_counter == 0 and not ps.on_ground and ps.vel.z > 2048) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,32)~=0 and ps.jumping_counter > 348) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,1)~=0 and vel >= 0 and vel < 8) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,2)~=0 and vel >= 8 and not _testkey(pli, SK.RUN)) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,4)~=0 and vel >= 8 and _testkey(pli, SK.RUN)) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,64)~=0 and ps.pos.z < (sprite[_aci].z-(48*256))) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,128)~=0 and vel <= -8 and not _testkey(pli, SK.RUN)) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,256)~=0 and vel <= -8 and _testkey(pli, SK.RUN)) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,512)~=0 and (ps.quick_kick > 0 or (ps.curr_weapon == ffiC.KNEE_WEAPON and ps.kickback_pic > 0))) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,1024)~=0 and sprite[ps.i].xrepeat < 32) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,2048)~=0 and ps.jetpack_on) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,4096)~=0 and ps:get_inv_amount(ffiC.GET_STEROIDS) > 0 and ps:get_inv_amount(ffiC.GET_STEROIDS) < 400) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,8192)~=0 and ps.on_ground) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,16384)~=0 and sprite[ps.i].xrepeat > 32 and sprite[ps.i].extra > 0 and ps.timebeforeexit == 0) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,32768)~=0 and sprite[ps.i].extra <= 0) then
|
||||||
|
j = true
|
||||||
|
elseif (band(l,65536)~=0) then
|
||||||
|
-- TODO: multiplayer branch
|
||||||
|
if (_angdiffabs(ps.ang, ffiC.getangle(sprite[_aci].x-ps.pos.x, sprite[_aci].y-ps.pos.y)) < 128) then
|
||||||
|
j = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return j
|
||||||
|
end
|
||||||
|
|
||||||
|
function _checkspace(sectnum, floorp)
|
||||||
|
local sect = sector[sectnum]
|
||||||
|
local picnum = floorp and sect.floorpicnum or sect.ceilingpicnum
|
||||||
|
local stat = floorp and sect.floorstat or sect.ceilingstat
|
||||||
|
return bit.band(stat,1)~=0 and sect.ceilingpal == 0 and
|
||||||
|
(picnum==D.MOONSKY1 or picnum==D.BIGORBIT1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function _flash(spr, ps)
|
||||||
|
spr.shade = -127
|
||||||
|
ps.visibility = -127
|
||||||
|
ffiC.lastvisinc = ffiC.totalclock+32
|
||||||
|
end
|
||||||
|
|
||||||
|
local INVENTILE = {
|
||||||
|
[D.FIRSTAID] = true,
|
||||||
|
[D.STEROIDS] = true,
|
||||||
|
[D.AIRTANK] = true,
|
||||||
|
[D.JETPACK] = true,
|
||||||
|
[D.HEATSENSOR] = true,
|
||||||
|
[D.BOOTS] = true,
|
||||||
|
[D.HOLODUKE] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
function _checkrespawn(spr)
|
||||||
|
if (spr:isenemy()) then
|
||||||
|
return (ud.respawn_monsters~=0)
|
||||||
|
end
|
||||||
|
if (INVENTILE[spr.picnum]) then
|
||||||
|
return (ud.respawn_inventory~=0)
|
||||||
|
end
|
||||||
|
return (ud.respawn_items~=0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Exported functions ---
|
--- Exported functions ---
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,32 @@ typedef struct {
|
||||||
char user_name[32];
|
char user_name[32];
|
||||||
uint32_t revision;
|
uint32_t revision;
|
||||||
} playerdata_t;
|
} playerdata_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t workslike, cstat; // 8b
|
||||||
|
int32_t hitradius, range, flashcolor; // 12b
|
||||||
|
int16_t spawns, sound, isound, vel; // 8b
|
||||||
|
int16_t decal, trail, tnum, drop; // 8b
|
||||||
|
int16_t offset, bounces, bsound; // 6b
|
||||||
|
int16_t toffset; // 2b
|
||||||
|
int16_t extra, extra_rand; // 4b
|
||||||
|
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b
|
||||||
|
int8_t shade, xrepeat, yrepeat, pal; // 4b
|
||||||
|
int8_t movecnt; // 1b
|
||||||
|
uint8_t clipdist; // 1b
|
||||||
|
int8_t filler[6]; // 6b
|
||||||
|
} projectile_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
intptr_t *execPtr;
|
||||||
|
intptr_t *loadPtr;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
int16_t cacherange;
|
||||||
|
|
||||||
|
projectile_t defproj;
|
||||||
|
} tiledata_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -425,6 +451,7 @@ user_defs ud;
|
||||||
playerdata_t g_player[MAXPLAYERS];
|
playerdata_t g_player[MAXPLAYERS];
|
||||||
|
|
||||||
const int32_t playerswhenstarted;
|
const int32_t playerswhenstarted;
|
||||||
|
int32_t lastvisinc;
|
||||||
|
|
||||||
int32_t A_IncurDamage(int32_t sn); // not bound-checked!
|
int32_t A_IncurDamage(int32_t sn); // not bound-checked!
|
||||||
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap);
|
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap);
|
||||||
|
@ -455,7 +482,7 @@ string.dump = nil
|
||||||
|
|
||||||
-- sanity-check struct type sizes
|
-- sanity-check struct type sizes
|
||||||
local good = true
|
local good = true
|
||||||
for i=0,6 do
|
for i=0,7 do
|
||||||
local what = ffi.string(ffiC.g_sizes_of_what[i])
|
local what = ffi.string(ffiC.g_sizes_of_what[i])
|
||||||
local fsz = ffi.sizeof(what)
|
local fsz = ffi.sizeof(what)
|
||||||
local csz = ffiC.g_sizes_of[i]
|
local csz = ffiC.g_sizes_of[i]
|
||||||
|
@ -469,6 +496,12 @@ if (not good) then
|
||||||
error("Some sizes don't match between C and LuaJIT/FFI.")
|
error("Some sizes don't match between C and LuaJIT/FFI.")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add game-side metamethods to "spritetype" and register it with "metatype"
|
||||||
|
defs_c.spritetype_mt.__index.isenemy = function(s)
|
||||||
|
return (bit.band(ffiC.g_tile[s.picnum], ffiC.SFLAG_BADGUY)~=0)
|
||||||
|
end
|
||||||
|
ffi.metatype("spritetype", defs_c.spritetype_mt)
|
||||||
|
|
||||||
-- "player" global, needed by the "control" module
|
-- "player" global, needed by the "control" module
|
||||||
local tmpmt = {
|
local tmpmt = {
|
||||||
__index = function(tab, key)
|
__index = function(tab, key)
|
||||||
|
@ -631,6 +664,14 @@ local actor_mt = {
|
||||||
return (a.t_data[5]==ai)
|
return (a.t_data[5]==ai)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-- Getters/setters.
|
||||||
|
get_t_data = function(a, idx)
|
||||||
|
if (idx >= 10ULL) then
|
||||||
|
error("Invalid t_data index "..idx, 2)
|
||||||
|
end
|
||||||
|
return ffi.cast(actor_ptr_ct, a).t_data[idx]
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ffi.metatype("actor_t", actor_mt)
|
ffi.metatype("actor_t", actor_mt)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
local ffi = require("ffi")
|
local ffi = require("ffi")
|
||||||
local ffiC = ffi.C
|
local ffiC = ffi.C
|
||||||
|
|
||||||
|
local bit = require("bit")
|
||||||
local string = require("string")
|
local string = require("string")
|
||||||
|
|
||||||
local error = error
|
local error = error
|
||||||
|
@ -236,9 +237,30 @@ local ivec3_mt = {
|
||||||
}
|
}
|
||||||
ivec3_ = ffi.metatype("vec3_t", ivec3_mt)
|
ivec3_ = ffi.metatype("vec3_t", ivec3_mt)
|
||||||
|
|
||||||
|
local walltype_mt = {
|
||||||
|
__index = {
|
||||||
|
isblocking = function(w)
|
||||||
|
return (bit.band(w.cstat, 1)~=0)
|
||||||
|
end,
|
||||||
|
|
||||||
|
ismasked = function(w)
|
||||||
|
return (bit.band(w.cstat, 16)~=0)
|
||||||
|
end,
|
||||||
|
|
||||||
|
isoneway = function(w)
|
||||||
|
return (bit.band(w.cstat, 32)~=0)
|
||||||
|
end,
|
||||||
|
|
||||||
|
ishittable = function(w)
|
||||||
|
return (bit.band(w.cstat, 64)~=0)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffi.metatype("walltype", walltype_mt)
|
||||||
|
|
||||||
local spritetype_ptr_ct = ffi.typeof("spritetype_u_t *")
|
local spritetype_ptr_ct = ffi.typeof("spritetype_u_t *")
|
||||||
|
|
||||||
local spritetype_mt = {
|
spritetype_mt = {
|
||||||
__pow = function(s, zofs)
|
__pow = function(s, zofs)
|
||||||
return ivec3_(s.x, s.y, s.z-zofs)
|
return ivec3_(s.x, s.y, s.z-zofs)
|
||||||
end,
|
end,
|
||||||
|
@ -252,7 +274,8 @@ local spritetype_mt = {
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ffi.metatype("spritetype", spritetype_mt)
|
-- The user of this module can insert additional "spritetype" metamethods and
|
||||||
|
-- register them with "ffi.metatype".
|
||||||
|
|
||||||
|
|
||||||
---=== Restricted access to C variables from Lunatic ===---
|
---=== Restricted access to C variables from Lunatic ===---
|
||||||
|
|
|
@ -7,6 +7,7 @@ local ffiC = ffi.C
|
||||||
--== First, load the definitions common to the game's and editor's Lua interface.
|
--== First, load the definitions common to the game's and editor's Lua interface.
|
||||||
decl = ffi.cdef
|
decl = ffi.cdef
|
||||||
local defs_c = require("defs_common")
|
local defs_c = require("defs_common")
|
||||||
|
ffi.metatype("spritetype", defs_c.spritetype_mt)
|
||||||
|
|
||||||
defs_c.create_globals(_G)
|
defs_c.create_globals(_G)
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ ud;
|
||||||
g_player;
|
g_player;
|
||||||
|
|
||||||
playerswhenstarted;
|
playerswhenstarted;
|
||||||
|
lastvisinc;
|
||||||
|
|
||||||
luaJIT_BC_lunacon;
|
luaJIT_BC_lunacon;
|
||||||
luaJIT_BC_con_lang;
|
luaJIT_BC_con_lang;
|
||||||
|
|
|
@ -9,6 +9,7 @@ local math = require("math")
|
||||||
local string = require("string")
|
local string = require("string")
|
||||||
local table = require("table")
|
local table = require("table")
|
||||||
|
|
||||||
|
|
||||||
local arg = arg
|
local arg = arg
|
||||||
|
|
||||||
local assert = assert
|
local assert = assert
|
||||||
|
@ -612,7 +613,8 @@ local Co = {
|
||||||
setgamename = newline_term_string,
|
setgamename = newline_term_string,
|
||||||
|
|
||||||
precache = cmd(D,D,D),
|
precache = cmd(D,D,D),
|
||||||
scriptsize = cmd(D), -- unused
|
scriptsize = cmd(D)
|
||||||
|
/ "", -- no-op
|
||||||
cheatkeys = cmd(D,D),
|
cheatkeys = cmd(D,D),
|
||||||
|
|
||||||
definecheat = newline_term_string, -- XXX: actually tricker syntax (TS)
|
definecheat = newline_term_string, -- XXX: actually tricker syntax (TS)
|
||||||
|
@ -713,6 +715,11 @@ local function handle_palfrom(...)
|
||||||
v[1] or 0, v[2] or 0, v[3] or 0, v[4] or 0)
|
v[1] or 0, v[2] or 0, v[3] or 0, v[4] or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function handle_move(mv, ...)
|
||||||
|
local flags = {...}
|
||||||
|
return format(ACS":set_move(%s,%d)", mv, (flags[1] and bit.bor(...)) or 0)
|
||||||
|
end
|
||||||
|
|
||||||
-- NOTE about prefixes: most is handled by all_alt_pattern(), however commands
|
-- NOTE about prefixes: most is handled by all_alt_pattern(), however commands
|
||||||
-- that have no arguments and that are prefixes of other commands MUST be
|
-- that have no arguments and that are prefixes of other commands MUST be
|
||||||
-- suffixed with a "* #sp1" pattern.
|
-- suffixed with a "* #sp1" pattern.
|
||||||
|
@ -799,9 +806,8 @@ local Ci = {
|
||||||
/ ACS":set_action(%1)",
|
/ ACS":set_action(%1)",
|
||||||
ai = cmd(AI)
|
ai = cmd(AI)
|
||||||
/ ACS":set_ai(%1)",
|
/ ACS":set_ai(%1)",
|
||||||
-- TODO: move's flags
|
|
||||||
move = sp1 * t_move * (sp1 * t_define)^0
|
move = sp1 * t_move * (sp1 * t_define)^0
|
||||||
/ ACS":set_move(%1)",
|
/ handle_move,
|
||||||
|
|
||||||
cactor = cmd(D)
|
cactor = cmd(D)
|
||||||
/ SPS":set_picnum(%1)",
|
/ SPS":set_picnum(%1)",
|
||||||
|
@ -876,7 +882,8 @@ local Ci = {
|
||||||
/ (PLS".actors_killed="..PLS".actors_killed+%1;"..ACS".actorstayput=-1"),
|
/ (PLS".actors_killed="..PLS".actors_killed+%1;"..ACS".actorstayput=-1"),
|
||||||
addphealth = cmd(D)
|
addphealth = cmd(D)
|
||||||
/ "", -- TODO
|
/ "", -- TODO
|
||||||
angoff = cmd(D),
|
angoff = cmd(D)
|
||||||
|
/ "spritext[_aci].angoff=%1",
|
||||||
debug = cmd(D)
|
debug = cmd(D)
|
||||||
/ "", -- TODO?
|
/ "", -- TODO?
|
||||||
endofgame = cmd(D)
|
endofgame = cmd(D)
|
||||||
|
@ -916,7 +923,8 @@ local Ci = {
|
||||||
|
|
||||||
fall = cmd()
|
fall = cmd()
|
||||||
/ "_con._VM_FallSprite(_aci)",
|
/ "_con._VM_FallSprite(_aci)",
|
||||||
flash = cmd(),
|
flash = cmd()
|
||||||
|
/ format("_con._flash(%s,%s)", ACS"", SPS""),
|
||||||
getlastpal = cmd()
|
getlastpal = cmd()
|
||||||
/ "_con._getlastpal(_aci)",
|
/ "_con._getlastpal(_aci)",
|
||||||
insertspriteq = cmd(),
|
insertspriteq = cmd(),
|
||||||
|
@ -926,7 +934,7 @@ local Ci = {
|
||||||
nullop = cmd()
|
nullop = cmd()
|
||||||
/ "", -- NOTE: really generate no code
|
/ "", -- NOTE: really generate no code
|
||||||
pkick = cmd()
|
pkick = cmd()
|
||||||
/ "", -- TODO
|
/ format("_con._pkick(%s,%s)", PLS"", ACS""),
|
||||||
pstomp = cmd()
|
pstomp = cmd()
|
||||||
/ PLS":pstomp(_aci)",
|
/ PLS":pstomp(_aci)",
|
||||||
resetactioncount = cmd()
|
resetactioncount = cmd()
|
||||||
|
@ -1119,10 +1127,8 @@ local Cif = {
|
||||||
ifsound = cmd(D)
|
ifsound = cmd(D)
|
||||||
/ "",
|
/ "",
|
||||||
-- vvv TODO: this is not correct for GET_ACCESS or GET_SHIELD.
|
-- vvv TODO: this is not correct for GET_ACCESS or GET_SHIELD.
|
||||||
-- Additionally, it accesses the current sprite unconditinally
|
|
||||||
-- (will throw error if invalid).
|
|
||||||
ifpinventory = cmd(D,D)
|
ifpinventory = cmd(D,D)
|
||||||
/ format("_con._getinventory(%s,%%1,%s)~=%%2", PLS"", SPS".pal"),
|
/ format("_con._getinventory(%s,%%1,_aci)~=%%2", PLS""),
|
||||||
|
|
||||||
ifvarl = cmd(R,D),
|
ifvarl = cmd(R,D),
|
||||||
ifvarg = cmd(R,D),
|
ifvarg = cmd(R,D),
|
||||||
|
@ -1145,12 +1151,12 @@ local Cif = {
|
||||||
ifactorsound = cmd(R,R),
|
ifactorsound = cmd(R,R),
|
||||||
|
|
||||||
ifp = (sp1 * t_define)^1
|
ifp = (sp1 * t_define)^1
|
||||||
/ "false", -- TODO
|
/ function (...) return format("_con._ifp(%d,_pli,_aci)", bit.bor(...)) end,
|
||||||
ifsquished = cmd()
|
ifsquished = cmd()
|
||||||
/ "false", -- TODO
|
/ "false", -- TODO
|
||||||
ifserver = cmd(),
|
ifserver = cmd(),
|
||||||
ifrespawn = cmd()
|
ifrespawn = cmd()
|
||||||
/ "false", -- TODO
|
/ format("_con._checkrespawn(%s)", SPS""),
|
||||||
ifoutside = cmd()
|
ifoutside = cmd()
|
||||||
/ format("_bit.band(sector[%s].ceilingstat,1)~=0", SPS".sectnum"),
|
/ format("_bit.band(sector[%s].ceilingstat,1)~=0", SPS".sectnum"),
|
||||||
ifonwater = cmd()
|
ifonwater = cmd()
|
||||||
|
@ -1164,9 +1170,9 @@ local Cif = {
|
||||||
ifinwater = cmd()
|
ifinwater = cmd()
|
||||||
/ format("sector[%s].lotag==2", SPS".sectnum"),
|
/ format("sector[%s].lotag==2", SPS".sectnum"),
|
||||||
ifinspace = cmd()
|
ifinspace = cmd()
|
||||||
/ "false", -- TODO
|
/ format("_con._checkspace(%s,false)", SPS".sectnum"),
|
||||||
ifinouterspace = cmd()
|
ifinouterspace = cmd()
|
||||||
/ "false", -- TODO
|
/ format("_con._checkspace(%s,true)", SPS".sectnum"),
|
||||||
ifhitweapon = cmd()
|
ifhitweapon = cmd()
|
||||||
/ "_con._A_IncurDamage(_aci)",
|
/ "_con._A_IncurDamage(_aci)",
|
||||||
ifhitspace = cmd()
|
ifhitspace = cmd()
|
||||||
|
@ -1175,10 +1181,11 @@ local Cif = {
|
||||||
/ SPS".extra<=0",
|
/ SPS".extra<=0",
|
||||||
ifclient = cmd(),
|
ifclient = cmd(),
|
||||||
ifcanshoottarget = cmd()
|
ifcanshoottarget = cmd()
|
||||||
/ "false", -- TODO
|
/ "_con._canshoottarget(_dist,_aci)",
|
||||||
ifcanseetarget = cmd() -- TODO: maybe set timetosleep afterwards
|
ifcanseetarget = cmd() -- TODO: maybe set timetosleep afterwards
|
||||||
/ format("_con._canseetarget(%s,%s)", SPS"", PLS""),
|
/ format("_con._canseetarget(%s,%s)", SPS"", PLS""),
|
||||||
ifcansee = cmd() * #sp1,
|
ifcansee = cmd() * #sp1
|
||||||
|
/ format("_con._cansee(_aci,%s)", PLS""),
|
||||||
ifbulletnear = cmd()
|
ifbulletnear = cmd()
|
||||||
/ "_con._bulletnear(_aci)",
|
/ "_con._bulletnear(_aci)",
|
||||||
ifawayfromwall = cmd()
|
ifawayfromwall = cmd()
|
||||||
|
@ -1706,7 +1713,7 @@ if (string.dump) then
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
local file = io.stdout
|
local file = require("io").stdout
|
||||||
for filename,codetab in pairs(g_file_code) do
|
for filename,codetab in pairs(g_file_code) do
|
||||||
file:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
file:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
||||||
file:write(table.concat(flatten_codetab(codetab), "\n"))
|
file:write(table.concat(flatten_codetab(codetab), "\n"))
|
||||||
|
|
Loading…
Reference in a new issue