A bunch of m32script additions, fixes and general stuff, among them: local vars/arrays, inline quotes and prettier error messages.

git-svn-id: https://svn.eduke32.com/eduke32@1691 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2010-08-11 22:37:45 +00:00
parent a2d2f0ed75
commit 71e59a5502
12 changed files with 1395 additions and 957 deletions

View file

@ -62,6 +62,8 @@ extern char *mapster32_fullpath;
extern char *testplay_addparam;
extern int32_t m32_osd_tryscript;
extern int32_t showheightindicators;
extern int32_t showambiencesounds;
extern int32_t ExtInit(void);
extern int32_t ExtPreInit(int32_t argc,const char **argv);

View file

@ -34,8 +34,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAXQUOTELEN 128
// Some misc #defines
#define NO 0
#define YES 1
//#define NO 0
//#define YES 1
typedef int32_t instype;
typedef int32_t ofstype;
@ -59,7 +59,7 @@ extern void Gv_Init(void);
extern int32_t __fastcall Gv_GetVarX(register int32_t id);
extern void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue);
extern int32_t __fastcall Gv_GetVarN(register int32_t id); // 'N' for "no side-effects"... vars only!
extern int32_t __fastcall Gv_GetVarN(register int32_t id); // 'N' for "no side-effects"... vars and locals only!
extern void SetGAMEPalette(void);
extern void SetWATERPalette(void);
@ -101,6 +101,7 @@ enum GameEvent_t {
extern ofstype aEventOffsets[MAXEVENTS];
extern int32_t aEventSizes[MAXEVENTS];
extern uint8_t aEventEnabled[MAXEVENTS];
extern uint16_t aEventNumLocals[MAXEVENTS];
enum GamevarFlags_t {
@ -109,18 +110,20 @@ enum GamevarFlags_t {
MAXVARLABEL = MAXLABELLEN, //26,
GAMEVAR_PERBLOCK = 0x00000001, // per-block (state, event, or top-level) variable
GAMEVAR_USER_MASK = (0x00000001),
GAMEVAR_USER_MASK = GAMEVAR_PERBLOCK,
GAMEVAR_RESET = 0x00000008, // marks var for to default
GAMEVAR_DEFAULT = 0x00000100, // allow override
GAMEVAR_SECRET = 0x00000200, // don't dump...
GAMEVAR_SYSTEM = 0x00000800, // cannot change mode flags...(only default value)
GAMEVAR_READONLY = 0x00001000, // values are read-only (no setvar allowed)
GAMEVAR_INTPTR = 0x00002000, // plValues is a pointer to an int32_t
GAMEVAR_FLOATPTR = 0x00004000, // plValues is a pointer to a float
GAMEVAR_SHORTPTR = 0x00008000, // plValues is a pointer to a short
GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char
GAMEVAR_PTR_MASK = GAMEVAR_INTPTR|GAMEVAR_FLOATPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR,
// GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state
GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars
};
@ -128,13 +131,14 @@ enum GamevarFlags_t {
enum GamearrayFlags_t {
MAXGAMEARRAYS = (MAXGAMEVARS>>2), // must be lower than MAXGAMEVARS
MAXARRAYLABEL = MAXVARLABEL,
GAMEARRAY_NORMAL = 0,
GAMEARRAY_READONLY = 0x00001000,
GAMEARRAY_NORMAL = 0,
GAMEARRAY_OFCHAR = 0x00000001,
GAMEARRAY_OFSHORT = 0x00000002,
GAMEARRAY_OFINT = 0x00000004,
GAMEARRAY_TYPEMASK = 0x00000007,
GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT,
GAMEARRAY_VARSIZE = 0x00000020,
@ -169,6 +173,7 @@ extern uint32_t m32_drawlinepat;
extern int32_t g_iReturnVar;
extern int32_t m32_sortvar1, m32_sortvar2;
extern int32_t m32_script_expertmode; // if true, make read-only vars writable
//extern int32_t g_numRealPalettes;
//extern int32_t g_scriptDebug;
@ -228,9 +233,31 @@ extern int32_t zoom;
extern int32_t halfxdim16, midydim16;
// gamevar bytecode format:
// FEDC|BA09|8765|4321|FEDC|BA09|8765|4321
// | .. .... .... gamevar ID
// | . constant bit (checked first) / get-payload-var bit for array or struct
// | . negate bit
// | . array bit \___\ if both set:
// | . struct bit / / local var
// .... .... .... ....| optional payload
#define M32_FLAG_CONSTANT (MAXGAMEVARS)
#define M32_FLAG_NEGATE (MAXGAMEVARS<<1)
#define M32_FLAG_VAR (0)
#define M32_FLAG_ARRAY (MAXGAMEVARS<<2)
#define M32_FLAG_SPECIAL (MAXGAMEVARS<<3)
#define M32_FLAG_STRUCT (MAXGAMEVARS<<3)
#define M32_FLAG_LOCAL (M32_FLAG_ARRAY|M32_FLAG_STRUCT)
#define M32_VARTYPE_MASK (M32_FLAG_ARRAY|M32_FLAG_STRUCT)
#define M32_FLAG_CONSTANTINDEX M32_FLAG_CONSTANT
// if set, fetch index for array or struct array from 16 high bits as a constant (otherwise: gamevar)
#define M32_BITS_MASK (0x0000ffff-(MAXGAMEVARS-1))
// IDs of special vars
#define M32_SPRITE_VAR_ID 0
@ -244,6 +271,8 @@ extern int32_t halfxdim16, midydim16;
#define M32_HITAG_VAR_ID 7
#define M32_TEXTURE_VAR_ID 8
#define M32_LOCAL_ARRAY_ID 0
#define M32_PRINTERROR(Text, ...) OSD_Printf(OSD_ERROR "Line %d, %s: " Text "\n", g_errorLineNum, keyw[g_tw], ## __VA_ARGS__)
#endif

View file

@ -486,8 +486,6 @@ int32_t app_main(int32_t argc, const char **argv)
totalclock = 0;
OSD_Exec("m32_autoexec.cfg");
updatesector(pos.x,pos.y,&cursectnum);
if (cursectnum == -1)
@ -507,6 +505,10 @@ int32_t app_main(int32_t argc, const char **argv)
Bprintf("%d * %d not supported in this graphics mode\n",xdim2d,ydim2d);
exit(0);
}
// executed once per init, but after setgamemode so that OSD has the right width
OSD_Exec("m32_autoexec.cfg");
overheadeditor();
keystatus[buildkeys[BK_MODE2D_3D]] = 0;
@ -527,6 +529,10 @@ int32_t app_main(int32_t argc, const char **argv)
Bprintf("%d * %d not supported in this graphics mode\n",xdim,ydim);
exit(0);
}
// executed once per init, but after setgamemode so that OSD has the right width
OSD_Exec("m32_autoexec.cfg");
setbrightness(GAMMA_CALC,palette,0);
}
CANCEL:
@ -2463,13 +2469,8 @@ void overheadeditor(void)
for (i=0; i<numwalls; i++) //make new red lines?
{
if (wall[i].x == dax && wall[i].y == day)
{
checksectorpointer((int16_t)i,sectorofwall((int16_t)i));
fixrepeats((int16_t)i);
asksave = 1;
}
else if (POINT2(i).x == dax && POINT2(i).y == day)
if ((wall[i].x == dax && wall[i].y == day)
|| (POINT2(i).x == dax && POINT2(i).y == day))
{
checksectorpointer((int16_t)i,sectorofwall((int16_t)i));
fixrepeats((int16_t)i);

View file

@ -66,7 +66,6 @@ extern int32_t remapinit;
extern double msens;
extern int32_t editorgridextent, grid, autogrid;
static int32_t default_grid=3;
extern int32_t showheightindicators;
extern int32_t graphicsmode;
extern int32_t AmbienceToggle;
extern int32_t ParentalLock;
@ -236,6 +235,8 @@ int32_t loadsetup(const char *fn)
if (readconfig(fp, "showheightindicators", val, VL) > 0)
showheightindicators = min(max(Batoi(val),0),2);
if (readconfig(fp, "showambiencesounds", val, VL) > 0)
showheightindicators = min(max(Batoi(val),0),2);
if (readconfig(fp, "graphicsmode", val, VL) > 0)
graphicsmode = min(max(Batoi(val),0),2);
@ -417,6 +418,9 @@ int32_t writesetup(const char *fn)
"; Height indicators (0:none, 1:only 2-sided&different, 2:all)\n"
"showheightindicators = %d\n"
"\n"
"; Ambience sound circles (0:none, 1:only in current sector, 2:all)\n"
"showambiencesounds = %d\n"
"\n"
"; 2D mode display type (0:classic, 1:textured, 2:textured/animated)\n"
"graphicsmode = %d\n\n"
"; Ambient sounds in 3D mode (0:off, 1:on)\n"
@ -499,7 +503,7 @@ int32_t writesetup(const char *fn)
#endif
option[3], msens, unrealedlook, pk_uedaccel, quickmapcycling,
revertCTRL,scrollamount,pk_turnaccel,pk_turndecel,autosave,
showheightindicators,graphicsmode,AmbienceToggle,ParentalLock,
showheightindicators,showambiencesounds,graphicsmode,AmbienceToggle,ParentalLock,
!!m32_osd_tryscript,
#if 1
keys[0], keys[1], keys[2], keys[3], keys[4], keys[5],

View file

@ -4,7 +4,6 @@
include names.h
// flag 1: per-block (top-level, event, or state) variable
gamevar h 0 1
gamevar i 0 1
gamevar j 0 1
gamevar k 0 1
@ -14,17 +13,9 @@ gamevar p 0 1
gamevar q 0 1
gamevar r 0 1
gamearray xx 10
gamearray yy 10
gamevar c 0 0
gamevar d 0 0
gamevar x 0 0
gamevar y 0 0
gamevar x2 0 0
gamevar y2 0 0
gamevar z 0 0
gamevar frac 0 0
gamevar gi 0 0
gamevar gj 0 0
@ -45,37 +36,16 @@ gamevar dayx 65536 0
gamevar drawcol 9 0
define TQUOTE 3
definequote 0 OK
definequote 1 DAMN
define TQUOTE 0
definequote TQUOTE >>> write on me! <<<
definequote 2 BU:%d ABS:%d
definequote TQUOTE write on me!
//light
define LIGHTQUOTE 1
// x y z r g b mins maxs
definequote LIGHTQUOTE light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d
// sec range radius fade ang horiz prio tile
definequote 4 ASPECT: VR=%d, YX=%d
definequote 5 ALPHA KEY: %d (SCANCODE: %d)
definequote 6 time: %d ms
definequote 7 door sector not an island sector!
definequote 8 door sector has no SE sprite!
//light x y z r g b mins maxs
definequote 9 light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d
// sec range radius fade ang horiz prio tile
definequote 10 --PRLIGHTS--
definequote 11 --ENDPRLIGHTS--
definequote 12 RED:
definequote 13 GREEN:
definequote 14 BLUE:
definequote 15 x/yoffset: %d %d
definequote 16 RGB color: %d %d %d
definequote 17 PICNUM:
definequote 18 NUMBER KEY: %d (SCANCODE: %d)
// Corruption checker
definequote 19 PANIC!!! SECTOR OR WALL LIMIT EXCEEDED!!!
@ -86,66 +56,18 @@ definequote 23 WALL[%d].POINT2=%d out of range: sector[%d].wallptr=%d, endwall=%
definequote 24 WALL[%d].NEXTWALL=%d out of range: numwalls=%d!!!
definequote 25 WALL[%d].NEXTSECTOR=%d out of range: numsectors=%d!!!
definequote 26 FLOAT ACCESS TEST
definequote 27 OVERRIDE POLYMER PARALLAX & SPECULAR: OFF
definequote 28 OVERRIDE POLYMER PARALLAX & SPECULAR: ON
definequote 29 PARALLAX SCALE: %f
definequote 30 PARALLAX BIAS: %f
definequote 31 SPECULAR FACTOR: %f
definequote 32 SPECULAR POWER: %f
definequote 33 PAL: %d
define PRSCALE 1000
// NOTE: inline constants >=32768 are sometimes broken ATM (when loading a second time?).
// This should always work
define MAXSPECULAR 100000
gamearray ar 128
gamearray parm 8
// various tests of m32-script features
defstate tests
// array test
getarraysize ar tmp
resizearray ar 65536
getticks parm[2]
for j range 65536
set ar[j] j
set i 0
for j range 65536
add i ar[j]
getticks parm[3]
resizearray ar tmp
ife i 2147450880 quote 0 else quote 1
sub parm[3] parm[2]
qsprintf TQUOTE 6 parm[3]
quote TQUOTE
// iteration and break test
for i range 10
{
addlogvar i
ife i 5 break
}
ife i 5 quote 0 else quote 1
quote 26
set tmp pr_parallaxscale
set gi tmp set gj tmp set gk tmp
al gi al gj al gk
ftoi gi 20 ftoi gj 200 ftoi gk 2000
al gi al gj al gk
mul gk 2
itof gk 2000
ends
// prints out maphack light definitions based on SE lights in map
defstate printlights
print 10
print "--PRLIGHTS--"
for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50
{
ife .lotag 50
@ -166,13 +88,13 @@ defstate printlights
else
set l 2
}
// range r g b
qsprintf TQUOTE 9 .sectnum .x .y .z .hitag .xvel .yvel .zvel
j k .ang .extra .xoffset .yoffset l .owner
// radius fade horiz minshade maxshade prio tile
// range r g b
qsprintf TQUOTE LIGHTQUOTE .sectnum .x .y .z .hitag .xvel .yvel .zvel
j k .ang .extra .xoffset .yoffset l .owner
// radius fade horiz minshade maxshade prio tile
print TQUOTE
}
print 11
print "--ENDPRLIGHTS--"
ends
// convenient polymer SE light manipulation with keypad keys
@ -245,7 +167,7 @@ defstate fiddlewithlights
ftoi k PRSCALE // must convert to scaled integer, scale is 1:PRSCALE
add k j, clamp k -10000 10000
itof k PRSCALE // convert back
qsprintf TQUOTE 29 k, quote TQUOTE
qsprintf TQUOTE "PARALLAX SCALE: %f" k, quote TQUOTE
set pr_parallaxscale k
break;
}
@ -253,23 +175,23 @@ defstate fiddlewithlights
{
set k pr_parallaxbias
ftoi k PRSCALE, add k j, clamp k -10000 10000, itof k PRSCALE
qsprintf TQUOTE 30 k, quote TQUOTE
qsprintf TQUOTE "PARALLAX BIAS: %f" k, quote TQUOTE
set pr_parallaxbias k
break;
}
case 3:
{
set k pr_specularfactor
ftoi k PRSCALE, add k j, clamp k -10000 MAXSPECULAR, itof k PRSCALE
qsprintf TQUOTE 31 k, quote TQUOTE
ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE
qsprintf TQUOTE "SPECULAR FACTOR: %f" k, quote TQUOTE
set pr_specularfactor k
break;
}
case 4:
{
set k pr_specularpower
ftoi k PRSCALE, add k j, clamp k -10000 MAXSPECULAR, itof k PRSCALE
qsprintf TQUOTE 32 k, quote TQUOTE
ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE
qsprintf TQUOTE "SPECULAR POWER: %f" k, quote TQUOTE
set pr_specularpower k
break;
}
@ -282,36 +204,39 @@ defstate fiddlewithlights
{
set i searchwall, seti i // set current sprite = targeted sprite
// horiz
ifeithershift set j 1 else set j 10
ifhitkey KEY_gUP add .extra j
else ifhitkey KEY_gKP5 sub .extra j
clamp .extra -500 500
ife .lotag 50
{
// horiz
ifeithershift set j 1 else set j 10
ifhitkey KEY_gUP add .extra j
else ifhitkey KEY_gKP5 sub .extra j
clamp .extra -500 500
// angle
set j 128
ifeitherctrl set j 4
ifeithershift { ifeitherctrl set j 1 else set j 32 }
ifhitkey KEY_gLEFT sub .ang j
else ifhitkey KEY_gRIGHT add .ang j
// angle
set j 128
ifeitherctrl set j 4
ifeithershift { ifeitherctrl set j 1 else set j 32 }
ifhitkey KEY_gLEFT sub .ang j
else ifhitkey KEY_gRIGHT add .ang j
// radius
ifeitherctrl
{
ifholdkey KEY_gMINUS add .shade 9
else ifholdkey KEY_gPLUS sub .shade 9
clamp .shade -118 117
}
}
// range
ifeithershift set j 10
else ifeitherctrl set j 1000
else set j 100
ifhitkey KEY_gPGUP add .hitag j
else ifhitkey KEY_gHOME sub .hitag j
ifhitkey KEY_KP9 add .hitag j
else ifhitkey KEY_KP7 sub .hitag j
clamp .hitag 0 16000
// radius
ifeitherctrl
{
ifholdkey KEY_gMINUS add .shade 9
else ifholdkey KEY_gPLUS sub .shade 9
clamp .shade -118 117
}
// min/max shade
ifeithershift set j -1 else set j 1
ifeitherctrl
@ -330,7 +255,7 @@ defstate fiddlewithlights
ife k 1
{
qsprintf TQUOTE 15 .xoffset .yoffset
qsprintf TQUOTE "XY offset: %d %d" .xoffset .yoffset
quote TQUOTE
}
}
@ -338,15 +263,15 @@ defstate fiddlewithlights
// color/picnum
ifeitheralt
{
ifhitkey KEY_gEND
ifhitkey KEY_KP1
{
getnumber256 .xvel 12 255
getnumber256 .yvel 13 255
getnumber256 .zvel 14 255
getnumber256 .xvel "RED:" 255
getnumber256 .yvel "GREEN:" 255
getnumber256 .zvel "BLUE:" 255
}
else ifhitkey KEY_gDOWN
else ifhitkey KEY_KP2
{
getnumber256 .owner 17 -MAXTILES
getnumber256 .owner "PICNUM:" -MAXTILES
}
}
else
@ -355,9 +280,9 @@ defstate fiddlewithlights
ifeithershift inv j
set k 0
ifhitkey KEY_gEND { add .xvel j, set k 1 }
ifhitkey KEY_gDOWN { add .yvel j, set k 1 }
ifhitkey KEY_gPGDN { add .zvel j, set k 1 }
ifhitkey KEY_KP1 { add .xvel j, set k 1 }
ifhitkey KEY_KP2 { add .yvel j, set k 1 }
ifhitkey KEY_KP3 { add .zvel j, set k 1 }
ife k 1
{
@ -365,35 +290,13 @@ defstate fiddlewithlights
clamp .yvel 1 255
clamp .zvel 1 255
qsprintf TQUOTE 16 .xvel .yvel .zvel
qsprintf TQUOTE "RGB color: %d %d %d" .xvel .yvel .zvel
quote TQUOTE
}
}
}
ends
/*
defstate testkeyavail
for i range 27
{
ifholdkey alphakeys[i]
{
qsprintf TQUOTE 5 i alphakeys[i]
quote TQUOTE
}
}
for i range 10
{
ifholdkey numberkeys[i]
{
qsprintf TQUOTE 18 i numberkeys[i]
quote TQUOTE
}
}
ends
*/
// rotate highlighted sprites around selected (closest to mouse) sprite
// global parameter: dang
defstate rotselspr
@ -488,7 +391,12 @@ onevent EVENT_DRAW2DSCREEN
*/
////////// polymer light 2d projections //////////
set tmp drawlinepat
var c d h x2 y2 oldpat
array xx 2
array yy 2
set oldpat drawlinepat
set drawlinepat 0x11111111
for i spritesofsector cursectnum
{
@ -548,7 +456,7 @@ onevent EVENT_DRAW2DSCREEN
}
}
}
set drawlinepat tmp
set drawlinepat oldpat
endevent
// LOCATORS auto-incrementer
@ -727,25 +635,6 @@ ends
onevent EVENT_ANALYZESPRITES
state tduprot
state tduplin
/*
ife searchstat 3
for i drawnsprites
{
ife tsprite[i].owner searchwall
{
qsprintf TQUOTE 33 tsprite[i].pal
quote TQUOTE
break
}
// switch sprite[j].picnum
// case LIZTROOP spritepal 1 break
// case PIGCOP spritepal 2 break
// case BOSS1 spritepal 6 break
// endswitch
}
*/
endevent
onevent EVENT_KEYS3D
@ -790,7 +679,7 @@ onevent EVENT_KEYS3D
// }
ifn tmp 0
{
quote 7
quote "door sector not an island sector!"
return
}
@ -805,7 +694,7 @@ onevent EVENT_KEYS3D
}
ifl l 0
{
quote 8
quote "door sector has no SE sprite!"
return
}
@ -868,7 +757,7 @@ onevent EVENT_KEYS3D
ifl davr 32768 set davr 32768
ifg davr 256000 set davr 256000
setaspect davr yxaspect
qsprintf TQUOTE 4 davr yxaspect
qsprintf TQUOTE "ASPECT: VR=%d, YX=%d" davr yxaspect
quote TQUOTE
}
endevent
@ -917,10 +806,10 @@ ends
// Map corruption checker
gamevar ewall 0 0
gamevar endwall 0 0
defstate corruptchk
var ewall
var endwall
ifle numsectors MAXSECTORS ifle numwalls MAXWALLS nullop else
{ quote 19 printmessage16 19 return }

