From acddac64bee2d733f7ff1fc526252e3e6299cc27 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 24 Feb 2013 16:05:22 +0000 Subject: [PATCH] Lunatic translator: nearing a workable state... - some more outer commands - gamearray persistence - faster 'mod': use math.modf instead of math.fmod (the former is JIT-compiled) - checkavail* - THISACTOR special handling - Fix building in Windows (export A_ShootWithZvel instead of A_Shoot). git-svn-id: https://svn.eduke32.com/eduke32@3516 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/gamedef.c | 23 +- polymer/eduke32/source/lunatic/bcheck.lua | 6 +- polymer/eduke32/source/lunatic/control.lua | 163 ++++++++++- polymer/eduke32/source/lunatic/defs.ilua | 11 +- polymer/eduke32/source/lunatic/dynsymlist | 6 +- polymer/eduke32/source/lunatic/lunacon.lua | 252 +++++++++++++----- .../source/lunatic/test/test_dists.lua | 2 +- 7 files changed, 383 insertions(+), 80 deletions(-) diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index 2db9bf370..ca10dc98b 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -2191,8 +2191,26 @@ void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, map->designertime = REALGAMETICSPERSEC * designertime; } } + +void C_DefineGameFuncName(int32_t idx, const char *name) +{ + assert(idx < NUMGAMEFUNCTIONS); + + Bstrncpyz(gamefunctions[idx], name, MAXGAMEFUNCLEN); + Bstrncpyz(keydefaults[3*idx], name, MAXGAMEFUNCLEN); +} #endif +// NOTE: external linkage for Lunatic +int32_t C_SetDefName(const char *name) +{ + clearDefNamePtr(); + g_defNamePtr = dup_filename(name); + if (g_defNamePtr) + initprintf("Using DEF file: %s.\n", g_defNamePtr); + return (g_defNamePtr==NULL); +} + // NOTE: external linkage for Lunatic void C_DefineProjectile(int32_t j, int32_t what, int32_t val) { @@ -5368,10 +5386,7 @@ repeatcase: } tempbuf[j] = '\0'; - clearDefNamePtr(); - g_defNamePtr = dup_filename(tempbuf); - - initprintf("Using DEF file: %s.\n",g_defNamePtr); + C_SetDefName(tempbuf); } continue; diff --git a/polymer/eduke32/source/lunatic/bcheck.lua b/polymer/eduke32/source/lunatic/bcheck.lua index c10a1f5ae..5d6fea4fe 100644 --- a/polymer/eduke32/source/lunatic/bcheck.lua +++ b/polymer/eduke32/source/lunatic/bcheck.lua @@ -72,11 +72,15 @@ function bcheck.level_idx(level) end end -function bcheck.quote_idx(qnum) +function bcheck.quote_idx(qnum, onlyidx) if (qnum >= con_lang.MAXQUOTES+0ULL) then error("invalid quote number "..qnum, 3) end + if (onlyidx) then + return nil + end + local cstr = ffiC.ScriptQuotes[qnum] if (cstr == nil) then error("null quote "..qnum, 3) diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 7b84f14dd..1d7e29a35 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -5,6 +5,7 @@ local ffi = require("ffi") local ffiC = ffi.C local bit = require("bit") +local io = require("io") local math = require("math") local geom = require("geom") local con_lang = require("con_lang") @@ -14,7 +15,10 @@ local setmetatable = setmetatable local assert = assert local error = error +local ipairs = ipairs local print = print +local rawget = rawget +local rawset = rawset local tostring = tostring local type = type local unpack = unpack @@ -306,14 +310,16 @@ function _div(a,b) if (b==0) then error("divide by zero", 2) end - return (a - math.fmod(a,b))/b + -- NOTE: math.modf() is compiled, math.fmod() is not: + -- http://wiki.luajit.org/NYI#Math-Library + return (a - math.modf(a,b))/b end function _mod(a,b) if (b==0) then error("mod by zero", 2) end - return (math.fmod(a,b)) + return (math.modf(a,b)) end -- Sect_ToggleInterpolation() clone @@ -424,8 +430,11 @@ end local MAXQUOTES = con_lang.MAXQUOTES local MAXQUOTELEN = con_lang.MAXQUOTELEN +-- CON redefinequote command function _definequote(qnum, quotestr) - bcheck.quote_idx(qnum) + -- NOTE: this is more permissive than C-CON: we allow to redefine quotes + -- that were not previously defined. + bcheck.quote_idx(qnum, true) assert(type(quotestr)=="string") ffiC.C_DefineQuote(qnum, quotestr) return (#quotestr >= MAXQUOTELEN) @@ -518,6 +527,11 @@ end local buf = ffi.new("char [?]", MAXQUOTELEN) function _qsprintf(qdst, qsrc, ...) + -- NOTE: more permissive than C-CON, see _definequote + if (bcheck.quote_idx(qdst, true) == nil) then + ffiC.C_DefineQuote(qdst, "") -- allocate quote + end + local dst = bcheck.quote_idx(qdst) local src = bcheck.quote_idx(qsrc) local vals = {...} @@ -894,6 +908,32 @@ function _checkpinventory(ps, inv, amount, i) end end +local INV_SELECTION_ORDER = { + ffiC.GET_FIRSTAID, + ffiC.GET_STEROIDS, + ffiC.GET_JETPACK, + ffiC.GET_HOLODUKE, + ffiC.GET_HEATS, + ffiC.GET_SCUBA, + ffiC.GET_BOOTS, +} + +-- checkavailinven CON command +function _selectnextinv(ps) + for _,inv in ipairs(INV_SELECTION_ORDER) do + if (ps:get_inv_amount(inv) > 0) then + ps.inven_icon = ICONS[inv] + return + end + end + + ps.inven_icon = 0 +end + +function _checkavailweapon(pli) + ffiC.P_CheckWeapon(player[pli]) +end + function _addphealth(ps, aci, hlthadd) if (ps.newowner >= 0) then ffiC.G_ClearCameraView(ps) @@ -1504,6 +1544,46 @@ end --- Game arrays --- +local function moddir_filename(cstr_fn) + local fn = ffi.string(cstr_fn) + local moddir = ffi.string(ffiC.g_modDir); + + if (moddir=="/") then + return fn + else + return format("%s/%s", moddir, fn) + end +end + +local GAR_FOOTER = "##EDuke32GameArray##" +local GAR_FOOTER_SIZE = #GAR_FOOTER + +local function gamearray_file_common(qnum, writep) + local fn = moddir_filename(bcheck.quote_idx(qnum)) + + local f, errmsg = io.open(fn); + if (f == nil) then + if (not writep) then + error([[failed opening "%s" for reading: %s]], fn, errmsg, 3) + else + return nil, nil, true, fn + end + end + + local fsize, errmsg = assert(f:seek("end")) + + local isnewgar = false + if (fsize >= GAR_FOOTER_SIZE) then + assert(f:seek("end", -GAR_FOOTER_SIZE)) + isnewgar = (assert(f:read(GAR_FOOTER_SIZE)) == GAR_FOOTER) + if (isnewgar) then + fsize = fsize - GAR_FOOTER_SIZE + end + end + + return f, math.floor(fsize/4), isnewgar, fn +end + local function check_gamearray_idx(gar, idx, addstr) if (idx >= gar._size+0ULL) then addstr = addstr or "" @@ -1511,6 +1591,8 @@ local function check_gamearray_idx(gar, idx, addstr) end end +local intbytes_t = ffi.typeof("union { int32_t i; uint8_t b[4]; }") + local gamearray_methods = { resize = function(gar, newsize) -- NOTE: size 0 is valid (then, no index is valid) @@ -1518,9 +1600,15 @@ local gamearray_methods = { error("invalid new array size "..newsize, 2) end + local MAXELTS = math.floor(0x7fffffff/4) + if (newsize > MAXELTS) then + -- mainly for some sanity with kread() (which we don't use, but still) + error("new array size "..newsize.." too large (max="..MAXELTS.." elements)", 2) + end + -- clear trailing elements in case we're shrinking for i=gar._size,newsize-1 do - gar[i] = nil + rawset(gar, i, nil) end gar._size = newsize @@ -1533,15 +1621,70 @@ local gamearray_methods = { check_gamearray_idx(dar, didx, "lower destination ") check_gamearray_idx(dar, didx+numelts-1, "upper destination ") for i=0,numelts-1 do - dar[dsix+i] = sar[sidx+i] + rawset(dar, didx+i, rawget(sar, sidx+i)) end end, + + read = function(gar, qnum) + local f, nelts, isnewgar = gamearray_file_common(qnum, false) + + assert(f:seek("set")) + local str, errmsg = f:read(4*nelts) + if (#str ~= 4*nelts) then + error("failed reading whole file into gamearray: %s", errmsg, 2) + end + + gar:resize(nelts) + + for i=0,nelts-1 do + local b1, b2, b3, b4 = byte(str, 4*i+1, 4*i+4) + -- ints on disk are litte-endian + local int = b1 + 256*b2 + 256^2*b3 + 256^3*b4 + + rawset(gar, i, (int==0) and nil or int) + end + + f:close() + end, + + write = function(gar, qnum) + local f, _, isnewgar, fn = gamearray_file_common(qnum, true) + + if (f ~= nil) then + f:close() + end + + if (not isnewgar) then + error("refusing to overwrite a file not created by a previous `writearraytofile'", 2) + end + + f = io.open(fn, "w+") + if (f == nil) then + error([[failed opening "%s" for writing: %s]], fn, errmsg, 3) + end + + local nelts = gar._size + local cstr = ffi.new("uint8_t [?]", 4*nelts) + local isbe = ffi.abi("be") -- is big-endian? + + for i=0,nelts-1 do + local diskval = intbytes_t(isbe and bit.bswap(gar[i]) or gar[i]) + for bi=0,3 do + cstr[4*i+bi] = diskval.b[bi] + end + end + + f:write(ffi.string(cstr, 4*nelts)) + f:write(GAR_FOOTER) + + f:close() + end } local gamearray_mt = { __index = function(gar, key) if (type(key)=="number") then - check_gamearray_idx(key) + check_gamearray_idx(gar, key) return 0 else return gamearray_methods[key] @@ -1549,16 +1692,16 @@ local gamearray_mt = { end, __newindex = function(gar, idx, val) - check_gamearray_idx(idx) - gar[idx] = val + check_gamearray_idx(gar, idx) + rawset(gar, idx, val) end, -- Calling a gamearray causes its cleanup: -- * All values equal to the default one (0) are cleared. __call = function(gar) for i=0,gar._size-1 do - if (gar[i]==0) then - gar[i] = nil + if (rawget(gar, i)==0) then + rawset(gar, i, nil) end end end, diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 92ceb2a7a..44ff1b277 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -228,6 +228,8 @@ __attribute__((packed)) struct { uint8_t gm, on_warping_sector, footprintcount, hurt_delay; uint8_t hbomb_on, jumping_toggle, rapid_fire_hold, on_ground; + // NOTE: there's array indexing with inven_icon, but always after a + // bound check: uint8_t inven_icon, buttonpalette, over_shoulder_on, show_empty_weapon; uint8_t jetpack_on, spritebridge, lastrandomspot; @@ -456,7 +458,7 @@ typedef struct { int32_t ForceSetup; int32_t NoAutoLoad; - int32_t scripthandle; + const int32_t scripthandle; int32_t setupread; int32_t CheckForUpdates; @@ -488,13 +490,14 @@ hudweapon_t hudweap; ]] -- INTERNAL VARIABLES/FUNCTIONS -decl("map_t MapInfo[($+1)*$];", con_lang.MAXVOLUMES, con_lang.MAXLEVELS) +decl("map_t MapInfo[$*$];", con_lang.MAXVOLUMES+1, con_lang.MAXLEVELS) decl[[ const char *s_buildRev; const char *g_sizes_of_what[]; int32_t g_sizes_of[]; int32_t g_elCallDepth; +char g_modDir[]; actor_t actor[MAXSPRITES]; camera_t g_camera; user_defs ud; @@ -515,9 +518,11 @@ int32_t g_scriptVersion; const int32_t g_currentFrameRate; const int32_t g_currentMenu; uint16_t g_earthquakeTime; +char CheatKeys[2]; int32_t A_IncurDamage(int32_t sn); // not bound-checked! void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap); +void P_CheckWeapon(DukePlayer_t *p); int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel); int32_t A_IncurDamage(int32_t sn); int32_t A_Spawn(int32_t j, int32_t pn); @@ -580,6 +585,8 @@ void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, int32_t partime, int32_t designertime, const char *levelname); void C_DefineProjectile(int32_t j, int32_t what, int32_t val); +void C_DefineGameFuncName(int32_t idx, const char *name); +int32_t C_SetDefName(const char *name); ]] diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 0ea9c07c1..f1fa2a06a 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -72,6 +72,7 @@ s_buildRev; g_sizes_of_what; g_sizes_of; g_elCallDepth; +g_modDir; kopen4loadfrommod; kfilelength; @@ -90,6 +91,8 @@ C_DefineVolumeName; C_DefineSkillName; C_DefineLevelName; C_DefineProjectile; +C_DefineGameFuncName; +C_SetDefName; actor; g_camera; @@ -130,7 +133,8 @@ md4once; A_IncurDamage; P_AddWeaponMaybeSwitch; -A_Shoot; +P_CheckWeapon; +A_ShootWithZvel; A_IncurDamage; A_Spawn; VM_FallSprite; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 1437d74bb..976535945 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -145,6 +145,7 @@ local function new_initial_codetab() "local sector, sprite, actor, player = sector, sprite, actor, player;", "local gameactor, gameevent, _gv = gameactor, gameevent, gv;", "local updatesector, updatesectorz, cansee = updatesector, updatesectorz, cansee;", + "local print = print;", -- switch function table, indexed by global switch sequence number: "local _SW = {};", @@ -172,8 +173,7 @@ local function new_initial_gvartab() local PRO = GamevarCreationFunc(GVFLAG.READONLY+GVFLAG.PERPLAYER) local gamevar = { - -- XXX: TODO: THISACTOR can mean different things in some contexts, - -- e.g. sector[THISACTOR] is sector[sprite[].sectnum] + -- NOTE: THISACTOR can mean different things in some contexts. THISACTOR = RO "_aci", RETURN = RW(CSV".RETURN"), @@ -424,6 +424,16 @@ local function parse_number(pos, numstr) return num end +-- returns: OK? +local function check_tilenum(tilenum) + if (not (tilenum >= 0 and tilenum < (ffiC and ffiC.MAXTILES or 30720))) then + errprintf("invalid tile number %d", tilenum) + return false + end + + return true +end + -- Mapping of various "define" types to the respective number of members and -- vice versa @@ -678,6 +688,18 @@ end -- Table of various outer command handling functions. local Cmd = {} +function Cmd.NYI(msg) + return function() + errprintf(msg.." not yet implemented") + end +end + +function Cmd.nyi(msg) + return function() + warnprintf(msg.." not yet implemented") + end +end + function Cmd.include(filename) do_include_file(g_directory, filename) end @@ -766,6 +788,22 @@ function Cmd.definevolumename(vol, name) g_data.volname[vol] = name end +function Cmd.definegamefuncname(idx, name) + local NUMGAMEFUNCTIONS = (ffi and ffiC.NUMGAMEFUNCTIONS or 56) + if (not (idx >= 0 and idx < NUMGAMEFUNCTIONS)) then + errprintf("function number exceeds number of game functions.") + return + end + + assert(type(name)=="string") + -- XXX: in place of C-CON's "invalid character in function name" report: + name:gsub("[^A-Za-z0-9]", "_") + + if (ffi) then + ffiC.C_DefineGameFuncName(idx, name) + end +end + -- strip whitespace from front and back local function stripws(str) return str:match("^%s*(.*)%s*$") @@ -793,17 +831,44 @@ function Cmd.definequote(qnum, quotestr) end function Cmd.defineprojectile(tilenum, what, val) - if (not (tilenum >= 0 and tilenum < (ffiC and ffiC.MAXTILES or 30720))) then - errprintf("invalid tile number %d", tilenum) - return - end + local ok = check_tilenum(tilenum) - if (ffi) then + if (ffi and ok) then -- TODO: potentially bound-check some members? ffiC.C_DefineProjectile(tilenum, what, val) end end +-- flags: if string, look up in ffiC and OR, else set number directly. +function Cmd.xspriteflags(tilenum, flags) + local ok = check_tilenum(tilenum) + + if (ffi and ok) then + if (type(flags)=="number") then + ffiC.g_tile[tilenum].flags = flags + else + assert(type(flags)=="string") + ffiC.g_tile[tilenum].flags = bit.bor(ffiC.g_tile[tilenum].flags, ffiC[flags]) + end + end +end + +function Cmd.cheatkeys(sc1, sc2) + if (ffi) then + ffiC.CheatKeys[0] = sc1 + ffiC.CheatKeys[1] = sc2 + end +end + +function Cmd.setdefname(filename) + assert(type(filename)=="string") + if (ffi) then + if (ffiC.C_SetDefName(filename) ~= 0) then + error("OUT OF MEMORY", 0) + end + end +end + function Cmd.gamestartup(...) local args = {...} @@ -1110,63 +1175,90 @@ end -- XXX: many of these are also allowed inside actors/states/events in CON. local Couter = { --- 1. Preprocessor - include = sp1 * maybe_quoted_filename / Cmd.include, - includedefault = cmd(), - define = cmd(I,D) / do_define_label, + include = sp1 * maybe_quoted_filename + / Cmd.include, + includedefault = cmd() + / Cmd.NYI("`includedefault'"), + define = cmd(I,D) + / do_define_label, --- 2. Defines and Meta-Settings - dynamicremap = cmd(), - setcfgname = sp1 * tok.filename, - setdefname = sp1 * tok.filename, - setgamename = newline_term_string, + dynamicremap = cmd() + / Cmd.NYI("dynamic tile remapping"), + setcfgname = sp1 * tok.filename + / Cmd.nyi("`setcfgname'"), + setdefname = sp1 * tok.filename + / Cmd.setdefname, + setgamename = newline_term_string + / Cmd.nyi("`setgamename'"), - precache = cmd(D,D,D), + precache = cmd(D,D,D) + , -- / Cmd.nyi("`precache'"), scriptsize = cmd(D) / "", -- no-op - cheatkeys = cmd(D,D), + cheatkeys = cmd(D,D) + / Cmd.cheatkeys, - definecheat = newline_term_string, -- XXX: actually tricker syntax (TS) - definegamefuncname = newline_term_string, -- XXX: TS? - definegametype = n_defines(2) * newline_term_string, + definecheat = newline_term_string -- XXX: actually tricker syntax (TS) + , -- / Cmd.nyi("`definecheat'"), + definegamefuncname = sp1 * tok.define * newline_term_string -- XXX: TS? + / Cmd.definegamefuncname, + definegametype = n_defines(2) * newline_term_string + / Cmd.NYI("`definegametype'"), -- TODO_MP definelevelname = n_defines(2) * sp1 * tok.filename * sp1 * tok.time * sp1 * tok.time * - newline_term_string / Cmd.definelevelname, - defineskillname = sp1 * tok.define * newline_term_string / Cmd.defineskillname, - definevolumename = sp1 * tok.define * newline_term_string / Cmd.definevolumename, + newline_term_string + / Cmd.definelevelname, + defineskillname = sp1 * tok.define * newline_term_string + / Cmd.defineskillname, + definevolumename = sp1 * tok.define * newline_term_string + / Cmd.definevolumename, - definequote = sp1 * tok.define * newline_term_string / Cmd.definequote, - defineprojectile = cmd(D,D,D) / Cmd.defineprojectile, - definesound = sp1 * tok.define * sp1 * maybe_quoted_filename * n_defines(5) / Cmd.definesound, + definequote = sp1 * tok.define * newline_term_string + / Cmd.definequote, + defineprojectile = cmd(D,D,D) + / Cmd.defineprojectile, + definesound = sp1 * tok.define * sp1 * maybe_quoted_filename * n_defines(5) + / Cmd.definesound, -- NOTE: gamevar.ogg and the like is OK, too - music = sp1 * tok.define * match_until(sp1 * tok.filename, sp1 * conl.keyword * sp1) / Cmd.music, + music = sp1 * tok.define * match_until(sp1 * tok.filename, sp1 * conl.keyword * sp1) + / Cmd.music, --- 3. Game Settings -- gamestartup has 26/30 fixed defines, depending on 1.3D/1.5 version: - gamestartup = (sp1 * tok.define)^26 / Cmd.gamestartup, - spritenopal = cmd(D), - spritenoshade = cmd(D), - spritenvg = cmd(D), - spriteshadow = cmd(D), + gamestartup = (sp1 * tok.define)^26 + / Cmd.gamestartup, + spritenopal = cmd(D) + / function(tilenum, flags) Cmd.xspriteflags(tilenum, "SFLAG_NOPAL") end, + spritenoshade = cmd(D) + / function(tilenum, flags) Cmd.xspriteflags(tilenum, "SFLAG_NOSHADE") end, + spritenvg = cmd(D) + / function(tilenum, flags) Cmd.xspriteflags(tilenum, "SFLAG_NVG") end, + spriteshadow = cmd(D) + / function(tilenum, flags) Cmd.xspriteflags(tilenum, "SFLAG_SHADOW") end, - spriteflags = cmd(D,D), -- also see inner + spriteflags = cmd(D,D) -- also see inner + / function(tilenum, flags) Cmd.xspriteflags(tilenum, flags) end, --- 4. Game Variables / Arrays - gamevar = cmd(I,D,D) / Cmd.gamevar, - gamearray = cmd(I,D) / Cmd.gamearray, + gamevar = cmd(I,D,D) + / Cmd.gamevar, + gamearray = cmd(I,D) + / Cmd.gamearray, --- 5. Top level commands that are also run-time commands - move = sp1 * tok.identifier * (sp1 * tok.define)^-2 / -- hvel, vvel - function(...) do_define_composite(LABEL.MOVE, ...) end, + move = sp1 * tok.identifier * (sp1 * tok.define)^-2 -- hvel, vvel + / function(...) do_define_composite(LABEL.MOVE, ...) end, -- startframe, numframes, viewtype, incval, delay: - action = sp1 * tok.identifier * (sp1 * tok.define)^-5 / - function(...) do_define_composite(LABEL.ACTION, ...) end, + action = sp1 * tok.identifier * (sp1 * tok.define)^-5 + / function(...) do_define_composite(LABEL.ACTION, ...) end, -- action, move, flags...: ai = sp1 * tok.identifier * (sp1 * tok.action * - (sp1 * tok.move * (sp1 * tok.define)^0)^-1 - )^-1 / - function(...) do_define_composite(LABEL.AI, ...) end, + (sp1 * tok.move * (sp1 * tok.define)^0)^-1 + )^-1 + / function(...) do_define_composite(LABEL.AI, ...) end, --- 6. Deprecated TLCs betaname = newline_term_string, @@ -1226,6 +1318,10 @@ local getperxvarcmd = -- getvar[]. <> local setperxvarcmd = -- setvar[].<> arraypat * singlememberpat * sp1 * tok.rvar +local function thisactor_to_pli(var) + return (var=="_aci") and "_pli" or var +end + -- Function generating code for a struct read/write access. local function StructAccess(Structname, writep, index, membertab) assert(type(membertab)=="table") @@ -1262,6 +1358,15 @@ local function StructAccess(Structname, writep, index, membertab) end end + -- THISACTOR special meanings + if (Structname=="player" or Structname=="input") then + index = thisactor_to_pli(index) + elseif (Structname=="sector") then + if (index=="_aci") then + index = SPS".sectnum" + end + end + -- METHOD_MEMBER local ismethod = (armembcode:find("%%s",1,true)~=nil) -- If ismethod is true, then the formatted string will now have an "%s" @@ -1278,8 +1383,8 @@ end function lookup.array_expr(writep, structname, index, membertab) if (conl.StructAccessCode[structname] == nil) then -- Try a gamearray - local ga = (g_gamearray[structname]) and lookup.gamearray(structname) - if (ga == nil) then + local ganame = g_gamearray[structname] and lookup.gamearray(structname) + if (ganame == nil) then if (structname=="actorvar") then -- actorvar[] inline array expr -- XXX: kind of CODEDUP with GetOrSetPerxvarCmd() factory @@ -1311,7 +1416,8 @@ function lookup.array_expr(writep, structname, index, membertab) return "_INVALIDAR" end - return format("%s[%s]", ga.name, index) + assert(type(ganame)=="string") + return format("%s[%s]", ganame, index) end local membercode, ismethod = StructAccess(structname, writep, index, membertab) @@ -1374,6 +1480,11 @@ local function GetOrSetPerxvarCmd(Setp, Actorp) errprintf("variable `%s' is not per-%s", perxvarname, Actorp and "actor" or "player") end + if (not Actorp) then + -- THISACTOR -> player index for {g,s}etplayervar + idx = thisactor_to_pli(idx) + end + if (Setp) then return format("%s=%s", lookup.gamevar(perxvarname, idx, true), var) else @@ -1396,6 +1507,12 @@ local handle = errprintf("command `%s' not yet implemented", g_lastkw) end, + dynNYI = function() + -- XXX: what if file name contains a double quote? (Similarly commands below.) + return format([[print("%s:%d: `%s' not yet implemented")]], + g_filename, getlinecol(g_lastkwpos), g_lastkw) + end, + addlog = function() return format("print('%s:%d: addlog')", g_filename, getlinecol(g_lastkwpos)) end, @@ -1506,7 +1623,7 @@ local Cinner = { -- We disallow them, recent EDuke32 versions didn't expose them either. getuserdef = GetStructCmd(Access.userdef, userdef_common_pat * tok.wvar), - getplayervar = GetOrSetPerxvarCmd(false, false), + getplayervar = GetOrSetPerxvarCmd(false, false), -- THISACTOR getactorvar = GetOrSetPerxvarCmd(false, true), setsector = SetStructCmd(Access.sector), @@ -1520,7 +1637,7 @@ local Cinner = { settspr = SetStructCmd(Access.tspr), setuserdef = SetStructCmd(Access.userdef, userdef_common_pat * tok.rvar), - setplayervar = GetOrSetPerxvarCmd(true, false), + setplayervar = GetOrSetPerxvarCmd(true, false), -- THISACTOR setactorvar = GetOrSetPerxvarCmd(true, true), setvarvar = varvarop / "%1=%2", @@ -1617,13 +1734,15 @@ local Cinner = { cmenu = cmd(R) / handle.NYI, checkavailweapon = cmd(R) -- THISACTOR - / handle.NYI, + / function(pli) + return format("_con._checkavailweapon(%s)", thisactor_to_pli(pli)) + end, checkavailinven = cmd(R) -- THISACTOR - / handle.NYI, + / function(pli) + return format("_con._selectnextinv(player[%s])", thisactor_to_pli(pli)) + end, guniqhudid = cmd(R) / "_gv._set_guniqhudid(%1)", - savegamevar = cmd(R), - readgamevar = cmd(R), echo = cmd(R) / "_con._echo(%1)", activatecheat = cmd(R) @@ -1705,8 +1824,6 @@ local Cinner = { / "_con._spawnmany(_aci,1233,%1)", -- TODO: dyntile paper = cmd(D) / "_con._spawnmany(_aci,4460,%1)", -- TODO: dyntile - savenn = cmd(D), - save = cmd(D), sleeptime = cmd(D) / ACS".timetosleep=%1", @@ -1809,7 +1926,7 @@ local Cinner = { / "_con._userquote(%1)", getkeyname = cmd(R,R,R) / "_con._getkeyname(%1,%2,%3)", - getpname = cmd(R,R) + getpname = cmd(R,R) -- THISACTOR / handle.NYI, -- array stuff @@ -1821,8 +1938,26 @@ local Cinner = { / "%1:resize(%2)", getarraysize = cmd(GARI,W) / "%2=%1._size", - readarrayfromfile = cmd(GARI,D), - writearraytofile = cmd(GARI,D), + readarrayfromfile = cmd(GARI,D) + / "%1:read(%2)", + writearraytofile = cmd(GARI,D) + / "%1:write(%2)", + + -- Persistence + clearmapstate = cmd(R) + / handle.dynNYI, + loadmapstate = cmd() + / handle.dynNYI, + savemapstate = cmd() + / handle.dynNYI, + savegamevar = cmd(R) + / handle.dynNYI, + readgamevar = cmd(R) + / handle.dynNYI, + savenn = cmd(D) + / handle.dynNYI, + save = cmd(D) + / handle.dynNYI, addlogvar = cmd(R) / handle.addlogvar, @@ -1898,8 +2033,7 @@ local Cinner = { / "_con._activatebysector(%1,%2)", operateactivators = cmd(R,R) -- THISACTOR / function(tag, pli) - return format("_con._operateactivators(%s,%s)", tag, - (pli=="_aci") and "_pli" or pli) + return format("_con._operateactivators(%s,%s)", tag, thisactor_to_pli(pli)) end, operatesectors = cmd(R,R) / "_con._operatesectors(%1,%2)", @@ -1915,10 +2049,6 @@ local Cinner = { myospalx = cmd(R,R,R,R,R,R) / "_con._myos(%1,%2,32768,%3,%4,%5,%6)", - clearmapstate = cmd(R), - loadmapstate = cmd(), - savemapstate = cmd(), - headspritesect = cmd(W,R) / "%1=sprite._headspritesect[%2]", headspritestat = cmd(W,R) diff --git a/polymer/eduke32/source/lunatic/test/test_dists.lua b/polymer/eduke32/source/lunatic/test/test_dists.lua index 138cfffbc..fbee09979 100644 --- a/polymer/eduke32/source/lunatic/test/test_dists.lua +++ b/polymer/eduke32/source/lunatic/test/test_dists.lua @@ -81,7 +81,7 @@ t = os.clock()-t printf("rotate: %.03fns per call", (1e9)/Nsq) --- Results (helixhorned x86_64) +-- Results (helixhorned x86, x86_64) -- number of points: 10000, testing 100000000 distances -- edist: 6.300ns per call, mean=6286.597 -- ldist: 17.600ns per call, mean=8692.612