diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index c1532df4c..63daa0f38 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -10005,6 +10005,8 @@ int32_t g_sizes_of[] = { sizeof(sectortype), sizeof(walltype), sizeof(spritetype), sizeof(spriteext_t), sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t), sizeof(user_defs), sizeof(tiledata_t) }; + +DukePlayer_t *g_player_ps[MAXPLAYERS]; #endif void G_MaybeAllocPlayer(int32_t pnum) @@ -10017,7 +10019,8 @@ void G_MaybeAllocPlayer(int32_t pnum) if (g_player[pnum].ps == NULL || g_player[pnum].sync == NULL) G_GameExit("OUT OF MEMORY"); #ifdef LUNATIC - g_player[pnum].ps->wa.idx = pnum; + g_player_ps[pnum] = g_player[pnum].ps; + g_player[pnum].ps->wa.idx = pnum; #endif } diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index ce3d3d2f0..8561c7596 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -823,6 +823,17 @@ local UserdefLabels = { weaponswitch = UD".weaponswitch", } +local INP = function(memb) return PL"._input"..memb end + +local InputLabels = { + avel = INP".avel", + horz = INP".horz", + fvel = INP".fvel", + svel = INP".svel", + bits = INP".bits", + extbits = INP".extbits", +} + -- These structs cannot be accessed by inline array exprs in CON: StructAccessCode2 = { @@ -830,6 +841,7 @@ StructAccessCode2 = projectile = ProjectileLabels, thisprojectile = SpriteProjectileLabels, userdef = UserdefLabels, + input = InputLabels, } -- NOTE: These MUST be in reverse lexicographical order! diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index eb3931b19..a9648dc88 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -491,6 +491,7 @@ actor_t actor[MAXSPRITES]; camera_t g_camera; user_defs ud; playerdata_t g_player[MAXPLAYERS]; +DukePlayer_t *g_player_ps[MAXPLAYERS]; weapondata_t g_playerWeapon[MAXPLAYERS][MAX_WEAPONS]; tiledata_t g_tile[MAXTILES]; projectile_t ProjectileData[MAXTILES]; @@ -578,18 +579,55 @@ if (not good) then error("Some sizes don't match between C and LuaJIT/FFI.") end --- "player" global, needed by the "control" module -local tmpmt = { - __index = function(tab, key) - if (key >= 0 and key < ffiC.playerswhenstarted) then - return ffiC.g_player[key].ps[0] - end - error('out-of-bounds player[] read access', 2) - end, - __newindex = function(tab, key, val) error('cannot write directly to player[] struct', 2) end, +--== "player" global, needed by the "control" module ==-- + +local player_static_members = {} + +player_static_members.INPUT_BITS = defs_c.conststruct +{ + JUMP = 1, + CROUCH = 2, + FIRE = 4, + AIM_UP = 8, + AIM_DOWN = 16, + RUNNING = 32, + LOOK_LEFT = 64, + LOOK_RIGHT = 128, + -- weapons... + STEROIDS = 4096, + LOOK_UP = 8192, + LOOK_DOWN = 16384, + NIGHTVISION = 32768, + MEDKIT = 65536, + RESERVED = 131072, + CENTER_VIEW = 262144, + HOLSTER_WEAPON = 524288, + INVENTORY_LEFT = 1048576, + PAUSE = 2097152, + QUICK_KICK = 4194304, + AIM_MODE = 8388608, + HOLODUKE = 16777216, + JETPACK = 33554432, + QUIT = 67108864, + INVENTORY_RIGHT = 134217728, + TURN_AROUND = 268435456, + OPEN = 536870912, + INVENTORY = 1073741824, + ESC = 2147483648, } -player = setmtonce({}, tmpmt) + +player_static_members.INPUT_EXT_BITS = defs_c.conststruct +{ + INPUT_MOVE_FORWARD = 1, + INPUT_MOVE_BACKWARD = 2, + INPUT_STRAFE_LEFT = 4, + INPUT_STRAFE_RIGHT = 8, + INPUT_TURN_LEFT = 16, + INPUT_TURN_RIGHT = 32, +} + +player = setmtonce({}, defs_c.GenStructMetatable("g_player_ps", "playerswhenstarted", player_static_members)) -- needed by "control" actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, "actor[]") @@ -921,6 +959,14 @@ local player_mt = { end, }, } + +local function player_index_index(p, key) + if (key=="_input") then + return ffiC.g_player[p.weapon._p].sync[0] + end +end + +setmtonce(player_mt.__index, { __index = player_index_index }) ffi.metatype("DukePlayer_t", player_mt) local function GenProjectileSetFunc(Member) diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index 8d34f3212..ab66c988e 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -461,11 +461,6 @@ end local tspritetype_mt = deep_copy(spritetype_mt) -print(spritetype_mt) -print(spritetype_mt.__index) -print(tspritetype_mt) -print(tspritetype_mt.__index) - -- Methods that are specific to tsprites function tspritetype_mt.__index.dup(tspr) if (ffiC.spritesortcnt >= ffiC.MAXSPRITESONSCREEN+0ULL) then @@ -507,7 +502,7 @@ end ---- indirect C array access ---- -- Construct const struct from table -local function conststruct(tab) +function conststruct(tab) local strtab = { "const struct { int32_t " } local vals = {} @@ -567,7 +562,9 @@ function static_members.sprite.changestat(spritenum, statnum) end end -local function GenStructMetatable(Structname, Boundname) +function GenStructMetatable(Structname, Boundname, StaticMembersTab) + StaticMembersTab = StaticMembersTab or static_members[Structname] + return { __index = function(tab, key) if (type(key)=="number") then @@ -576,7 +573,7 @@ local function GenStructMetatable(Structname, Boundname) end error("out-of-bounds "..Structname.."[] read access", 2) elseif (type(key)=="string") then - return static_members[Structname][key] + return StaticMembersTab[key] end end, diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 66686c0ed..979f2d593 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -92,6 +92,7 @@ actor; g_camera; ud; g_player; +g_player_ps; g_playerWeapon; g_tile; ProjectileData; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index eb76ff152..f893e6c7c 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1208,6 +1208,7 @@ local Access = projectile = function(...) return StructAccess("projectile", ...) end, thisprojectile = function(...) return StructAccess("thisprojectile", ...) end, userdef = function(...) return StructAccess("userdef", ...) end, + input = function(...) return StructAccess("input", ...) end, } local function GetStructCmd(accessfunc, pattern) @@ -1329,7 +1330,7 @@ local Cinner = { getactor = GetStructCmd(Access.xsprite), getplayer = GetStructCmd(Access.player), - getinput = getstructcmd / handle.NYI, + getinput = GetStructCmd(Access.input), getprojectile = GetStructCmd(Access.projectile), getthisprojectile = GetStructCmd(Access.thisprojectile), gettspr = GetStructCmd(Access.tspr), @@ -1351,7 +1352,7 @@ local Cinner = { setactor = SetStructCmd(Access.xsprite), setplayer = SetStructCmd(Access.player), - setinput = setstructcmd / handle.NYI, + setinput = SetStructCmd(Access.input), setprojectile = SetStructCmd(Access.projectile), setthisprojectile = SetStructCmd(Access.thisprojectile), settspr = SetStructCmd(Access.tspr), diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index e38f8410d..c2216f3f9 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -199,6 +199,22 @@ gameevent(gv.EVENT_JUMP, end ) +gameevent("PROCESSINPUT", + -- Input test. + -- NOTE: I don't think that exposing g_player[].sync (aka "input") is a good idea... + function(actori, playeri, dist) + local IB = player.INPUT_BITS + local input = player[playeri]._input + if (bit.band(input.bits, IB.JUMP) ~= 0) then + print("JUMPED") + -- ... because for example this doesn't work + -- (P_HandleSharedKeys, where the JETPACK bit is tested, runs + -- before P_ProcessInput): + input.bits = bit.bor(input.bits, IB.JETPACK) + end + end + ) + -- test event chaining gameevent("JUMP", function(actori, playeri, dist)