View file

@ -0,0 +1,152 @@
// load a.m32 first
defstate testkeyavail
for i range 27
{
ifholdkey alphakeys[i]
{
qsprintf TQUOTE "ALPHA KEY: %d (SCANCODE: %d)" i alphakeys[i]
quote TQUOTE
}
}
for i range 10
{
ifholdkey numberkeys[i]
{
qsprintf TQUOTE "NUMBER KEY: %d (SCANCODE: %d)" i numberkeys[i]
quote TQUOTE
}
}
ends
// various tests of m32-script features
defstate arraytest
getarraysize ar tmp
resizearray ar 65536
getticks parm[2]
for j range 65536
set ar[j] j
set i 0
for j range 65536
add i ar[j]
getticks parm[3]
resizearray ar tmp
ife i 2147450880 quote "OK" else quote "DAMN"
sub parm[3] parm[2]
qsprintf TQUOTE "time: %d ms" parm[3]
quote TQUOTE
ends
defstate itertest
// iteration and break test
for i range 10
{
addlogvar i
ife i 5 break
}
ife i 5 quote "OK" else quote "DAMN"
quote "FLOAT ACCESS TEST"
set tmp pr_parallaxscale
set gi tmp set gj tmp set gk tmp
al gi al gj al gk
ftoi gi 20 ftoi gj 200 ftoi gk 2000
al gi al gj al gk
mul gk 2
itof gk 2000
ends
define TEST_ZERO 0
define TEST_PLUS_ONE 1
define TEST_MINUS_ONE -1
define MOST_POSITIVE_DIRECT 32767
define MOST_NEGATIVE_DIRECT -32768
define LEAST_POSITIVE_INDIRECT 32768
define LEAST_NEGATIVE_INDIRECT -32769
define HEX_MOST_POSITIVE_DIRECT 0x7fff
define HEX_MOST_NEGATIVE_DIRECT 0xffff8000
define HEX_LEAST_POSITIVE_INDIRECT 0x8000
define HEX_LEAST_NEGATIVE_INDIRECT 0xffff7fff
define MAX_CONSTANT 2147483647
define MIN_CONSTANT -2147483648
// tests various combinations of constants and labels
defstate consttest
quote " --- Constants test ---", quote " "
quote "Shoud be 0:"
set i 0, set j TEST_ZERO
qsprintf TQUOTE "%d %d %d %d" 0 TEST_ZERO i j
quote TQUOTE, quote " "
quote "Shoud be 1:"
set i 1, set j TEST_PLUS_ONE
qsprintf TQUOTE "%d %d %d %d" 1 TEST_PLUS_ONE i j
quote TQUOTE, quote " "
quote "Shoud be -1:"
set i -1, set j TEST_MINUS_ONE
qsprintf TQUOTE "%d %d %d %d" -1 TEST_MINUS_ONE i j
quote TQUOTE, quote " "
quote "Shoud be 32767:"
set i 32767, set j MOST_POSITIVE_DIRECT
qsprintf TQUOTE "%d %d %d %d" 32767 MOST_POSITIVE_DIRECT i j
quote TQUOTE, quote " "
quote "Shoud be -32768:"
set i -32768, set j MOST_NEGATIVE_DIRECT
qsprintf TQUOTE "%d %d %d %d" -32768 MOST_NEGATIVE_DIRECT i j
quote TQUOTE, quote " "
quote "Shoud be 32768:"
set i 32768, set j LEAST_POSITIVE_INDIRECT
qsprintf TQUOTE "%d %d %d %d" 32768 LEAST_POSITIVE_INDIRECT i j
quote TQUOTE, quote " "
quote "Shoud be -32769:"
set i -32769, set j LEAST_NEGATIVE_INDIRECT
qsprintf TQUOTE "%d %d %d %d" -32769 LEAST_NEGATIVE_INDIRECT i j
quote TQUOTE, quote " "
quote "Hex tests:"
quote "Shoud be 32767:"
set i 0x7fff, set j HEX_MOST_POSITIVE_DIRECT
qsprintf TQUOTE "%d %d %d %d" 0x7fff HEX_MOST_POSITIVE_DIRECT i j
quote TQUOTE, quote " "
quote "Shoud be -32768:"
set i 0xffff8000, set j HEX_MOST_NEGATIVE_DIRECT
qsprintf TQUOTE "%d %d %d %d" 0xffff8000 HEX_MOST_NEGATIVE_DIRECT i j
quote TQUOTE, quote " "
quote "Shoud be 32768:"
set i 0x8000, set j HEX_LEAST_POSITIVE_INDIRECT
qsprintf TQUOTE "%d %d %d %d" 0x8000 HEX_LEAST_POSITIVE_INDIRECT i j
quote TQUOTE, quote " "
quote "Shoud be -32769:"
set i 0xffff7fff, set j HEX_LEAST_NEGATIVE_INDIRECT
qsprintf TQUOTE "%d %d %d %d" 0xffff7fff HEX_LEAST_NEGATIVE_INDIRECT i j
quote TQUOTE, quote " "
quote "min/max tests:"
quote "Shoud be 2147483647:"
set i 2147483647, set j MAX_CONSTANT
qsprintf TQUOTE "%d %d %d %d" 2147483647 MAX_CONSTANT i j
quote TQUOTE, quote " "
quote "Shoud be -2147483648:"
set i -2147483648, set j MIN_CONSTANT
qsprintf TQUOTE "%d %d %d %d" -2147483648 MIN_CONSTANT i j
quote TQUOTE, quote " "
ends

