Lunatic: more commands...

git-svn-id: https://svn.eduke32.com/eduke32@3491 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-16 18:53:24 +00:00
parent 801662c3e7
commit 3665fde85b
9 changed files with 198 additions and 37 deletions

View file

@ -59,5 +59,17 @@ function bcheck.inventory_idx(inv)
end end
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 return bcheck

View file

@ -284,14 +284,20 @@ function _gettimedate()
return v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] return v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]
end end
local rshift = bit.rshift
function rnd(x) function rnd(x)
return (bit.rshift(ffiC.krand(), 8) >= (255-x)) return (rshift(ffiC.krand(), 8) >= (255-x))
end end
-- Legacy operators -- Legacy operators
function _rand(x) 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 end
function _div(a,b) 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 return cansee(sprite[s1], sprite[s1].sectnum, sprite[s2], sprite[s2].sectnum) and 1 or 0
end 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) function _sleepcheck(aci, dist)
local acs = actor[aci] local acs = actor[aci]
if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then
@ -859,6 +879,12 @@ function _canseetarget(spr, ps)
ps.pos, sprite[ps.i].sectnum) ps.pos, sprite[ps.i].sectnum)
end 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 function A_CheckHitSprite(spr, angadd)
local zoff = (spr:isenemy() and 42*256) or (spr.picnum==D.APLAYER and 39*256) or 0 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) return math.sqrt(a*a + b*b)
end 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 = { local SK = {
CROUCH = 1, CROUCH = 1,
RUN = 5, RUN = 5,
@ -1152,6 +1185,28 @@ function _setactorsoundpitch(aci, sndidx, pitchoffset)
ffiC.S_ChangeSoundPitch(sndidx, aci, pitchoffset) ffiC.S_ChangeSoundPitch(sndidx, aci, pitchoffset)
end 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 --- --- Exported functions ---

View file

@ -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 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); int32_t A_Spawn(int32_t j, int32_t pn);
void A_AddToDeleteQueue(int32_t i); 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 P_DoQuote(int32_t q, DukePlayer_t *p);
void G_ClearCameraView(DukePlayer_t *ps); void G_ClearCameraView(DukePlayer_t *ps);
void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, 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_InitTimer(int32_t ticspersec);
void G_GetTimeDate(int32_t *vals); void G_GetTimeDate(int32_t *vals);
int32_t G_ToggleWallInterpolation(int32_t w, int32_t doset); 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_CheckAnySoundPlaying(int32_t i);
int32_t A_PlaySound(uint32_t num, int32_t i); int32_t A_PlaySound(uint32_t num, int32_t i);

View file

@ -767,10 +767,10 @@ typedef struct {
]] ]]
local neartag_ret_ct = ffi.typeof("const neartag_ret_t") 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 -- TODO: make tagsearch something more convenient
function neartag(pos, sectnum, ang, range, tagsearch) function neartag(pos, sectnum, ang, range, tagsearch)
check_sector_idx(sectnum) 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]") 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) 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]) return neartag_ret_ct(a[0], b[0], c[0], d[0])

View file

@ -142,12 +142,14 @@ A_Dodge;
A_InsertSprite; A_InsertSprite;
A_Spawn; A_Spawn;
A_AddToDeleteQueue; A_AddToDeleteQueue;
A_MoveSprite;
P_DoQuote; P_DoQuote;
G_ClearCameraView; G_ClearCameraView;
G_DrawTileGeneric; G_DrawTileGeneric;
G_InitTimer; G_InitTimer;
G_GetTimeDate; G_GetTimeDate;
G_ToggleWallInterpolation; G_ToggleWallInterpolation;
G_StartTrack;
A_CheckAnySoundPlaying; A_CheckAnySoundPlaying;
A_PlaySound; A_PlaySound;

View file

@ -10,6 +10,17 @@ local error = error
module(...) 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 dvec2_t = ffi.typeof("struct { double x, y; }")
local dvec3_t = ffi.typeof("struct { double x, y, z; }") 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, lensq = function(a) return a.x*a.x + a.y*a.y + a.z*a.z end,
-- Manhattan distance: -- Manhattan distance:
len1 = function(a) return math.abs(a.x)+math.abs(a.y)+math.abs(a.z) end, 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_ vec3 = vec3_
function tovec3(t) return vec3(t.x, t.y, t.z) end 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. -- Two-element vector cross product.
-- Anti-commutative, distributive. -- Anti-commutative, distributive.

View file

