From 5e41c1604cc87ae7d6a3af8824c91c5978a2b543 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Tue, 9 Jul 2013 18:23:43 +0000 Subject: [PATCH] LunaCON: handle system gamearrays for some array commands. - 'copy' may have them as source, 'getarraysize' works fine - 'setarray' and 'resizearray' are obviously forbidden - 'readarrayfromfile' and 'writearrayfromfile' is not implemented for them (use case?) Also, in the Makefile: don't use realpath on directories. It may give an empty string. git-svn-id: https://svn.eduke32.com/eduke32@3940 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/Makefile | 2 +- polymer/eduke32/source/lunatic/control.lua | 33 ++++++++++++-------- polymer/eduke32/source/lunatic/lunacon.lua | 35 +++++++++++++++++----- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index cb2018733..5201ea133 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -151,7 +151,7 @@ ifneq (0,$(LUNATIC)) ifneq ($(PLATFORM),WINDOWS) # On non-Windows, we expect to have liblpeg.a (or a symlink to it) in source/. # On Windows, it will reside in platform/Windows/lib32 or lib64. - LIBDIRS+= -L$(realpath (OBJ)/..) + LIBDIRS+= -L$(OBJ)/.. ifeq ($(realpath $(OBJ)/../liblpeg.a),) # XXX: This cripples "make clean" etc. too, but IMO it's better than warning. $(error "liblpeg.a not found in $(realpath $(OBJ)/..)") diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 7e709d173..fe12dc71e 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -1939,7 +1939,11 @@ local function gamearray_file_common(qnum, writep) end local function check_gamearray_idx(gar, idx, addstr) - if (idx >= gar._size+0ULL) then + -- If the actual table has no "_size" field, then we're dealing with a + -- system gamearray: currently, only g_tile.sizx/sizy. + local size = rawget(gar, '_size') or ffiC.MAXTILES + + if (idx >= size+0ULL) then addstr = addstr or "" error("invalid "..addstr.."array index "..idx, 3) end @@ -1947,6 +1951,22 @@ end local intbytes_t = ffi.typeof("union { int32_t i; uint8_t b[4]; }") +function _gar_copy(sar, sidx, dar, didx, numelts) + -- XXX: Strictest bound checking, see later if we need to relax it. + check_gamearray_idx(sar, sidx, "lower source ") + check_gamearray_idx(sar, sidx+numelts-1, "upper source ") + check_gamearray_idx(dar, didx, "lower destination ") + check_gamearray_idx(dar, didx+numelts-1, "upper destination ") + + -- Source is user gamearray? + local sisuser = (rawget(sar, '_size') ~= nil) + + for i=0,numelts-1 do + local val = sisuser and rawget(sar, sidx+i) or sar[sidx+i] + rawset(dar, didx+i, val) + end +end + local gamearray_methods = { resize = function(gar, newsize) -- NOTE: size 0 is valid (then, no index is valid) @@ -1968,17 +1988,6 @@ local gamearray_methods = { gar._size = newsize end, - copyto = function(sar, sidx, dar, didx, numelts) - -- XXX: Strictest bound checking, see later if we need to relax it. - check_gamearray_idx(sar, sidx, "lower source ") - check_gamearray_idx(sar, sidx+numelts-1, "upper source ") - check_gamearray_idx(dar, didx, "lower destination ") - check_gamearray_idx(dar, didx+numelts-1, "upper destination ") - for i=0,numelts-1 do - rawset(dar, didx+i, rawget(sar, sidx+i)) - end - end, - read = function(gar, qnum) local f, nelts, isnewgar = gamearray_file_common(qnum, false) diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 5b50d7beb..93b977a68 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -342,6 +342,7 @@ local function reset_codegen() g_switchCount = 0 g_gamevar = new_initial_gvartab() g_gamearray = { + -- SYSTEM_GAMEARRAY tilesizx = { name="g_tile.sizx", size=MAXTILES, sysp=true }, tilesizy = { name="g_tile.sizy", size=MAXTILES, sysp=true }, } @@ -358,6 +359,11 @@ local function reset_codegen() g_numerrors = 0 end +-- Is SYSTEM_GAMEARRAY? +local function issysgar(str) + return str:match("^g_tile.siz[xy]") +end + local function addcode(x) assert(type(x)=="string" or type(x)=="table") g_curcode[#g_curcode+1] = x @@ -1947,6 +1953,16 @@ local handle = return format("_con._rotspr(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", ...) end, + -- : format string, number of %s's must match number of varargs + -- : number, if 2^i is set, arg '%i' must not be a system gamearray + arraycmd = function(fmt, dstargi, ...) + local args = {...} + if (issysgar(args[dstargi])) then + errprintf("%s: system gamearray not supported", g_lastkw) + end + return format(fmt, ...) + end, + -- readgamevar or savegamevar RSgamevar = function(identifier, dosave) -- check identifier for sanity @@ -2352,19 +2368,24 @@ local Cinner = { end, -- array stuff - -- TODO: handle system gamearrays. Right now, the generated code will be wrong. copy = sp1 * tok.gamearray * arraypat * sp1 * tok.gamearray * arraypat * sp1 * tok.rvar - / "%1:copyto(%2,%3,%4,%5)", + / function(...) return handle.arraycmd("_con._gar_copy(%s,%s,%s,%s,%s)", 3, ...) end, setarray = sp1 * tok.gamearray * arraypat * sp1 * tok.rvar - / "%1[%2]=%3", + / function(...) return handle.arraycmd("%s[%s]=%s", 1, ...) end, resizearray = cmd(GARI,R) - / "%1:resize(%2)", + / function(...) return handle.arraycmd("%s:resize(%s)", 1, ...) end, getarraysize = cmd(GARI,W) - / "%2=%1._size", + / function(ar, dst) + return format("%s=%s", dst, issysgar(ar) and tostring(MAXTILES) or ar.."._size") + end, readarrayfromfile = cmd(GARI,D) - / "%1:read(%2,nil)", -- false: error on no file, nil: don't. + / function(...) -- false: error on no file, nil: don't. + return handle.arraycmd("%s:read(%s,nil)", 1, ...) + end, writearraytofile = cmd(GARI,D) - / "%1:write(%2)", + / function(...) + return handle.arraycmd("%s:write(%s)", 1, ...) + end, -- Persistence clearmapstate = cmd(R)