View file

@ -94,6 +94,8 @@ static struct strllist
const char *scripthist[SCRIPTHISTSIZ];
int32_t scripthistend = 0;
int32_t showambiencesounds=2;
//////////////////// Key stuff ////////////////////
#define eitherALT (keystatus[KEYSC_LALT] || keystatus[KEYSC_RALT])
@ -7318,19 +7320,6 @@ static int32_t osdcmd_testplay_addparam(const osdfuncparm_t *parm)
return OSDCMD_OK;
}
static int32_t osdcmd_showheightindicators(const osdfuncparm_t *parm)
{
extern int32_t showheightindicators;
if (parm->numparms == 1)
showheightindicators = clamp(atoi(parm->parms[0]), 0, 2);
OSD_Printf("height indicators: %s\n",
showheightindicators==0 ? "none" :
(showheightindicators==1 ? "two-sided walls only" : "all"));
return OSDCMD_OK;
}
//PK vvv ------------
static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
@ -7368,20 +7357,55 @@ static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
}
else if (!Bstrcasecmp(parm->name, "pk_uedaccel"))
{
if (showval)
OSD_Printf("UnrealEd mouse navigation acceleration is %d\n", pk_uedaccel);
else
if (parm->numparms==1)
{
pk_uedaccel = atoi(parm->parms[0]);
pk_uedaccel = pk_uedaccel<0 ? 0:pk_uedaccel;
pk_uedaccel = pk_uedaccel>5 ? 5:pk_uedaccel;
}
if (parm->numparms <= 1)
OSD_Printf("UnrealEd mouse navigation acceleration is %d\n", pk_uedaccel);
else
return OSDCMD_SHOWHELP;
}
else if (!Bstrcasecmp(parm->name, "osd_tryscript"))
{
m32_osd_tryscript = !m32_osd_tryscript;
OSD_Printf("Try M32 script execution on invalid OSD command: %s\n", m32_osd_tryscript?"on":"off");
}
else if (!Bstrcasecmp(parm->name, "script_expertmode"))
{
m32_script_expertmode = !m32_script_expertmode;
if (m32_script_expertmode)
OSD_Printf("M32 Script expert mode ENABLED. Be sure to know what you are doing!\n");
else
OSD_Printf("M32 Script expert mode DISABLED.\n");
}
else if (!Bstrcasecmp(parm->name, "show_heightindicators"))
{
static const char *how[3] = {"none", "two-sided walls only", "all"};
if (parm->numparms == 1)
showheightindicators = clamp(atoi(parm->parms[0]), 0, 2);
if (parm->numparms <= 1)
OSD_Printf("height indicators: %s\n", how[showheightindicators]);
else
return OSDCMD_SHOWHELP;
}
else if (!Bstrcasecmp(parm->name, "show_ambiencesounds"))
{
static const char *how[3] = {"none", "current sector only", "all"};
if (parm->numparms == 1)
showambiencesounds = clamp(atoi(parm->parms[0]), 0, 2);
if (parm->numparms <= 1)
OSD_Printf("ambience sound circles: %s\n", how[showambiencesounds]);
else
return OSDCMD_SHOWHELP;
}
return OSDCMD_OK;
}
@ -7615,18 +7639,19 @@ static int32_t registerosdcommands(void)
OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip);
OSD_RegisterFunction("quit","quit: exits the game immediately", osdcmd_quit);
OSD_RegisterFunction("exit","exit: exits the game immediately", osdcmd_quit);
OSD_RegisterFunction("quit","quit: exits the editor immediately", osdcmd_quit);
OSD_RegisterFunction("exit","exit: exits the editor immediately", osdcmd_quit);
OSD_RegisterFunction("sensitivity","sensitivity <value>: changes the mouse sensitivity", osdcmd_sensitivity);
//PK
OSD_RegisterFunction("pk_turnaccel", "pk_turnaccel: sets turning acceleration", osdcmd_vars_pk);
OSD_RegisterFunction("pk_turndecel", "pk_turndecel: sets turning deceleration", osdcmd_vars_pk);
OSD_RegisterFunction("pk_uedaccel", "pk_uedaccel: sets UnrealEd movement speed factor (0-5, exponentially)", osdcmd_vars_pk);
OSD_RegisterFunction("pk_quickmapcycling", "pk_quickmapcycling: allows cycling of maps with (Shift-)Ctrl-X", osdcmd_vars_pk);
OSD_RegisterFunction("testplay_addparam", "testplay_addparam \"string\": set additional parameters for test playing", osdcmd_testplay_addparam);
OSD_RegisterFunction("showheightindicators", "showheightindicators [012]: toggles height indicators in 2D mode", osdcmd_showheightindicators);
OSD_RegisterFunction("pk_turnaccel", "pk_turnaccel <value>: sets turning acceleration+deceleration", osdcmd_vars_pk);
OSD_RegisterFunction("pk_turndecel", "pk_turndecel <value>: sets turning deceleration", osdcmd_vars_pk);
OSD_RegisterFunction("pk_uedaccel", "pk_uedaccel <value>: sets UnrealEd movement speed factor (0-5, exponentially)", osdcmd_vars_pk);
OSD_RegisterFunction("pk_quickmapcycling", "pk_quickmapcycling: toggles quick cycling of maps with (Shift-)Ctrl-X", osdcmd_vars_pk);
OSD_RegisterFunction("testplay_addparam", "testplay_addparam \"string\": sets additional parameters for test playing", osdcmd_testplay_addparam);
OSD_RegisterFunction("show_heightindicators", "show_heightindicators <0, 1 or 2>: sets display of height indicators in 2D mode", osdcmd_vars_pk);
OSD_RegisterFunction("show_ambiencesounds", "show_ambiencesounds <0, 1 or 2>: sets display of MUSICANDSFX circles in 2D mode", osdcmd_vars_pk);
#ifdef POLYMOST
OSD_RegisterFunction("tint", "tint <pal> <r> <g> <b> <flags>: queries or sets hightile tinting", osdcmd_tint);
#endif
@ -7634,10 +7659,11 @@ static int32_t registerosdcommands(void)
// M32 script
OSD_RegisterFunction("include", "include <filnames...>: compiles one or more M32 script files", osdcmd_include);
OSD_RegisterFunction("do", "do (m32 script ...): executes M32 script statements", osdcmd_do);
OSD_RegisterFunction("scriptinfo", "scriptinfo: shows information about compiled M32 script", osdcmd_scriptinfo);
OSD_RegisterFunction("script_info", "script_info: shows information about compiled M32 script", osdcmd_scriptinfo);
OSD_RegisterFunction("script_expertmode", "script_expertmode: toggles M32 script expert mode", osdcmd_vars_pk);
OSD_RegisterFunction("enableevent", "enableevent <all|EVENT_...|(event number)>", osdcmd_endisableevent);
OSD_RegisterFunction("disableevent", "disableevent <all|EVENT_...|(event number)>", osdcmd_endisableevent);
OSD_RegisterFunction("osd_tryscript", "osd_tryscript: Toggles execution of M32 script on invalid OSD command", osdcmd_vars_pk);
OSD_RegisterFunction("osd_tryscript", "osd_tryscript: toggles execution of M32 script on invalid OSD command", osdcmd_vars_pk);
// OSD_RegisterFunction("disasm", "disasm [s|e] <state or event number>", osdcmd_disasm);
return 0;
}
@ -9008,22 +9034,26 @@ void ExtPreCheckKeys(void) // just before drawrooms
}
}
for (i=0; i<numsprites; i++)
if (sprite[i].picnum == 5 /*&& zoom >= 256*/ && sprite[i].sectnum != MAXSECTORS)
{
xp1 = mulscale14(sprite[i].x-pos.x,zoom);
yp1 = mulscale14(sprite[i].y-pos.y,zoom);
if (showambiencesounds)
for (i=0; i<numsprites; i++)
if (sprite[i].picnum == MUSICANDSFX /*&& zoom >= 256*/ && sprite[i].sectnum != MAXSECTORS)
{
if (showambiencesounds==1 && sprite[i].sectnum!=cursectnum)
continue;
radius = mulscale14(sprite[i].hitag,zoom);
col = 6;
if (i+16384 == pointhighlight)
if (totalclock & 32) col += (2<<2);
drawlinepat = 0xf0f0f0f0;
drawcircle16(halfxdim16+xp1, midydim16+yp1, radius, editorcolors[(int32_t)col]);
drawlinepat = 0xffffffff;
// radius = mulscale15(sprite[i].hitag,zoom);
// drawcircle16(halfxdim16+xp1, midydim16+yp1, radius, col);
}
xp1 = mulscale14(sprite[i].x-pos.x,zoom);
yp1 = mulscale14(sprite[i].y-pos.y,zoom);
radius = mulscale14(sprite[i].hitag,zoom);
col = 6;
if (i+16384 == pointhighlight)
if (totalclock & 32) col += (2<<2);
drawlinepat = 0xf0f0f0f0;
drawcircle16(halfxdim16+xp1, midydim16+yp1, radius, editorcolors[(int32_t)col]);
drawlinepat = 0xffffffff;
// radius = mulscale15(sprite[i].hitag,zoom);
// drawcircle16(halfxdim16+xp1, midydim16+yp1, radius, col);
}
enddrawing();
}

