From 3665fde85b378c7b279560765db3461b0ed3de35 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 16 Feb 2013 18:53:24 +0000 Subject: [PATCH] Lunatic: more commands... git-svn-id: https://svn.eduke32.com/eduke32@3491 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/lunatic/bcheck.lua | 12 +++ polymer/eduke32/source/lunatic/control.lua | 59 ++++++++++++- polymer/eduke32/source/lunatic/defs.ilua | 2 + .../eduke32/source/lunatic/defs_common.lua | 2 +- polymer/eduke32/source/lunatic/dynsymlist | 2 + polymer/eduke32/source/lunatic/geom.lua | 25 +++--- polymer/eduke32/source/lunatic/lunacon.lua | 83 ++++++++++++++----- .../source/lunatic/test/test_dists.lua | 36 +++++++- polymer/eduke32/source/lunatic/xmath.lua | 14 ++++ 9 files changed, 198 insertions(+), 37 deletions(-) diff --git a/polymer/eduke32/source/lunatic/bcheck.lua b/polymer/eduke32/source/lunatic/bcheck.lua index b783d549b..5dc3cb68b 100644 --- a/polymer/eduke32/source/lunatic/bcheck.lua +++ b/polymer/eduke32/source/lunatic/bcheck.lua @@ -59,5 +59,17 @@ function bcheck.inventory_idx(inv) end end +function bcheck.volume_idx(volume) + if (volume >= con_lang.MAXVOLUMES+0ULL) then + error("invalid volume number "..volume) + end +end + +function bcheck.level_idx(level) + if (level >= con_lang.MAXLEVELS+0ULL) then + error("invalid level number "..level) + end +end + return bcheck diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 084ea6603..209acb3f6 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -284,14 +284,20 @@ function _gettimedate() return v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] end +local rshift = bit.rshift + function rnd(x) - return (bit.rshift(ffiC.krand(), 8) >= (255-x)) + return (rshift(ffiC.krand(), 8) >= (255-x)) end -- Legacy operators function _rand(x) - return bit.rshift(ffiC.krand()*(x+1), 16) + return rshift(ffiC.krand()*(x+1), 16) +end + +function _displayrand(x) + return rshift(math.random(0, 32767)*(x+1), 15) end function _div(a,b) @@ -846,6 +852,20 @@ function _canseespr(s1, s2) return cansee(sprite[s1], sprite[s1].sectnum, sprite[s2], sprite[s2].sectnum) and 1 or 0 end +-- CON "hitscan" command +function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype) + local srcv = geom.ivec3(x, y, z) + local hit = hitscan(srcv, sectnum, vx, vy, vz, cliptype) + return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z +end + +-- CON "neartag" command +function _neartag(x, y, z, sectnum, ang, range, tagsearch) + local pos = geom.ivec3(x, y, z) + local near = neartag(pos, sectnum, ang, range, tagsearch) + return near.sector, near.wall, near.sprite, near.dist +end + function _sleepcheck(aci, dist) local acs = actor[aci] if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then @@ -859,6 +879,12 @@ function _canseetarget(spr, ps) ps.pos, sprite[ps.i].sectnum) end +function _movesprite(spritenum, x, y, z, cliptype) + check_sprite_idx(spritenum) + local vel = geom.ivec3(x, y, z) + return ffiC.A_MoveSprite(spritenum, vel, cliptype) +end + local function A_CheckHitSprite(spr, angadd) local zoff = (spr:isenemy() and 42*256) or (spr.picnum==D.APLAYER and 39*256) or 0 @@ -947,6 +973,13 @@ function _hypot(a, b) return math.sqrt(a*a + b*b) end +function _rotatepoint(pivotx, pivoty, posx, posy, ang) + local pos = geom.ivec3(posx, posy) + local pivot = geom.ivec3(pivotx, pivoty) + pos = xmath.rotate(pos, pivot, ang):toivec3() + return pos.x, pos.y +end + local SK = { CROUCH = 1, RUN = 5, @@ -1152,6 +1185,28 @@ function _setactorsoundpitch(aci, sndidx, pitchoffset) ffiC.S_ChangeSoundPitch(sndidx, aci, pitchoffset) end +function _starttrack(level) + bcheck.level_idx(level) + + if (ffiC.G_StartTrack(level) ~= 0) then + error("null music for volume "..ffiC.ud.volume_number.. + " level "..level) + end +end + +function _startlevel(volume, level) + bcheck.volume_idx(volume) + bcheck.level_idx(level) + + ffiC.ud.m_volume_number = volume + ffiC.ud.m_level_number = level + + ffiC.ud.display_bonus_screen = 0 + + -- TODO_MP + player[0].gm = bit.bor(player[0].gm, 0x00000008) -- MODE_EOL +end + --- Exported functions --- diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index b20519c62..c9c138a82 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -522,6 +522,7 @@ int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int3 int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss); int32_t A_Spawn(int32_t j, int32_t pn); void A_AddToDeleteQueue(int32_t i); +int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype); void P_DoQuote(int32_t q, DukePlayer_t *p); void G_ClearCameraView(DukePlayer_t *ps); void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, @@ -529,6 +530,7 @@ void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, void G_InitTimer(int32_t ticspersec); void G_GetTimeDate(int32_t *vals); int32_t G_ToggleWallInterpolation(int32_t w, int32_t doset); +int32_t G_StartTrack(int32_t level); int32_t A_CheckAnySoundPlaying(int32_t i); int32_t A_PlaySound(uint32_t num, int32_t i); diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index 20a0632ff..f70f91714 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -767,10 +767,10 @@ typedef struct { ]] local neartag_ret_ct = ffi.typeof("const neartag_ret_t") +local function newar() return ffi.new("int16_t [1]") end -- TODO: make tagsearch something more convenient function neartag(pos, sectnum, ang, range, tagsearch) check_sector_idx(sectnum) - local newar = function() return ffi.new("int16_t [1]") end local a, b, c, d = newar(), newar(), newar(), ffi.new("int32_t [1]") ffiC.neartag(pos.x, pos.y, pos.z, sectnum, ang, a, b, c, d, range, tagsearch, nil) return neartag_ret_ct(a[0], b[0], c[0], d[0]) diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index c69922d38..1393b35ec 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -142,12 +142,14 @@ A_Dodge; A_InsertSprite; A_Spawn; A_AddToDeleteQueue; +A_MoveSprite; P_DoQuote; G_ClearCameraView; G_DrawTileGeneric; G_InitTimer; G_GetTimeDate; G_ToggleWallInterpolation; +G_StartTrack; A_CheckAnySoundPlaying; A_PlaySound; diff --git a/polymer/eduke32/source/lunatic/geom.lua b/polymer/eduke32/source/lunatic/geom.lua index 2c0769567..450fc760c 100644 --- a/polymer/eduke32/source/lunatic/geom.lua +++ b/polymer/eduke32/source/lunatic/geom.lua @@ -10,6 +10,17 @@ local error = error module(...) +-- This has no metamethods, but can be useful for calculations expecting +-- integer values, e.g. geom.ivec3(x, y, z) is a reasonable way to round +-- a vec3. It can be also used as the RHS to the vec2/vec3 arithmetic +-- methods. +-- NOTE: We must have a typedef with that exact name, because for +-- Lunatic (i.e. not stand-alone), it is a duplicate (and ignored) +-- declaration for an already metatype'd type. +ffi.cdef "typedef struct { int32_t x, y, z; } vec3_t;" +ivec3 = ffi.typeof("vec3_t") + + local dvec2_t = ffi.typeof("struct { double x, y; }") local dvec3_t = ffi.typeof("struct { double x, y, z; }") @@ -92,6 +103,10 @@ local vec3_mt = { lensq = function(a) return a.x*a.x + a.y*a.y + a.z*a.z end, -- Manhattan distance: len1 = function(a) return math.abs(a.x)+math.abs(a.y)+math.abs(a.z) end, + + toivec3 = function(v) + return ivec3(v.x, v.y, v.z) + end, }, } @@ -111,16 +126,6 @@ vec3_ = ffi.metatype(dvec3_t, vec3_mt) vec3 = vec3_ function tovec3(t) return vec3(t.x, t.y, t.z) end --- This has no metamethods, but can be useful for calculations expecting --- integer values, e.g. geom.ivec3(x, y, z) is a reasonable way to round --- a vec3. It can be also used as the RHS to the vec2/vec3 arithmetic --- methods. --- NOTE: We must have a typedef with that exact name, because for --- Lunatic (i.e. not stand-alone), it is a duplicate (and ignored) --- declaration for an already metatype'd type. -ffi.cdef "typedef struct { int32_t x, y, z; } vec3_t;" -ivec3 = ffi.typeof("vec3_t") - -- Two-element vector cross product. -- Anti-commutative, distributive. diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 436bdef60..0a2b82909 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1287,6 +1287,28 @@ local handle = return format("print('%s:%d: debug %d')", g_filename, getlinecol(g_lastkwpos), val) end, + hitscan = function(...) + local v = {...} + assert(#v == 14) -- 7R 6W 1R + local vals = { + v[8], v[9], v[10], v[11], v[12], v[13], -- outargs + v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[14] -- inargs + } + return format("%s,%s,%s,%s,%s,%s=_con._hitscan(%s,%s,%s,%s,%s,%s,%s,%s)", + unpack(vals)) + end, + + neartag = function(...) + local v = {...} + assert(#v == 11) -- 5R 4W 2R + local vals = { + v[6], v[7], v[8], v[9], -- outargs + v[1], v[2], v[3], v[4], v[5], v[10], v[11] -- inargs + } + return format("%s,%s,%s,%s=_con._neartag(%s,%s,%s,%s,%s,%s,%s)", + unpack(vals)) + end, + palfrom = function(...) local v = {...} return format(PLS":_palfrom(%d,%d,%d,%d)", @@ -1478,7 +1500,6 @@ local Cinner = { userquote = cmd(R), echo = cmd(R) / "_con._echo(%1)", - starttrackvar = cmd(R), activatecheat = cmd(R) / handle.NYI, setgamepalette = cmd(R), @@ -1662,19 +1683,38 @@ local Cinner = { / "sprite.changesect(%1,%2)", changespritestat = cmd(R,R) / "sprite.changestat(%1,%2)", - clipmove = cmd(W,W,W,R,W,R,R,R,R,R,R) - / handle.NYI, - clipmovenoslide = cmd(W,W,W,R,W,R,R,R,R,R,R) - / handle.NYI, - displayrand = cmd(W), - displayrandvar = cmd(W,D), - displayrandvarvar = cmd(W,R), + displayrand = cmd(W) + / "%1=_con._displayrand(32767)", + displayrandvar = cmd(W,D) + / "%1=_con._displayrand(%2)", + displayrandvarvar = cmd(W,R) + / "%1=_con._displayrand(%2)", dist = cmd(W,R,R) / "%1=_xmath.dist(sprite[%1],sprite[%2])", ldist = cmd(W,R,R) / "%1=_xmath.ldist(sprite[%1],sprite[%2])", - dragpoint = cmd(R,R,R), - hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R), -- 7R 6W 1R + dragpoint = cmd(R,R,R) + / handle.NYI, + rotatepoint = cmd(R,R,R,R,R,W,W) + / "%6,%7=_con._rotatepoint(%1,%2,%3,%4,%5)", + + -- collision detection etc. + hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R) -- 7R 6W 1R + / handle.hitscan, + clipmove = cmd(W,W,W,R,W,R,R,R,R,R,R) + / handle.NYI, + clipmovenoslide = cmd(W,W,W,R,W,R,R,R,R,R,R) + / handle.NYI, + lineintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W) -- 10R 4W + / handle.NYI, + rayintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W) -- 10R 4W + / handle.NYI, + movesprite = cmd(R,R,R,R,R,W) + / "%6=_con._movesprite(%1,%2,%3,%4,%5)", + neartag = cmd(R,R,R,R,R,W,W,W,W,R,R) -- 5R 4W 2R + / handle.neartag, + getzrange = cmd(R,R,R,R,W,W,W,W,R,R) + / handle.NYI, -- screen text and numbers display gametext = cmd(R,R,R,R,R,R,R,R,R,R,R), -- 11 R @@ -1683,12 +1723,6 @@ local Cinner = { digitalnumberz = cmd(R,R,R,R,R,R,R,R,R,R,R,R), -- 12R minitext = cmd(R,R,R,R,R), - lineintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W) -- 10R 4W - / handle.NYI, - rayintersect = cmd(R,R,R,R,R,R,R,R,R,R,W,W,W,W) -- 10R 4W - / handle.NYI, - movesprite = cmd(R,R,R,R,R,W), - neartag = cmd(R,R,R,R,R,W,W,W,W,R,R), palfrom = (sp1 * tok.define)^-4 / handle.palfrom, @@ -1726,7 +1760,6 @@ local Cinner = { redefinequote = sp1 * tok.define * newline_term_string / function(qnum, qstr) return format("_con._definequote(%d,%q)", qnum, stripws(qstr)) end, - rotatepoint = cmd(R,R,R,R,R,W,W), rotatesprite = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R / handle.rotatesprite, rotatesprite16 = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R @@ -1751,6 +1784,13 @@ local Cinner = { gettexturefloor = cmd() / (CSV".TEXTURE=sector["..SPS".sectnum].floorpicnum"), + startlevel = cmd(R,R) + / "_con._startlevel(%1,%2)", + starttrack = cmd(D) + / "_con._starttrack(%1)", + starttrackvar = cmd(R) + / "_con._starttrack(%1)", + showview = cmd(R,R,R,R,R,R,R,R,R,R), -- 10R showviewunbiased = cmd(R,R,R,R,R,R,R,R,R,R), -- 10R smaxammo = cmd(R,R) @@ -1761,17 +1801,17 @@ local Cinner = { / ACS".flags=%1", ssp = cmd(R,R) / handle.NYI, - startlevel = cmd(R,R), - starttrack = cmd(D), updatesector = cmd(R,R,W), updatesectorz = cmd(R,R,R,W), getactorangle = cmd(W) / ("%1="..SPS".ang"), - setactorangle = cmd(R), + setactorangle = cmd(R) + / SPS".ang=_bit.band(%1,2047)", getplayerangle = cmd(W) / ("%1="..PLS".ang"), - setplayerangle = cmd(R), + setplayerangle = cmd(R) + / PLS".ang=_bit.band(%1,2047)", getangletotarget = cmd(W) / "%1=_con._angtotarget(_aci)", @@ -1787,7 +1827,6 @@ local Cinner = { / "%1=_gv.getticks()", gettimedate = cmd(W,W,W,W,W,W,W,W) / "%1,%2,%3,%4,%5,%6,%7,%8=_con._gettimedate()", - getzrange = cmd(R,R,R,R,W,W,W,W,R,R), setaspect = cmd(R,R), } diff --git a/polymer/eduke32/source/lunatic/test/test_dists.lua b/polymer/eduke32/source/lunatic/test/test_dists.lua index f6c2189a2..138cfffbc 100644 --- a/polymer/eduke32/source/lunatic/test/test_dists.lua +++ b/polymer/eduke32/source/lunatic/test/test_dists.lua @@ -16,9 +16,10 @@ local function edist(p1, p2) return sqrt(p1.x*p1.x + p2.x*p2.x) end -local vec2 = ffi.typeof("struct { int32_t x, y; }") +-- z dummy is so that there's no error with xmath.rotate() +local vec2 = ffi.typeof("struct { int32_t x, y, z /* dummy */; }") -local numpoints = 1e4 +local numpoints = tonumber(arg[1]) or 1e4 local Nsq = numpoints*numpoints printf("number of points: %d, testing %d distances", numpoints, Nsq) @@ -54,3 +55,34 @@ end t = os.clock()-t printf("ldist: %.03fns per call, mean=%.03f", (1e9*t)/Nsq, sum/Nsq) + + +-- test rotation +t = os.clock() + +-- from control.lua (the CON version of rotatepoint) +local function _rotatepoint(pivotx, pivoty, posx, posy, ang) + local pos = geom.ivec3(posx, posy) + local pivot = geom.ivec3(pivotx, pivoty) + pos = xmath.rotate(pos, pivot, ang):toivec3() + return pos.x, pos.y +end + +sum = 0 +for i=1,numpoints do + for j=1,numpoints do +-- local p = xmath.rotate(pts[i], pts[j], j) +-- sum = sum+p.x + sum = sum + _rotatepoint(pts[j].x, pts[j].y, pts[i].x, pts[i].y, j) + end +end + +t = os.clock()-t + +printf("rotate: %.03fns per call", (1e9)/Nsq) + +-- Results (helixhorned 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 +-- rotate: 10.000ns per call [even with _rotatepoint()!] diff --git a/polymer/eduke32/source/lunatic/xmath.lua b/polymer/eduke32/source/lunatic/xmath.lua index 5993eae30..426e673ce 100644 --- a/polymer/eduke32/source/lunatic/xmath.lua +++ b/polymer/eduke32/source/lunatic/xmath.lua @@ -5,6 +5,8 @@ local ffi = require("ffi") local bit = require("bit") local math = require("math") +local geom = require("geom") + local assert = assert @@ -96,3 +98,15 @@ function dist(pos1, pos2) local t = y + z return x - arshift(x,4) + arshift(t,2) + arshift(t,3) end + + +-- Point rotation. Note the different order of arguments from engine function. +-- XXX: passing mixed vec2/vec3 is problematic. Get rid of geom.vec2? +-- : BUILD angle (0-2047 based) +function rotate(pos, pivot, ang) + local p = geom.tovec3(pos)-pivot + local c, s = cosb(ang), sinb(ang) + p.x = pivot.x + (c*p.x - s*p.y) + p.y = pivot.y + (c*p.y + s*p.x) + return p +end