diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 16bf0b214..ce3d3d2f0 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -235,7 +235,7 @@ STAT = { STAT_FALLER = 12, STAT_DUMMYPLAYER = 13, STAT_LIGHT = 14, - STAT_NETALLOC = 15, +-- STAT_NETALLOC = 15, } local GAMEFUNC = { @@ -343,7 +343,7 @@ local SX = function(memb) return "spriteext[%s]"..memb end -- Generate code to access a signed member as unsigned. local function s2u(label) - return "(_bit.band("..label.."+65536),65535)" + return "(_bit.band("..label.."+65536,65535))" end local function S2U(label) @@ -365,12 +365,12 @@ local ActorLabels = { yrepeat = SP".yrepeat", xoffset = SP".xoffset", yoffset = SP".yoffset", - sectnum = { SP".sectnum" }, - statnum = { SP".statnum" }, + sectnum = { SP".sectnum", SP".sectnum" }, -- set: for tsprite + statnum = { SP".statnum", SP".statnum" }, -- set: for tsprite ang = SP".ang", - owner = { SP".owner" }, + owner = { SP".owner", SP":_set_owner(%%s)" }, xvel = SP".xvel", - yvel = { SP".yvel" }, + yvel = { SP".yvel", SP":_set_yvel(%%s)" }, -- XXX zvel = SP".zvel", lotag = SP".lotag", hitag = SP".hitag", @@ -434,6 +434,10 @@ for member, code in pairs(ActorLabels) do end end +-- Sprites set stat- and sectnum via sprite.change{stat,sect} functions. +ActorLabels.sectnum[2] = "sprite.changesect(%s,%%s)" +ActorLabels.statnum[2] = "sprite.changestat(%s,%%s)" + local PL = function(memb) return "player[%s]"..memb end local PlayerLabels = { @@ -630,7 +634,7 @@ local PlayerLabels = { palette = PL".palette", -- NOTE the special case: - pals = PL"._pals[%s]", + pals = PL"._pals.col[%s]", pals_time = PL"._pals.f", name = {}, diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 0c022ed8f..dc53f4499 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -427,7 +427,7 @@ function _debris(i, dtile, n) shade=spr.shade, xrepeat=32+krandand(15), yrepeat=32+krandand(15), ang=krandand(2047), xvel=32+krandand(127), zvel=-krandand(2047) } -- NOTE: BlimpSpawnSprites[14] (its array size is 15) will never be chosen - sprite[jj]:set_yvel(isblimpscrap and ffiC.BlimpSpawnSprites[math.mod(jj, 14)] or -1) + sprite[jj]:_set_yvel(isblimpscrap and ffiC.BlimpSpawnSprites[math.mod(jj, 14)] or -1) sprite[jj].pal = spr.pal end end diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index c3b210fb3..eb3931b19 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -977,6 +977,10 @@ gv_access._ud = ffiC.ud -- Support for some CON global system gamevars gv_access._csv = ffi.new "struct { int32_t RETURN; }" +function gv_access._get_yxaspect() + return ffiC.yxaspect +end + function gv_access._currentFramerate() return ffiC.g_currentFrameRate end @@ -1523,6 +1527,27 @@ DBG_.oom = function() end end +-- Test reading from all struct members +function DBG_.testmembread() + for _1, sac in pairs { con_lang.StructAccessCode, con_lang.StructAccessCode2 } do + for what, labels in pairs(sac) do + if (what~="tspr") then + for _3, membaccode in pairs(labels) do + if (type(membaccode)=="table") then + membaccode = membaccode[1] + end + if (membaccode) then + local codestr = "do local _bit,_math=require'bit',require'math'; local tmp=".. + membaccode:gsub("%%s","0").." end" + local code = assert(loadstring(codestr)) + code() + end + end + end + end + end +end + ---=== Finishing environment setup ===--- diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index 5a88f2a66..8d34f3212 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -225,6 +225,7 @@ const int32_t windowx1, windowy1, windowx2, windowy2; ]] decl[[ +int32_t yxaspect; int32_t spritesortcnt; const int32_t rendmode; const int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1]; @@ -240,6 +241,9 @@ int32_t getflorzofslopeptr(const sectortype *sec, int32_t dax, int32_t day); void getzsofslopeptr(const sectortype *sec, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz); +int32_t changespritesect(int16_t spritenum, int16_t newsectnum); +int32_t changespritestat(int16_t spritenum, int16_t newstatnum); + int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz, hitdata_t *hitinfo, uint32_t cliptype); int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, @@ -416,11 +420,21 @@ local spritetype_mt = { ffi.cast(spritetype_ptr_ct, s).picnum = tilenum end, - set_yvel = function(s, yvel) - -- XXX: for now, no checking + _set_yvel = function(s, yvel) + -- XXX: no protection against malicious use (might set picnum to + -- another one temporarily) + -- XXX: this belongs into game-side Lunatic + if (s.picnum==1405) then -- APLAYER + error("setting yvel on an APLAYER sprite forbidden", 2) + end ffi.cast(spritetype_ptr_ct, s).yvel = yvel end, + _set_owner = function(s, owner) + check_sprite_idx(owner) + ffi.cast(spritetype_ptr_ct, s).owner = owner + end, + --- Custom setters set_cstat_bits = function(s, bits) s.cstat = bor(s.cstat, bits) @@ -535,6 +549,24 @@ static_members.sprite.CSTAT = conststruct TRANSLUCENT_BOTH_BITS = 512+2, } +function static_members.sprite.changesect(spritenum, sectnum) + check_sprite_idx(spritenum) + check_sector_idx(sectnum) + if (ffiC.changespritesect(spritenum, sectnum)==-1) then + error("cannot change sector number of sprite not in the game world", 2) + end +end + +function static_members.sprite.changestat(spritenum, statnum) + check_sprite_idx(spritenum) + if (statnum >= ffiC.MAXSTATUS+0ULL) then + error("invalid status number "..statnum, 2) + end + if (ffiC.changespritestat(spritenum, statnum)==-1) then + error("cannot change status number of sprite not in the game world", 2) + end +end + local function GenStructMetatable(Structname, Boundname) return { __index = function(tab, key) diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index c243d56ac..66686c0ed 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -22,6 +22,7 @@ windowx1; windowy1; windowx2; windowy2; +yxaspect; yax_getbunch; @@ -29,6 +30,9 @@ getceilzofslopeptr; getflorzofslopeptr; getzsofslopeptr; +changespritesect; +changespritestat; + headspritesect; headspritestat; prevspritesect; diff --git a/polymer/eduke32/source/lunatic/dynsymlist_m32 b/polymer/eduke32/source/lunatic/dynsymlist_m32 index e203f7704..527fada6b 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist_m32 +++ b/polymer/eduke32/source/lunatic/dynsymlist_m32 @@ -22,6 +22,7 @@ windowx1; windowy1; windowx2; windowy2; +yxaspect; yax_getbunch; @@ -29,6 +30,9 @@ getceilzofslopeptr; getflorzofslopeptr; getzsofslopeptr; +changespritesect; +changespritestat; + headspritesect; headspritestat; prevspritesect; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 89e2ed9bb..eb76ff152 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -175,6 +175,8 @@ local function new_initial_gvartab() windowx2 = RO "_gv.windowx2", windowy2 = RO "_gv.windowy2", + yxaspect = RO "_gv._get_yxaspect()", + numsectors = RO "_gv.numsectors", NUMSECTORS = RO "_gv.numsectors", NUMWALLS = RO "_gv.numwalls", diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 42e4fadaf..e38f8410d 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -222,6 +222,10 @@ gameevent("JUMP", gameevent(gv.EVENT_ENTERLEVEL, function() + if (gv._DEBUG_LUNATIC) then + DBG_.testmembread() + end + -- NOTE: times are for helixhorned (Core2Duo 3GHz) local i local N = 1e6 @@ -291,6 +295,11 @@ gameevent(gv.EVENT_ENTERLEVEL, -- N=10: 190-210 us * 10 = 1.9-2.1 ms -- N=100: about 160 us * 100 = about 16 ms + -- Make the DUKECAR in E1L1 into a static object + if (sprite[24].picnum==2491) then + sprite.changestat(24, gv.STAT_DEFAULT) + end + checkfail("gameevent('GAME', function() print('qwe') end)", "must be called from top level") end