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
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

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]
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 ---

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 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);

View file

@ -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])

View file

@ -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;

View file

@ -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.

View file

@ -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),
}

View file

@ -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()!]

View file

@ -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?
-- <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