mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
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
This commit is contained in:
parent
b0a8a381c8
commit
acddac64be
7 changed files with 383 additions and 80 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
]]
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[<current actor>].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 = -- get<actor/player>var[<idx>].<varname> <<var>>
|
|||
local setperxvarcmd = -- set<actor/player>var[<idx>].<<varname>> <var>
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue