CON: always return non-negative values from 'clipmove' and related.

Previously, the C function clipmove() returned negative values when hit a
wall (32768+wallnum) or sprite (49152+spritenum) because internally,
these values were encoded into a *signed* 16-bit integer. This made no
difference to C code using it, since it always proceeded by bit checks,
but was inconsistent with documentation on CON 'clipmove' on the wiki.

The following commands are affected too, since they use the value returned
by clipmove(): 'clipmovenoslide', 'movesprite'. Also, the value of
actor[].movflag ('htmovflag' from CON).

Also, fix 'clipmove*' in LunaCON and add lunatic/test/checknearwall.con
as an example of how to implement a being-close-to-a-wall checker as
requested in
http://forums.duke4.net/topic/7869-determining-closeness-to-a-wall/

git-svn-id: https://svn.eduke32.com/eduke32@4874 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2015-01-04 18:44:58 +00:00
parent 2daa44ca6a
commit b0c48eec25
4 changed files with 97 additions and 7 deletions

View file

@ -2330,8 +2330,8 @@ static int32_t colnext[256];
static char coldist[8] = {0,1,2,3,4,3,2,1}; static char coldist[8] = {0,1,2,3,4,3,2,1};
static int32_t colscan[27]; static int32_t colscan[27];
static int16_t clipnum, hitwalls[4]; static int16_t clipnum;
const int32_t hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1; static const int32_t hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1;
#ifdef USE_OPENGL #ifdef USE_OPENGL
int32_t hitallsprites = 0; int32_t hitallsprites = 0;
#endif #endif
@ -13611,7 +13611,7 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
int32_t i, j, k, tempint1, tempint2; int32_t i, j, k, tempint1, tempint2;
int32_t x1, y1, x2, y2; int32_t x1, y1, x2, y2;
int32_t dax, day; int32_t dax, day;
int32_t hitwall, cnt, retval=0; int32_t retval=0;
spritetype *curspr=NULL; // non-NULL when handling sprite with sector-like clipping spritetype *curspr=NULL; // non-NULL when handling sprite with sector-like clipping
int32_t curidx=-1, clipsectcnt, clipspritecnt; int32_t curidx=-1, clipsectcnt, clipspritecnt;
@ -13933,8 +13933,9 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
} }
#endif #endif
hitwall = 0; int32_t hitwalls[4], hitwall;
cnt = clipmoveboxtracenum; int32_t cnt = clipmoveboxtracenum;
do do
{ {
int32_t intx=goalx, inty=goaly; int32_t intx=goalx, inty=goaly;
@ -13977,7 +13978,8 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
xvect = (goalx-intx)<<14; xvect = (goalx-intx)<<14;
yvect = (goaly-inty)<<14; yvect = (goaly-inty)<<14;
if (cnt == clipmoveboxtracenum) retval = clipobjectval[hitwall]; if (cnt == clipmoveboxtracenum)
retval = (uint16_t)clipobjectval[hitwall];
hitwalls[cnt] = hitwall; hitwalls[cnt] = hitwall;
} }
cnt--; cnt--;

View file

@ -1539,7 +1539,7 @@ end
function _clipmovex(x, y, z, sectnum, xv, yv, wd, cd, fd, clipmask, noslidep) function _clipmovex(x, y, z, sectnum, xv, yv, wd, cd, fd, clipmask, noslidep)
check_sector_idx(sectnum) check_sector_idx(sectnum)
local ipos = ivec3(x, y, z) local ipos = ivec3(x, y, z)
local sect = ffi.new("int16_t [1]") local sect = ffi.new("int16_t [1]", sectnum)
local ret = ffiC.clipmovex(ipos, sect, xv, yv, wd, cd, fd, clipmask, noslidep) local ret = ffiC.clipmovex(ipos, sect, xv, yv, wd, cd, fd, clipmask, noslidep)
-- Return: clipmovex() return value; updated x, y, sectnum -- Return: clipmovex() return value; updated x, y, sectnum
return ret, ipos.x, ipos.y, sect[0] return ret, ipos.x, ipos.y, sect[0]

View file

@ -3546,6 +3546,8 @@ local Grammar = Pat{
+ Range("09")^1) + Range("09")^1)
) / parse_number, ) / parse_number,
-- TODO: negated gamevars. Currently, "-var" is parsed as a negated label.
t_identifier_all = lpeg.C(t_broken_identifier + t_good_identifier), t_identifier_all = lpeg.C(t_broken_identifier + t_good_identifier),
-- NOTE: -conl.keyword alone would be wrong, e.g. "state breakobject": -- NOTE: -conl.keyword alone would be wrong, e.g. "state breakobject":
-- NOTE 2: The + "[" is so that stuff like -- NOTE 2: The + "[" is so that stuff like

View file

@ -0,0 +1,86 @@
// Inputs to "state checknearwall".
gamevar wd 128 0 // wall distance
gamevar cfd 1024 0 // ceiling/floor distance
// Outputs of "state checknearwall".
gamevar hitwall -1 0
// Temporary variables.
gamevar tmp 0 0
gamevar ret 0 0
gamevar x 0 0
gamevar y 0 0
gamevar z 0 0
gamevar sectnum 0 0
define CM_BLK_WAL 1
state getcoords
setvarvar x sprite[THISACTOR].x
setvarvar y sprite[THISACTOR].y
setvarvar z sprite[THISACTOR].z
setvarvar sectnum sprite[THISACTOR].sectnum
ends
// Inputs: (wd, cfd)
// Returns: hitwall
// -1: hit no wall
// >=0: hit that wall
state checknearwall
setvar hitwall -1
setvarvar tmp wd, shiftvarl tmp 14
state getcoords
clipmovenoslide ret (x, y, z, sectnum) (tmp, 0) (wd, cfd, cfd) CM_BLK_WAL
ifvarn ret 0 { setvarvar hitwall ret, subvar hitwall 32768, break }
state getcoords
clipmovenoslide ret (x, y, z, sectnum) (0, tmp) (wd, cfd, cfd) CM_BLK_WAL
ifvarn ret 0 { setvarvar hitwall ret, subvar hitwall 32768, break }
mulvar tmp -1
state getcoords
clipmovenoslide ret (x, y, z, sectnum) (tmp, 0) (wd, cfd, cfd) CM_BLK_WAL
ifvarn ret 0 { setvarvar hitwall ret, subvar hitwall 32768, break }
state getcoords
clipmovenoslide ret (x, y, z, sectnum) (0, tmp) (wd, cfd, cfd) CM_BLK_WAL
ifvarn ret 0 { setvarvar hitwall ret, subvar hitwall 32768, break }
ends
////////// Example usage //////////
onevent EVENT_PROCESSINPUT
state checknearwall
endevent
define Q_tmp 500
definequote Q_tmp <write on me>
define Q_no 501
definequote Q_no Hit no wall
define Q_yes 502
definequote Q_yes Hit wall %d
define Q_info 503
definequote Q_info pos: %d %d %d sect: %d
onevent EVENT_DISPLAYREST
qsprintf Q_tmp Q_info, x y z sectnum
minitext (100, 8) Q_tmp (0, 0)
ifvarn hitwall -1
{
qsprintf Q_tmp Q_yes hitwall
minitext (100, 16) Q_tmp (0, 0)
}
else
{
minitext (100, 16) Q_no (0, 0)
}
endevent