From 354a1a70ef759fd39ecfa303c12a066766331a2e Mon Sep 17 00:00:00 2001 From: helixhorned Date: Fri, 30 Nov 2012 18:57:46 +0000 Subject: [PATCH] Lunatic: expose more stuff, more codegen (the easy ones). git-svn-id: https://svn.eduke32.com/eduke32@3247 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/lunatic/con_lang.lua | 2 + polymer/eduke32/source/lunatic/control.lua | 4 + polymer/eduke32/source/lunatic/defs.ilua | 18 +- .../eduke32/source/lunatic/defs_common.lua | 22 ++- polymer/eduke32/source/lunatic/dynsymlist | 7 + polymer/eduke32/source/lunatic/dynsymlist_m32 | 5 + polymer/eduke32/source/lunatic/lunacon.lua | 155 ++++++++++++------ 7 files changed, 158 insertions(+), 55 deletions(-) diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 0a86477c8..c5de2a602 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -19,6 +19,8 @@ MAXSKILLS = 7 MAXSOUNDS = 4096 +SLEEPTIME = 1536 + -- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective -- defines. These are exported to the ffi.C namespace and as literal defines diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 95cb278e8..a0a86da73 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -119,3 +119,7 @@ function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation, ffiC.rotatesprite(65536*x, 65536*y, zoom, ang, tilenum, shade, pal, bit.bor(2,orientation), cx1, cy1, cx2, cy2) end + +function rnd(x) + return (bit.rshift(ffiC.krand(), 8) >= (255-x)) +end diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 6ca996efe..a0d60c0dd 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -6,6 +6,7 @@ _EDUKE32_LUNATIC = true local ffi = require("ffi") local ffiC = ffi.C +local bit = bit local string = string local table = table local print = print @@ -219,6 +220,7 @@ local DUKEPLAYER_STRUCT = [[ ]] local randgen = require("randgen") +local geom = require("geom") -- Converts a template struct definition to an internal, unrestricted one. local function strip_const(structstr) @@ -414,6 +416,8 @@ user_defs ud; playerdata_t g_player[MAXPLAYERS]; const int32_t playerswhenstarted; + +int32_t A_IncurDamage(int32_t sn); // not bound-checked! ]] -- functions @@ -612,9 +616,19 @@ local actor_mt = { ffi.metatype("actor_t", actor_mt) ---- default defines +--- default defines etc. local con_lang = require("con_lang") +local player_mt = { + __index = { + cansee = function(p, otherpos, othersect) + return cansee(p.pos, sprite[p.i].sectnum, otherpos, othersect) + end, + }, +} +ffi.metatype("DukePlayer_t", player_mt) + + for i=1,#con_lang.labels do local strbuf = {"enum {"} @@ -637,7 +651,7 @@ local allowed_modules = { }, randgen = randgen, - geom = require("geom"), + geom = geom, stat = require("stat"), bitar = require("bitar"), diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index f6bc30ec3..d17e28d6d 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -174,6 +174,11 @@ int16_t yax_getbunch(int16_t i, int16_t cf); 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, + int32_t x2, int32_t y2, int32_t z2, int16_t sect2); + +int32_t ldist(const spritetype *s1, const spritetype *s2); +int32_t dist(const spritetype *s1, const spritetype *s2); void updatesector(int32_t x, int32_t y, int16_t *sectnum); void updatesectorbreadth(int32_t x, int32_t y, int16_t *sectnum); @@ -186,8 +191,10 @@ void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, -- misc. functions ffi.cdef[[ -int32_t ksqrt(uint32_t num); double gethitickms(void); + +int32_t krand(void); +int32_t ksqrt(uint32_t num); ]] @@ -345,6 +352,19 @@ function hitscan(pos, sectnum, vx,vy,vz, cliptype) return hitdata end +function cansee(pos1,sect1, pos2,sect2) + if (sect1 >= ffiC.numsectors+0ULL) then + error("passed out-of-bounds first sector number "..sect1, 2) + end + if (sect2 >= ffiC.numsectors+0ULL) then + error("passed out-of-bounds second sector number "..sect2, 2) + end + + local ret = ffiC.cansee(pos1.x,pos1.y,pos1.z, sect1, + pos2.x,pos2.y,pos2.z, sect2) + return (ret~=0) and true or false +end + -- TODO: should these rather be one function, and the specific kind of updating -- controlled by an argument? function updatesector(pos, sectnum) diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index f3bfe8a27..51e54eb82 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -27,10 +27,15 @@ nextspritestat; headsectbunch; nextsectbunch; +krand; ksqrt; +cansee; hitscan; rotatesprite; +dist; +ldist; + updatesector; updatesectorz; updatesectorbreadth; @@ -53,6 +58,8 @@ g_player; playerswhenstarted; +A_IncurDamage; + luaJIT_BC_lunacon; luaJIT_BC_con_lang; luaJIT_BC_geom; diff --git a/polymer/eduke32/source/lunatic/dynsymlist_m32 b/polymer/eduke32/source/lunatic/dynsymlist_m32 index bba715f52..2aaed0f91 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist_m32 +++ b/polymer/eduke32/source/lunatic/dynsymlist_m32 @@ -27,10 +27,15 @@ nextspritestat; headsectbunch; nextsectbunch; +krand; ksqrt; +cansee; hitscan; rotatesprite; +dist; +ldist; + updatesector; updatesectorz; updatesectorbreadth; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 482a1ff92..abd8a3311 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -667,6 +667,10 @@ local setperxvarcmd = -- setvar[]. arraypat * memberpat * sp1 * t_rvar +local function ACS(s) return "actor[_aci]"..s end +local function SPS(s) return "sprite[_aci]"..s end +local function PLS(s) return "player[_pli]"..s end + -- 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 -- suffixed with a "* #sp1" pattern. @@ -748,25 +752,28 @@ local Ci = { getincangle = cmd(W,R,R), --- 3. Actors - action = cmd(AC) / - function(str) return string.format("actor[_aci]:set_action(%s)", str) end, - ai = cmd(AI) / - function(str) return string.format("actor[_aci]:set_ai(%s)", str) end, + action = cmd(AC) + / ACS":set_action(%1)", + ai = cmd(AI) + / ACS":set_ai(%1)", -- TODO: move's flags - move = sp1 * t_move * (sp1 * t_define)^0 / - function(str, ...) return string.format("actor[_aci]:set_move(%s)", str) end, + move = sp1 * t_move * (sp1 * t_define)^0 + / ACS":set_move(%1)", - cactor = cmd(D) / - "sprite[_aci].tilenum=%1", -- TODO: wrap, e.g. sprite[]:set_picnum(tilenum), bound check there - count = cmd(D), + cactor = cmd(D) + / SPS".picnum=%1", -- TODO: wrap, e.g. sprite[]:set_picnum(tilenum), bound check there + count = cmd(D) + / ACS":set_count(%1)", cstator = cmd(D), cstat = cmd(D), clipdist = cmd(D), sizeto = cmd(D,D), - sizeat = cmd(D,D) / - "sprite[_aci].xrepeat, sprite[_aci].yrepeat = %1, %2", - strength = cmd(D), - addstrength = cmd(D), + sizeat = cmd(D,D) + / (SPS".xrepeat,"..SPS".yrepeat=%1,%2"), + strength = cmd(D) + / SPS".extra=%1", + addstrength = cmd(D) + / (SPS".extra="..SPS".extra+%1"), spritepal = cmd(D), hitradius = cmd(D,D,D,D,D), @@ -812,10 +819,12 @@ local Ci = { guts = cmd(D,D), -- cont'd - addkills = cmd(D), + addkills = cmd(D) + / (PLS".actors_killed="..PLS".actors_killed+%1;"..ACS".actorstayput=-1"), addphealth = cmd(D), angoff = cmd(D), - debug = cmd(D), + debug = cmd(D) + / "", -- TODO? endofgame = cmd(D), eqspawn = cmd(D), espawn = cmd(D), @@ -851,11 +860,14 @@ local Ci = { nullop = cmd(), pkick = cmd(), pstomp = cmd(), - resetactioncount = cmd(), - resetcount = cmd(), + resetactioncount = cmd() + / ACS":reset_acount()", + resetcount = cmd() + / ACS":set_count(0)", resetplayer = cmd(), -- exec SPECIAL HANDLING! respawnhitag = cmd(), - tip = cmd(), + tip = cmd() + / PLS".tipincs=26", tossweapon = cmd(), wackplayer = cmd(), @@ -990,24 +1002,39 @@ local Ci = { } local Cif = { - ifai = cmd(AI), - ifaction = cmd(AC), - ifmove = cmd(MV), + ifai = cmd(AI) + / ACS":has_ai(%1)", + ifaction = cmd(AC) + / ACS":has_action(%1)", + ifmove = cmd(MV) + / ACS":has_move(%1)", - ifrnd = cmd(D), + ifrnd = cmd(D) + / "_gv.rnd(%1)", ifpdistl = cmd(D), ifpdistg = cmd(D), - ifwasweapon = cmd(D), - ifactioncount = cmd(D), - ifcount = cmd(D), - ifactor = cmd(D), - ifstrength = cmd(D), - ifspawnedby = cmd(D), - ifgapzl = cmd(D), - iffloordistl = cmd(D), - ifceilingdistl = cmd(D), - ifphealthl = cmd(D), - ifspritepal = cmd(D), + ifactioncount = cmd(D) + / ACS":get_acount()==%1", + ifcount = cmd(D) + / ACS":get_count()==%1", + ifactor = cmd(D) + / SPS".picnum==%d", + ifstrength = cmd(D) + / SPS".extra<=%d", + ifspawnedby = cmd(D) + / ACS".picnum==%d", + ifwasweapon = cmd(D) + / ACS".picnum==%d", + ifgapzl = cmd(D) -- factor into a con.* function? + / format("_bit.arshift(%s-%s,8)<%%1", ACS".floorz", ACS".ceilingz"), + iffloordistl = cmd(D) + / format("(%s-%s)<=256*%%1", ACS".floorz", SPS".z"), + ifceilingdistl = cmd(D) + / format("(%s-%s)<=256*%%1", SPS".z", ACS".ceilingz"), + ifphealthl = cmd(D) + / format("sprite[%s].extra<%%1", PLS".i"), + ifspritepal = cmd(D) + / SPS".pal==%1", ifgotweaponce = cmd(D), ifangdiffl = cmd(D), ifsound = cmd(D), @@ -1037,24 +1064,30 @@ local Cif = { ifsquished = cmd(), ifserver = cmd(), ifrespawn = cmd(), - ifoutside = cmd(), + ifoutside = cmd() + / format("_bit.band(sector[%s].ceilingstat,1)~=0", SPS".sectnum"), ifonwater = cmd(), ifnotmoving = cmd(), ifnosounds = cmd(), - ifmultiplayer = cmd(), - ifinwater = cmd(), + ifmultiplayer = cmd() + / "false", -- TODO? + ifinwater = cmd() + / format("sector[%s].lotag==2", SPS".sectnum"), ifinspace = cmd(), ifinouterspace = cmd(), - ifhitweapon = cmd(), + ifhitweapon = cmd() + / "TODO", ifhitspace = cmd(), - ifdead = cmd(), + ifdead = cmd() + / SPS".extra<=0", ifclient = cmd(), ifcanshoottarget = cmd(), ifcanseetarget = cmd(), ifcansee = cmd() * #sp1, ifbulletnear = cmd(), ifawayfromwall = cmd(), - ifactornotstayput = cmd(), + ifactornotstayput = cmd() + / ACS".actorstayput==-1", } @@ -1165,7 +1198,21 @@ local function after_inner_cmd_Cmt(subj, pos, ...) end if (type(capts[1])=="string" and capts[2]==nil) then - return true, capts[1].."--" + return true, capts[1] .."--"..linecolstr(pos) --TEMP + end + + return true +end + +local function after_if_cmd_Cmt(subj, pos, ...) + local capts = {...} + + if (g_numerrors == inf) then + return nil + end + + if (type(capts[1])=="string" and capts[2]==nil) then + return true, capts[1] end return true @@ -1181,19 +1228,18 @@ local function after_cmd_Cmt(subj, pos, ...) end -- attach the command names at the front! -local function attachnames(kwtab, customfunc) +local function attachnames(kwtab, matchtimefunc) for cmdname,cmdpat in pairs(kwtab) do -- The match-time function capture at the end is so that every -- command acts as a barrier to captures to prevent stack overflow (and -- to make lpeg.match return a subject position at the end) - kwtab[cmdname] = lpeg.Cmt(Keyw(cmdname) * cmdpat, - customfunc or after_cmd_Cmt) + kwtab[cmdname] = lpeg.Cmt(Keyw(cmdname) * cmdpat, matchtimefunc) end end -attachnames(Co) +attachnames(Co, after_cmd_Cmt) attachnames(Ci, after_inner_cmd_Cmt) -attachnames(Cif) +attachnames(Cif, after_if_cmd_Cmt) -- Takes one or more tables and +'s all its patterns together in reverse @@ -1269,7 +1315,7 @@ local Cb = { state = sp1 * t_identifier * sp1 * stmt_list_or_eps * "ends", } -attachnames(Cb) +attachnames(Cb, after_cmd_Cmt) local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09")^0 @@ -1284,10 +1330,11 @@ local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09" local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) * (alphanum + Set("_/\\*")) * (alphanum + Set("_/\\*-"))^0) -local function begin_if_fn() +local function begin_if_fn(condstr) g_ifseqlevel = g_ifseqlevel+1 - - return "if (TODO) then" + condstr = condstr or "TODO" + assert(type(condstr)=="string") + return format("if (%s) then", condstr) end local function end_if_fn() @@ -1350,7 +1397,7 @@ local Grammar = Pat{ (Var("case_block") + Var("default_block"))^0 * sp1 * "endswitch", -- NOTE: some old DNWMD has "case: PIGCOP". I don't think I'll allow that. - case_block = (sp1 * Keyw("case") * sp1 * t_define * (sp0*":")^-1)^1 * sp1 * + case_block = (sp1 * Keyw("case") * sp1 * t_define/"XXX_CASE" * (sp0*":")^-1)^1 * sp1 * stmt_list_nosp_or_eps, -- * "break", default_block = sp1 * Keyw("default") * (sp0*":"*sp0 + sp1) * stmt_list_nosp_or_eps, -- * "break", @@ -1362,7 +1409,7 @@ local Grammar = Pat{ -- TODO?: SST TC has "state ... else ends" while_stmt = Keyw("whilevarvarn") * sp1 * t_rvar * sp1 * t_rvar * sp1 * Var("single_stmt") - + Keyw("whilevarn") * sp1 * t_rvar * sp1 * t_define * sp1 * Var("single_stmt"), + + Keyw("whilevarn") * sp1 * t_rvar * sp1 * t_define/"WHILE_XXX" * sp1 * Var("single_stmt"), -- TODO: some sp1 --> sp0? single_stmt = Stmt( @@ -1426,6 +1473,10 @@ end ---=== EXPORTED FUNCTIONS ===--- +local function new_initial_perfile_codetab() + return { "local _con=require'con'; local _gv=gv; local _bit=require'bit'" } +end + function parse(contents) -- local -- save outer state local lastkw, lastkwpos, numerrors = g_lastkw, g_lastkwpos, g_numerrors @@ -1433,7 +1484,7 @@ function parse(contents) -- local local curcode = g_curcode g_ifseqlevel = 0 - g_curcode = { "local _con=require'con'\n" } + g_curcode = new_initial_perfile_codetab() g_file_code[g_filename] = g_curcode -- set up new state