File diff suppressed because it is too large Load diff

View file

@ -25,23 +25,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef _m32def_h_
#define _m32def_h_
#define ABORTERRCNT 8
// the parsing routines aren't good at error recovery yet...
#define ABORTERRCNT 1
// these two are for m32def.c
#define C_CUSTOMERROR(Text, ...) do { \
C_ReportError(-1); \
initprintf("%s:%d: error: " Text "\n", g_szScriptFileName, g_lineNumber, ## __VA_ARGS__); \
PrintErrorPosition(); \
g_numCompilerErrors++; \
} while (0)
#define C_CUSTOMWARNING(Text, ...) do { \
C_ReportError(-1); \
initprintf("%s:%d: warning: " Text "\n", g_szScriptFileName, g_lineNumber, ## __VA_ARGS__); \
PrintErrorPosition(); \
g_numCompilerWarnings++; \
} while (0)
extern char g_szScriptFileName[BMAX_PATH];
extern int32_t g_totalLines,g_lineNumber;
extern int32_t g_numCompilerErrors,g_numCompilerWarnings;
extern int32_t g_totalLines, g_lineNumber;
extern int32_t g_numCompilerErrors, g_numCompilerWarnings;
extern int32_t g_didDefineSomething;
@ -52,8 +55,9 @@ void C_CompilationInfo(void);
typedef struct
{
int32_t ofs;
int32_t ofs; // offset into script[]
int32_t codesize;
uint16_t numlocals; // number of local int32_t vars to allocate
char name[MAXLABELLEN];
} statesinfo_t;
@ -99,7 +103,6 @@ extern vmstate_t vm_default;
extern int32_t g_errorLineNum;
extern int32_t g_tw;
extern const char *keyw[];
enum SystemString_t {
@ -228,6 +231,7 @@ enum IterationTypes_t
ITER_SELSECTORS,
ITER_SELWALLS,
ITER_DRAWNSPRITES,
// ---
ITER_SPRITESOFSECTOR,
ITER_WALLSOFSECTOR,
ITER_LOOPOFWALL,

View file

@ -151,6 +151,12 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
{
instype *oinsptr=insptr;
vmstate_t vm_backup;
void *olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals;
void *localvars = alloca(aEventNumLocals[iEventID] * sizeof(int32_t));
// needed since any read access before initialization would cause undefined behaviour
if (aEventNumLocals[iEventID] > 0)
Bmemset(localvars, aEventNumLocals[iEventID]*sizeof(int32_t), 0);
Bmemcpy(&vm_backup, &vm, sizeof(vmstate_t));
@ -163,7 +169,10 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
vm.flags = 0;
insptr = script + aEventOffsets[iEventID];
aGameArrays[M32_LOCAL_ARRAY_ID].vals = localvars;
VM_Execute(0);
aGameArrays[M32_LOCAL_ARRAY_ID].vals = olocalvars;
if (vm.flags&VMFLAG_ERROR)
{
@ -278,6 +287,26 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
vm.flags |= VMFLAG_ERROR; \
continue; \
} \
static char *GetMaybeInlineQuote(int32_t quotei)
{
char *quotetext;
if (quotei==-1)
{
quotetext = (char *)insptr;
while (*insptr++) /* skip the string */;
}
else
{
quotei = Gv_GetVarX(quotei);
do { X_ERROR_INVALIDQUOTE(quotei, ScriptQuotes) } while (0);
if (vm.flags&VMFLAG_ERROR)
return NULL;
quotetext = ScriptQuotes[quotei];
}
return quotetext;
}
int32_t VM_Execute(int32_t once)
{
@ -311,10 +340,18 @@ skip_check:
{
instype *tempscrptr = insptr+2;
int32_t stateidx = *(insptr+1), o_g_st = vm.g_st, oret=vm.flags&VMFLAG_RETURN;
void *olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals;
void *localvars = alloca(statesinfo[stateidx].numlocals * sizeof(int32_t));
// needed since any read access before initialization would cause undefined behaviour
if (statesinfo[stateidx].numlocals > 0)
Bmemset(localvars, statesinfo[stateidx].numlocals*sizeof(int32_t), 0);
insptr = script + statesinfo[stateidx].ofs;
vm.g_st = 1+MAXEVENTS+stateidx;
aGameArrays[M32_LOCAL_ARRAY_ID].vals = localvars;
VM_Execute(0);
aGameArrays[M32_LOCAL_ARRAY_ID].vals = olocalvars;
vm.g_st = o_g_st;
vm.flags &= ~VMFLAG_RETURN;
vm.flags |= oret;
@ -544,7 +581,7 @@ skip_check:
if (asize<=0 || asize>65536)
{
M32_PRINTERROR("Invalid array size %d (max: 65536)");
M32_PRINTERROR("Invalid array size %d (must be between 1 and 65536)", asize);
vm.flags |= VMFLAG_ERROR;
continue;
}
@ -598,7 +635,7 @@ skip_check:
if ((sidx+numelts) > ssiz) numelts = ssiz-sidx;
if ((didx+numelts) > dsiz) numelts = dsiz-didx;
switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPEMASK)
switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0:
case GAMEARRAY_OFINT:
@ -1150,13 +1187,13 @@ skip_check:
if (state < 0)
{
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t( *)(const void *,const void *))X_DoSortDefault);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void *,const void *))X_DoSortDefault);
}
else
{
x_sortingstateptr = script + statesinfo[state].ofs;
vm.g_st = 1+MAXEVENTS+state;
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t( *)(const void *,const void *))X_DoSort);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void *,const void *))X_DoSort);
vm.g_st = o_g_st;
insptr = end;
}
@ -2025,16 +2062,20 @@ badindex:
char pp1[4][8] = {"sprite","sector","wall","tsprite"};
const memberlabel_t *pp2[4] = {SpriteLabels, SectorLabels, WallLabels, SpriteLabels};
if ((code&M32_FLAG_ARRAY) || (code&M32_FLAG_SPECIAL))
if ((code&M32_VARTYPE_MASK)==M32_FLAG_ARRAY || (code&M32_VARTYPE_MASK)==M32_FLAG_STRUCT)
{
if (code&MAXGAMEVARS)
if (code&M32_FLAG_CONSTANT)
Bsprintf(buf2, "%d", (code>>16)&0xffff);
else
Bsprintf(buf2, "%s", aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel?
aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel:"???");
{
char *label = aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel;
Bsprintf(buf2, "%s", label?label:"???");
}
}
else if ((code&M32_VARTYPE_MASK)==M32_FLAG_LOCAL)
Bsprintf(buf2, "%d", code&(MAXGAMEVARS-1));
if ((code&0x0000FFFC) == MAXGAMEVARS) // addlogvar for a constant.. why not? :P
if ((code&0x0000FFFC) == M32_FLAG_CONSTANT) // addlogvar for a constant.. why not? :P
{
switch (code&3)
{
@ -2044,13 +2085,25 @@ badindex:
default: Bsprintf(buf, "(??? constant)"); break;
}
}
else if (code&M32_FLAG_ARRAY)
Bsprintf(buf, "%s[%s]", aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel?
aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2);
else if (code&M32_FLAG_SPECIAL)
Bsprintf(buf, "%s[%s].%s", pp1[code&3], buf2, pp2[code&3][(code>>2)&31].name);
else
Bsprintf(buf, "???");
{
switch (code&M32_VARTYPE_MASK)
{
case M32_FLAG_ARRAY:
Bsprintf(buf, "%s[%s]", aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel?
aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2);
break;
case M32_FLAG_STRUCT:
Bsprintf(buf, "%s[%s].%s", pp1[code&3], buf2, pp2[code&3][(code>>2)&31].name);
break;
case M32_FLAG_VAR:
Bsprintf(buf, "???");
break;
case M32_FLAG_LOCAL:
Bsprintf(buf, ".local[%s]", buf2);
break;
}
}
}
else
{
@ -2098,17 +2151,24 @@ badindex:
case CON_GETNUMBER256:
insptr++;
{
int32_t var=*insptr++, quote=Gv_GetVarX(*insptr++), max=Gv_GetVarX(*insptr++), sign=ksgn(max)<0?1:0;
char buf[60];
int32_t var=*insptr++, quote=*insptr++;
const char *quotetext = GetMaybeInlineQuote(quote);
if (vm.flags&VMFLAG_ERROR)
continue;
X_ERROR_INVALIDQUOTE(quote, ScriptQuotes);
Bmemcpy(buf, ScriptQuotes[quote], sizeof(buf)-1);
buf[sizeof(buf)-1]='\0';
{
int32_t max=Gv_GetVarX(*insptr++), sign=ksgn(max)<0?1:0;
char buf[64]; // buffers in getnumber* are 80 bytes long
if (tw==CON_GETNUMBER16)
Gv_SetVarX(var, getnumber16(ScriptQuotes[quote], Gv_GetVarX(var), max, sign));
else
Gv_SetVarX(var, getnumber256(ScriptQuotes[quote], Gv_GetVarX(var), max, sign));
// no danger of accessing unallocated memory since we took care in C_SetScriptSize()
Bmemcpy(buf, quotetext, sizeof(buf));
buf[sizeof(buf)-1]='\0';
if (tw==CON_GETNUMBER16)
Gv_SetVarX(var, getnumber16(quotetext, Gv_GetVarX(var), max, sign));
else
Gv_SetVarX(var, getnumber256(quotetext, Gv_GetVarX(var), max, sign));
}
}
continue;
@ -2121,35 +2181,39 @@ badindex:
case CON_PRINTEXT16:
insptr++;
{
int32_t i=Gv_GetVarX(*insptr++);
int32_t x=(tw>=CON_PRINTMESSAGE256)?Gv_GetVarX(*insptr++):0;
int32_t y=(tw>=CON_PRINTMESSAGE256)?Gv_GetVarX(*insptr++):0;
int32_t col=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
int32_t backcol=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
int32_t fontsize=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
int32_t i=*insptr++;
const char *quotetext = GetMaybeInlineQuote(i);
if (vm.flags&VMFLAG_ERROR)
continue;
if (tw==CON_ERRORINS) vm.flags |= VMFLAG_ERROR;
X_ERROR_INVALIDQUOTE(i, ScriptQuotes);
if (tw==CON_PRINT)
OSD_Printf("%s\n", ScriptQuotes[i]);
if (tw==CON_QUOTE)
message("%s", ScriptQuotes[i]);
else if (tw==CON_PRINTMESSAGE16)
printmessage16("%s", ScriptQuotes[i]);
else if (tw==CON_PRINTMESSAGE256)
printmessage256(x, y, ScriptQuotes[i]);
else if (tw==CON_PRINTEXT256)
{
if (col<0 || col>=256) col=0;
if (backcol<0 || backcol>=256) backcol=-1;
printext256(x, y, col, backcol, ScriptQuotes[i], fontsize);
}
else if (tw==CON_PRINTEXT16)
{
printext16(x, y, editorcolors[col&15], backcol<0 ? -1 : editorcolors[backcol&15],
ScriptQuotes[i], fontsize);
int32_t x=(tw>=CON_PRINTMESSAGE256)?Gv_GetVarX(*insptr++):0;
int32_t y=(tw>=CON_PRINTMESSAGE256)?Gv_GetVarX(*insptr++):0;
int32_t col=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
int32_t backcol=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
int32_t fontsize=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
if (tw==CON_ERRORINS) vm.flags |= VMFLAG_ERROR;
if (tw==CON_PRINT || tw==CON_ERRORINS)
OSD_Printf("%s\n", quotetext);
else if (tw==CON_QUOTE)
message("%s", quotetext);
else if (tw==CON_PRINTMESSAGE16)
printmessage16("%s", quotetext);
else if (tw==CON_PRINTMESSAGE256)
printmessage256(x, y, quotetext);
else if (tw==CON_PRINTEXT256)
{
if (col<0 || col>=256) col=0;
if (backcol<0 || backcol>=256) backcol=-1;
printext256(x, y, col, backcol, quotetext, fontsize);
}
else if (tw==CON_PRINTEXT16)
{
printext16(x, y, editorcolors[col&15], backcol<0 ? -1 : editorcolors[backcol&15],
quotetext, fontsize);
}
}
}
continue;
@ -2157,11 +2221,12 @@ badindex:
case CON_QSTRLEN:
insptr++;
{
int32_t i=*insptr++;
int32_t j=Gv_GetVarX(*insptr++);
int32_t i=*insptr++, quote=*insptr++;
const char *quotetext = GetMaybeInlineQuote(quote);
if (vm.flags&VMFLAG_ERROR)
continue;
X_ERROR_INVALIDQUOTE(j, ScriptQuotes);
Gv_SetVarX(i, Bstrlen(ScriptQuotes[j]));
Gv_SetVarX(i, Bstrlen(quotetext));
continue;
}
@ -2169,16 +2234,18 @@ badindex:
insptr++;
{
int32_t q1 = Gv_GetVarX(*insptr++);
int32_t q2 = Gv_GetVarX(*insptr++);
int32_t st = Gv_GetVarX(*insptr++);
int32_t ln = Gv_GetVarX(*insptr++);
int32_t q2 = *insptr++;
const char *q2text = GetMaybeInlineQuote(q2);
if (vm.flags&VMFLAG_ERROR)
continue;
X_ERROR_INVALIDQUOTE(q1, ScriptQuotes);
X_ERROR_INVALIDQUOTE(q2, ScriptQuotes);
{
int32_t st = Gv_GetVarX(*insptr++);
int32_t ln = Gv_GetVarX(*insptr++);
char *s1 = ScriptQuotes[q1];
char *s2 = ScriptQuotes[q2];
const char *s2 = q2text;
while (*s2 && st--) s2++;
while ((*s1 = *s2) && ln--)
@ -2198,10 +2265,13 @@ badindex:
insptr++;
{
int32_t i = Gv_GetVarX(*insptr++);
int32_t j = Gv_GetVarX(*insptr++);
int32_t j = *insptr++;
const char *quotetext = GetMaybeInlineQuote(j);
if (vm.flags&VMFLAG_ERROR)
continue;
X_ERROR_INVALIDQUOTE(i, ScriptQuotes);
X_ERROR_INVALIDQUOTE(j, ScriptQuotes);
switch (tw)
{
@ -2226,13 +2296,13 @@ badindex:
break;
#endif
case CON_QSTRCAT:
Bstrncat(ScriptQuotes[i],ScriptQuotes[j],(MAXQUOTELEN-1)-Bstrlen(ScriptQuotes[i]));
Bstrncat(ScriptQuotes[i], quotetext, (MAXQUOTELEN-1)-Bstrlen(ScriptQuotes[i]));
break;
case CON_QSTRNCAT:
Bstrncat(ScriptQuotes[i],ScriptQuotes[j],Gv_GetVarX(*insptr++));
Bstrncat(ScriptQuotes[i], quotetext, Gv_GetVarX(*insptr++));
break;
case CON_QSTRCPY:
Bstrcpy(ScriptQuotes[i],ScriptQuotes[j]);
Bstrcpy(ScriptQuotes[i], quotetext);
break;
}
continue;
@ -2241,14 +2311,16 @@ badindex:
case CON_QSPRINTF:
insptr++;
{
int32_t dq = Gv_GetVarX(*insptr++), sq = Gv_GetVarX(*insptr++);
int32_t dq=Gv_GetVarX(*insptr++), sq=*insptr++;
const char *sourcetext = GetMaybeInlineQuote(sq);
if (vm.flags&VMFLAG_ERROR)
continue;
X_ERROR_INVALIDQUOTE(dq, ScriptQuotes);
X_ERROR_INVALIDQUOTE(sq, ScriptQuotes);
{
int32_t arg[32], numvals=0, i=0, j=0, k=0;
int32_t len = Bstrlen(ScriptQuotes[sq]);
int32_t len = Bstrlen(sourcetext);
char tmpbuf[MAXQUOTELEN<<1];
while (*insptr != -1 && numvals < 32)
@ -2259,23 +2331,23 @@ badindex:
i = 0;
do
{
while (k < len && j < MAXQUOTELEN && ScriptQuotes[sq][k] != '%')
tmpbuf[j++] = ScriptQuotes[sq][k++];
while (k < len && j < MAXQUOTELEN && sourcetext[k] != '%')
tmpbuf[j++] = sourcetext[k++];
if (ScriptQuotes[sq][k] == '%')
if (sourcetext[k] == '%')
{
k++;
if (i>=numvals) goto dodefault;
switch (ScriptQuotes[sq][k])
switch (sourcetext[k])
{
case 'l':
if (ScriptQuotes[sq][k+1] != 'd')
if (sourcetext[k+1] != 'd')
{
// write the % and l
tmpbuf[j++] = ScriptQuotes[sq][k-1];
tmpbuf[j++] = ScriptQuotes[sq][k++];
tmpbuf[j++] = sourcetext[k-1];
tmpbuf[j++] = sourcetext[k++];
break;
}
k++;
@ -2321,7 +2393,7 @@ badindex:
dodefault:
default:
tmpbuf[j++] = ScriptQuotes[sq][k-1];
tmpbuf[j++] = sourcetext[k-1];
break;
}
}

View file

@ -33,25 +33,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ACCESS_USEVARS 2
#define ACCESS_SPRITEEXT 4
int32_t m32_script_expertmode = 0;
static int32_t __fastcall VM_AccessWall(int32_t how, int32_t lVar1, int32_t lLabelID, int32_t lVar2)
{
int32_t lValue;
int32_t i = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar1) : lVar1;
if (i<0 || i >= numwalls)
if (!m32_script_expertmode && (i<0 || i >= numwalls))
goto badwall;
if (how&ACCESS_SET)
{
if (WallLabels[lLabelID].flags & 1)
if (!m32_script_expertmode && (WallLabels[lLabelID].flags & 1))
goto readonly;
lValue = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar2) : lVar2;
asksave = 1;
if (WallLabels[lLabelID].min != 0 || WallLabels[lLabelID].max != 0)
if (!m32_script_expertmode && (WallLabels[lLabelID].min != 0 || WallLabels[lLabelID].max != 0))
{
if (lValue < WallLabels[lLabelID].min)
lValue = WallLabels[lLabelID].min;
@ -134,19 +136,19 @@ static int32_t __fastcall VM_AccessSector(int32_t how, int32_t lVar1, int32_t lL
if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
i = Gv_GetVarX(lVar1);
if (i<0 || i >= numsectors)
if (!m32_script_expertmode && (i<0 || i >= numsectors))
goto badsector;
if (how&ACCESS_SET)
{
if (SectorLabels[lLabelID].flags & 1)
if (!m32_script_expertmode && (SectorLabels[lLabelID].flags & 1))
goto readonly;
lValue = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar2) : lVar2;
asksave = 1;
if (SectorLabels[lLabelID].min != 0 || SectorLabels[lLabelID].max != 0)
if (!m32_script_expertmode && (SectorLabels[lLabelID].min != 0 || SectorLabels[lLabelID].max != 0))
{
if (lValue < SectorLabels[lLabelID].min)
lValue = SectorLabels[lLabelID].min;
@ -252,18 +254,18 @@ static int32_t __fastcall VM_AccessSprite(int32_t how, int32_t lVar1, int32_t lL
i = Gv_GetVarX(lVar1);
if (i < 0 || i >= MAXSPRITES)
goto badactor;
goto badsprite;
if (how&ACCESS_SET)
{
if (SpriteLabels[lLabelID].flags & 1)
if (!m32_script_expertmode && (SpriteLabels[lLabelID].flags & 1))
goto readonly;
lValue = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar2) : lVar2;
asksave = 1;
if (SpriteLabels[lLabelID].min != 0 || SpriteLabels[lLabelID].max != 0)
if (!m32_script_expertmode && (SpriteLabels[lLabelID].min != 0 || SpriteLabels[lLabelID].max != 0))
{
if (lValue < SpriteLabels[lLabelID].min)
lValue = SpriteLabels[lLabelID].min;
@ -342,14 +344,11 @@ static int32_t __fastcall VM_AccessSprite(int32_t how, int32_t lVar1, int32_t lL
return lValue;
}
badactor:
// OSD_Printf(CON_ERROR "tried to set %s on invalid target sprite (%d) from spr %d pic %d gv %s\n",g_errorLineNum,keyw[g_tw],
// SpriteLabels[lLabelID].name,i,vm.g_i,vm.g_sp->picnum,
// (lVar1<MAXGAMEVARS)?aGameVars[lVar1].szLabel:"extended");
badsprite:
M32_PRINTERROR("tried to set %s on invalid target sprite (%d)", SpriteLabels[lLabelID].name, i);
return -1;
readonly:
M32_PRINTERROR("Sprite structure member `%s' is read-only.", SpriteLabels[lLabelID].name);
M32_PRINTERROR("sprite structure member `%s' is read-only.", SpriteLabels[lLabelID].name);
return -1;
}

View file

@ -42,6 +42,7 @@ static void Gv_Clear(void)
{
if (aGameVars[i].szLabel)
Bfree(aGameVars[i].szLabel);
aGameVars[i].szLabel = NULL;
aGameVars[i].dwFlags = 0;
@ -50,22 +51,30 @@ static void Gv_Clear(void)
Bfree(aGameVars[i].val.plValues);
aGameVars[i].val.plValues = NULL;
}
aGameVars[i].val.lValue=0;
aGameVars[i].val.lValue = 0;
aGameVars[i].dwFlags |= GAMEVAR_RESET;
if (i >= MAXGAMEARRAYS)
continue;
if (aGameArrays[i].szLabel)
Bfree(aGameArrays[i].szLabel);
aGameArrays[i].szLabel = NULL;
if (aGameArrays[i].vals)
Bfree(aGameArrays[i].vals);
aGameArrays[i].vals = NULL;
aGameArrays[i].dwFlags |= GAMEARRAY_RESET;
}
g_gameVarCount = g_gameArrayCount = 0;
hash_init(&h_gamevars);
hash_init(&h_arrays);
return;
}
@ -90,7 +99,7 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
{
// found it it's a duplicate in error
if (aGameArrays[i].dwFlags&GAMEARRAY_TYPEMASK)
if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK)
{
C_CUSTOMWARNING("ignored redefining system array `%s'.", pszLabel);
}
@ -98,8 +107,10 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
return 0;
}
if (!(dwFlags&GAMEARRAY_VARSIZE) && (asize<=0 || asize>=65536))
if (!(dwFlags&GAMEARRAY_VARSIZE) && !(dwFlags&GAMEARRAY_TYPE_MASK) && (asize<=0 || asize>65536))
{
// the dummy array with index 0 sets the size to 0 so that accidental accesses as array
// will complain.
C_CUSTOMERROR("invalid array size %d. Must be between 1 and 65536", (int32_t)asize);
return 0;
}
@ -111,7 +122,7 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
if (aGameArrays[i].szLabel != pszLabel)
Bstrcpy(aGameArrays[i].szLabel, pszLabel);
if (!(dwFlags & GAMEARRAY_TYPEMASK))
if (!(dwFlags & GAMEARRAY_TYPE_MASK))
aGameArrays[i].vals = Bcalloc(asize, sizeof(int32_t));
else
aGameArrays[i].vals = arrayptr;
@ -148,7 +159,7 @@ int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
if (i >= 0 && !(aGameVars[i].dwFlags & GAMEVAR_RESET))
{
// found it...
if (aGameVars[i].dwFlags & (GAMEVAR_INTPTR|GAMEVAR_FLOATPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR))
if (aGameVars[i].dwFlags & GAMEVAR_PTR_MASK)
{
C_ReportError(-1);
initprintf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
@ -206,36 +217,44 @@ int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
return 1;
}
int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"... vars only!
int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"... vars and locals only!
{
if (id == M32_THISACTOR_VAR_ID)
return vm.g_i;
if (id & (0xFFFFFFFF-(MAXGAMEVARS-1)))
switch (id&M32_VARTYPE_MASK)
{
M32_PRINTERROR("Gv_GetVarN(): invalid var index %d", id);
vm.flags |= VMFLAG_ERROR;
return -1;
case M32_FLAG_VAR:
id &= (MAXGAMEVARS-1);
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
{
case 0:
return aGameVars[id].val.lValue;
case GAMEVAR_PERBLOCK:
return aGameVars[id].val.plValues[vm.g_st];
case GAMEVAR_FLOATPTR:
case GAMEVAR_INTPTR:
return *((int32_t *)aGameVars[id].val.lValue);
case GAMEVAR_SHORTPTR:
return *((int16_t *)aGameVars[id].val.lValue);
case GAMEVAR_CHARPTR:
return *((uint8_t *)aGameVars[id].val.lValue);
default:
M32_PRINTERROR("Gv_GetVarN(): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1;
}
case M32_FLAG_LOCAL:
{
int32_t index = id&(MAXGAMEVARS-1);
// no bounds checking since it's done at script compilation time
return ((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index];
}
id &= (MAXGAMEVARS-1);
switch (aGameVars[id].dwFlags &
(GAMEVAR_USER_MASK|GAMEVAR_INTPTR|GAMEVAR_FLOATPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR))
{
case 0:
return aGameVars[id].val.lValue;
case GAMEVAR_PERBLOCK:
return aGameVars[id].val.plValues[vm.g_st];
case GAMEVAR_FLOATPTR:
case GAMEVAR_INTPTR:
return *((int32_t *)aGameVars[id].val.lValue);
case GAMEVAR_SHORTPTR:
return *((int16_t *)aGameVars[id].val.lValue);
case GAMEVAR_CHARPTR:
return *((uint8_t *)aGameVars[id].val.lValue);
default:
M32_PRINTERROR("Gv_GetVarN(): WTF??");
M32_PRINTERROR("Gv_GetVarN(): invalid var code %0x08x", id);
vm.flags |= VMFLAG_ERROR;
return -1;
}
@ -246,7 +265,9 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
if (id == M32_THISACTOR_VAR_ID)
return vm.g_i;
if ((id & 0x0000FFFC) == MAXGAMEVARS)
register int32_t negateResult = !!(id&M32_FLAG_NEGATE);
if ((id & M32_BITS_MASK) == M32_FLAG_CONSTANT)
{
switch (id&3)
{
@ -255,7 +276,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
case 1:
return constants[(id>>16)&0xffff];
case 2:
return labelval[(id>>16)&0xffff];
return (labelval[(id>>16)&0xffff] ^ -negateResult) + negateResult;
default:
M32_PRINTERROR("Gv_GetVarX() (constant): WTF??");
vm.flags |= VMFLAG_ERROR;
@ -263,229 +284,225 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
}
}
switch (id&M32_VARTYPE_MASK)
{
register int32_t negateResult = (id&M32_FLAG_NEGATE)>>(LOG2MAXGV+1);
case M32_FLAG_ARRAY:
{
register int32_t index;
int32_t siz;
if (id & (0xFFFFFFFF-(MAXGAMEVARS-1)))
index = (int32_t)((id>>16)&0xffff);
if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index);
id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE)
siz = Gv_GetVarN(aGameArrays[id].size);
else
siz = aGameArrays[id].size;
if (index < 0 || index >= siz)
{
if (id&M32_FLAG_ARRAY) // array
{
register int32_t index;
int32_t siz;
index = (int32_t)((id>>16)&0xffff);
if (!(id&MAXGAMEVARS))
index = Gv_GetVarN(index);
id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE)
siz = Gv_GetVarN(aGameArrays[id].size);
else
siz = aGameArrays[id].size;
if (index < 0 || index >= siz)
{
M32_PRINTERROR("Gv_GetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index);
return -1;
}
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPEMASK)
{
case 0:
case GAMEARRAY_OFINT:
return ((((int32_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult);
case GAMEARRAY_OFSHORT:
return ((((int16_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult);
case GAMEARRAY_OFCHAR:
return ((((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult);
default:
M32_PRINTERROR("Gv_GetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1;
}
}
if (id&M32_FLAG_SPECIAL) // struct shortcut vars
{
register int32_t index, memberid;
index = (id>>16)&0x7fff;
if (!(id&MAXGAMEVARS))
index = Gv_GetVarN(index);
memberid = (id>>2)&31;
switch (id&3)
{
case M32_SPRITE_VAR_ID:
return ((VM_AccessSprite(0, index, memberid, 0) ^ -negateResult) + negateResult);
case M32_SECTOR_VAR_ID:
// if (index == vm.g_i) index = sprite[vm.g_i].sectnum;
return ((VM_AccessSector(0, index, memberid, 0) ^ -negateResult) + negateResult);
case M32_WALL_VAR_ID:
return ((VM_AccessWall(0, index, memberid, 0) ^ -negateResult) + negateResult);
case M32_TSPRITE_VAR_ID:
return ((VM_AccessTsprite(0, index, memberid, 0) ^ -negateResult) + negateResult);
// default:
// M32_PRINTERROR("Gv_GetVarX() (special): WTF??");
// return -1;
}
}
id &= (MAXGAMEVARS-1);
if (!negateResult)
{
M32_PRINTERROR("Gv_GetVarX(): invalid gamevar ID (%d)", id);
vm.flags |= VMFLAG_ERROR;
return -1;
}
M32_PRINTERROR("Gv_GetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index);
return -1;
}
switch (aGameVars[id].dwFlags &
(GAMEVAR_USER_MASK|GAMEVAR_INTPTR|GAMEVAR_FLOATPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR))
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0:
return ((aGameVars[id].val.lValue ^ -negateResult) + negateResult);
case GAMEARRAY_OFINT:
return (((int32_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFSHORT:
return (((int16_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFCHAR:
return (((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult;
default:
M32_PRINTERROR("Gv_GetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1;
}
}
case M32_FLAG_STRUCT:
{
register int32_t index, memberid;
index = (id>>16)&0x7fff;
if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index);
memberid = (id>>2)&31;
switch (id&3)
{
case M32_SPRITE_VAR_ID:
return (VM_AccessSprite(0, index, memberid, 0) ^ -negateResult) + negateResult;
case M32_SECTOR_VAR_ID:
return (VM_AccessSector(0, index, memberid, 0) ^ -negateResult) + negateResult;
case M32_WALL_VAR_ID:
return (VM_AccessWall(0, index, memberid, 0) ^ -negateResult) + negateResult;
case M32_TSPRITE_VAR_ID:
return (VM_AccessTsprite(0, index, memberid, 0) ^ -negateResult) + negateResult;
}
}
case M32_FLAG_VAR:
{
id &= (MAXGAMEVARS-1);
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
{
case 0:
return (aGameVars[id].val.lValue ^ -negateResult) + negateResult;
case GAMEVAR_PERBLOCK:
return ((aGameVars[id].val.plValues[vm.g_st] ^ -negateResult) + negateResult);
return (aGameVars[id].val.plValues[vm.g_st] ^ -negateResult) + negateResult;
case GAMEVAR_FLOATPTR:
{
float fval = *(float *)aGameVars[id].val.lValue;
if (negateResult)
{
float fval = -(*(float *)aGameVars[id].val.lValue);
return *(int32_t *)&fval;
}
fval *= -1;
return *(int32_t *)&fval;
}
case GAMEVAR_INTPTR:
return ((*((int32_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return (*((int32_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
case GAMEVAR_SHORTPTR:
return ((*((int16_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return (*((int16_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
case GAMEVAR_CHARPTR:
return ((*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
return (*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
default:
M32_PRINTERROR("Gv_GetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1;
}
}
case M32_FLAG_LOCAL:
{
int32_t index = id&(MAXGAMEVARS-1);
// no bounds checking since it's done at script compilation time
return (((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] ^ -negateResult) + negateResult;
}
} // switch (id&M32_VARTYPE_MASK)
return 0; // never reached
}
void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
{
if (id & (0xFFFFFFFF-(MAXGAMEVARS-1)))
switch (id&M32_VARTYPE_MASK)
{
if (id&M32_FLAG_ARRAY) // array
case M32_FLAG_ARRAY:
{
register int32_t index;
int32_t siz;
index = (id>>16)&0xffff;
if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index);
id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE)
siz = Gv_GetVarN(aGameArrays[id].size);
else siz = aGameArrays[id].size;
if (index < 0 || index >= siz)
{
register int32_t index;
int32_t siz;
index = (id>>16)&0xffff;
if (!(id&MAXGAMEVARS))
index = Gv_GetVarN(index);
id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE)
siz = Gv_GetVarN(aGameArrays[id].size);
else siz = aGameArrays[id].size;
if (index < 0 || index >= siz)
{
M32_PRINTERROR("Gv_SetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index);
vm.flags |= VMFLAG_ERROR;
return;
}
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPEMASK)
{
case 0:
case GAMEARRAY_OFINT:
((int32_t *)aGameArrays[id].vals)[index] = lValue;
return;
case GAMEARRAY_OFSHORT:
((int16_t *)aGameArrays[id].vals)[index] = (int16_t)lValue;
return;
case GAMEARRAY_OFCHAR:
((uint8_t *)aGameArrays[id].vals)[index] = (uint8_t)lValue;
return;
default:
M32_PRINTERROR("Gv_SetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return;
}
M32_PRINTERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", aGameArrays[id].szLabel, index, siz);
vm.flags |= VMFLAG_ERROR;
return;
}
if (id&M32_FLAG_SPECIAL) // struct shortcut vars
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
{
register int32_t index, memberid;
index = (id>>16)&0x7fff;
if (!(id&MAXGAMEVARS))
index = Gv_GetVarN(index);
memberid = (id>>2)&31;
switch (id&3)
{
case M32_SPRITE_VAR_ID:
VM_AccessSprite(1, index, memberid, lValue);
return;
case M32_SECTOR_VAR_ID:
// if (index == vm.g_i) index = sprite[vm.g_i].sectnum;
VM_AccessSector(1, index, memberid, lValue);
return;
case M32_WALL_VAR_ID:
VM_AccessWall(1, index, memberid, lValue);
return;
case M32_TSPRITE_VAR_ID:
VM_AccessTsprite(1, index, memberid, lValue);
return;
// default:
// M32_PRINTERROR("Gv_SetVarX(): WTF??");
// return;
}
case 0:
case GAMEARRAY_OFINT:
((int32_t *)aGameArrays[id].vals)[index] = lValue;
return;
case GAMEARRAY_OFSHORT:
((int16_t *)aGameArrays[id].vals)[index] = (int16_t)lValue;
return;
case GAMEARRAY_OFCHAR:
((uint8_t *)aGameArrays[id].vals)[index] = (uint8_t)lValue;
return;
default:
M32_PRINTERROR("Gv_SetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return;
}
M32_PRINTERROR("Gv_SetVarX(): invalid gamevar ID (%d)", id);
vm.flags |= VMFLAG_ERROR;
return;
}
case M32_FLAG_STRUCT:
{
register int32_t index, memberid;
switch (aGameVars[id].dwFlags &
(GAMEVAR_USER_MASK|GAMEVAR_INTPTR|GAMEVAR_FLOATPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR))
{
case 0:
aGameVars[id].val.lValue=lValue;
return;
case GAMEVAR_PERBLOCK:
aGameVars[id].val.plValues[vm.g_st] = lValue;
return;
case GAMEVAR_FLOATPTR:
{
int32_t ival = lValue;
float fval = *(float *)&ival;
if (fval!=fval || fval<-3.4e38 || fval > 3.4e38)
index = (id>>16)&0x7fff;
if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index);
memberid = (id>>2)&31;
switch (id&3)
{
M32_PRINTERROR("Gv_SetVarX(): tried to set float var to NaN or infinity");
case M32_SPRITE_VAR_ID:
VM_AccessSprite(1, index, memberid, lValue);
return;
case M32_SECTOR_VAR_ID:
VM_AccessSector(1, index, memberid, lValue);
return;
case M32_WALL_VAR_ID:
VM_AccessWall(1, index, memberid, lValue);
return;
case M32_TSPRITE_VAR_ID:
VM_AccessTsprite(1, index, memberid, lValue);
return;
}
}
case M32_FLAG_VAR:
{
id &= (MAXGAMEVARS-1);
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
{
case 0:
aGameVars[id].val.lValue=lValue;
return;
case GAMEVAR_PERBLOCK:
aGameVars[id].val.plValues[vm.g_st] = lValue;
return;
case GAMEVAR_FLOATPTR:
{
int32_t ival = lValue;
float fval = *(float *)&ival;
if (fval!=fval || fval<-3.4e38 || fval > 3.4e38)
{
M32_PRINTERROR("Gv_SetVarX(): tried to set float var to NaN or infinity");
vm.flags |= VMFLAG_ERROR;
return;
}
}
case GAMEVAR_INTPTR:
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
default:
M32_PRINTERROR("Gv_SetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
return;
}
}
case GAMEVAR_INTPTR:
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
default:
M32_PRINTERROR("Gv_SetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
case M32_FLAG_LOCAL:
{
int32_t index = id&(MAXGAMEVARS-1);
((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] = lValue;
return;
}
}
}
static uint8_t alphakeys[] =
@ -616,6 +633,8 @@ static void Gv_AddSystemVars(void)
g_systemVarCount = g_gameVarCount;
// must be first!
Gv_NewArray(".LOCALS_BASE", NULL, 0, GAMEARRAY_OFINT);
Gv_NewArray("highlight", (void *)highlight, hlcnt_id,
GAMEARRAY_READONLY|GAMEARRAY_OFSHORT|GAMEARRAY_VARSIZE);