@ -1287,6 +1287,28 @@ local handle =
return format("print('%s:%d: debug %d')", g_filename, getlinecol(g_lastkwpos), val) return format("print('%s:%d: debug %d')", g_filename, getlinecol(g_lastkwpos), val)
end, 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(...) palfrom = function(...)
local v = {...} local v = {...}
return format(PLS":_palfrom(%d,%d,%d,%d)", return format(PLS":_palfrom(%d,%d,%d,%d)",
@ -1478,7 +1500,6 @@ local Cinner = {
userquote = cmd(R), userquote = cmd(R),
echo = cmd(R) echo = cmd(R)
/ "_con._echo(%1)", / "_con._echo(%1)",
starttrackvar = cmd(R),
activatecheat = cmd(R) activatecheat = cmd(R)
/ handle.NYI, / handle.NYI,
setgamepalette = cmd(R), setgamepalette = cmd(R),
@ -1662,19 +1683,38 @@ local Cinner = {
/ "sprite.changesect(%1,%2)", / "sprite.changesect(%1,%2)",
changespritestat = cmd(R,R) changespritestat = cmd(R,R)
/ "sprite.changestat(%1,%2)", / "sprite.changestat(%1,%2)",
clipmove = cmd(W,W,W,R,W,R,R,R,R,R,R) displayrand = cmd(W)
/ handle.NYI, / "%1=_con._displayrand(32767)",
clipmovenoslide = cmd(W,W,W,R,W,R,R,R,R,R,R) displayrandvar = cmd(W,D)
/ handle.NYI, / "%1=_con._displayrand(%2)",
displayrand = cmd(W), displayrandvarvar = cmd(W,R)
displayrandvar = cmd(W,D), / "%1=_con._displayrand(%2)",
displayrandvarvar = cmd(W,R),
dist = cmd(W,R,R) dist = cmd(W,R,R)
/ "%1=_xmath.dist(sprite[%1],sprite[%2])", / "%1=_xmath.dist(sprite[%1],sprite[%2])",
ldist = cmd(W,R,R) ldist = cmd(W,R,R)
/ "%1=_xmath.ldist(sprite[%1],sprite[%2])", / "%1=_xmath.ldist(sprite[%1],sprite[%2])",
dragpoint = cmd(R,R,R), dragpoint = cmd(R,R,R)
hitscan = cmd(R,R,R,R,R,R,R,W,W,W,W,W,W,R), -- 7R 6W 1R / 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 -- screen text and numbers display
gametext = cmd(R,R,R,R,R,R,R,R,R,R,R), -- 11 R 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 digitalnumberz = cmd(R,R,R,R,R,R,R,R,R,R,R,R), -- 12R
minitext = cmd(R,R,R,R,R), 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 palfrom = (sp1 * tok.define)^-4
/ handle.palfrom, / handle.palfrom,
@ -1726,7 +1760,6 @@ local Cinner = {
redefinequote = sp1 * tok.define * newline_term_string redefinequote = sp1 * tok.define * newline_term_string
/ function(qnum, qstr) return format("_con._definequote(%d,%q)", qnum, stripws(qstr)) end, / 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 rotatesprite = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R
/ handle.rotatesprite, / handle.rotatesprite,
rotatesprite16 = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R rotatesprite16 = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R
@ -1751,6 +1784,13 @@ local Cinner = {
gettexturefloor = cmd() gettexturefloor = cmd()
/ (CSV".TEXTURE=sector["..SPS".sectnum].floorpicnum"), / (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 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 showviewunbiased = cmd(R,R,R,R,R,R,R,R,R,R), -- 10R
smaxammo = cmd(R,R) smaxammo = cmd(R,R)
@ -1761,17 +1801,17 @@ local Cinner = {
/ ACS".flags=%1", / ACS".flags=%1",
ssp = cmd(R,R) ssp = cmd(R,R)
/ handle.NYI, / handle.NYI,
startlevel = cmd(R,R),
starttrack = cmd(D),
updatesector = cmd(R,R,W), updatesector = cmd(R,R,W),
updatesectorz = cmd(R,R,R,W), updatesectorz = cmd(R,R,R,W),
getactorangle = cmd(W) getactorangle = cmd(W)
/ ("%1="..SPS".ang"), / ("%1="..SPS".ang"),
setactorangle = cmd(R), setactorangle = cmd(R)
/ SPS".ang=_bit.band(%1,2047)",
getplayerangle = cmd(W) getplayerangle = cmd(W)
/ ("%1="..PLS".ang"), / ("%1="..PLS".ang"),
setplayerangle = cmd(R), setplayerangle = cmd(R)
/ PLS".ang=_bit.band(%1,2047)",
getangletotarget = cmd(W) getangletotarget = cmd(W)
/ "%1=_con._angtotarget(_aci)", / "%1=_con._angtotarget(_aci)",
@ -1787,7 +1827,6 @@ local Cinner = {
/ "%1=_gv.getticks()", / "%1=_gv.getticks()",
gettimedate = cmd(W,W,W,W,W,W,W,W) gettimedate = cmd(W,W,W,W,W,W,W,W)
/ "%1,%2,%3,%4,%5,%6,%7,%8=_con._gettimedate()", / "%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), setaspect = cmd(R,R),
} }

View file

@ -16,9 +16,10 @@ local function edist(p1, p2)
return sqrt(p1.x*p1.x + p2.x*p2.x) return sqrt(p1.x*p1.x + p2.x*p2.x)
end 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 local Nsq = numpoints*numpoints
printf("number of points: %d, testing %d distances", numpoints, Nsq) printf("number of points: %d, testing %d distances", numpoints, Nsq)
@ -54,3 +55,34 @@ end
t = os.clock()-t t = os.clock()-t
printf("ldist: %.03fns per call, mean=%.03f", (1e9*t)/Nsq, sum/Nsq) 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()!]

View file

@ -5,6 +5,8 @@ local ffi = require("ffi")
local bit = require("bit") local bit = require("bit")
local math = require("math") local math = require("math")
local geom = require("geom")
local assert = assert local assert = assert
@ -96,3 +98,15 @@ function dist(pos1, pos2)
local t = y + z local t = y + z
return x - arshift(x,4) + arshift(t,2) + arshift(t,3) return x - arshift(x,4) + arshift(t,2) + arshift(t,3)
end end
-- Point rotation. Note the different order of arguments from engine function.
-- XXX: passing mixed vec2/vec3 is problematic. Get rid of geom.vec2?
-- <ang>: 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