Lots of M32script tweaks:

* fix breaking out of 'switch' blocks and compilation of the 'default' case
* Have a way of assigning 'special function' menu [' F] entries to script states. Writing a string literal after the state name will register the state under that name. Menu names are limited to 24 characters and it's possible to have up to 16 of them.
* new branching command 'ifinteractive', true if a state runs from the menu mentioned above.
* new command: getnumberfromuser <<retvar>> "query_string" <maxnum> <flags>

See 'state collect_teleporting_sectors' in a.m32 for a combined usage of the new functionality.

git-svn-id: https://svn.eduke32.com/eduke32@1955 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-08-03 17:22:25 +00:00
parent cbf122fa80
commit aa8b2e4e05
7 changed files with 381 additions and 139 deletions

View file

@ -7722,21 +7722,26 @@ int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, i
return 0;
}
// sign is now used for more than one flag:
// sign is now used for more than one flag (also _getnumber256):
// 1: sign
// 2: autocomplete names
// 4: autocomplete taglabels
// 8: return -1 if cancelled
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
{
char buffer[80], ch;
char buffer[80], ournamestart[80-17], ch;
int32_t n, danum, oldnum;
uint8_t flags = (sign>>1)&7;
uint8_t flags = (sign&(2|4|8))>>1;
sign &= 1;
danum = num;
oldnum = danum;
// need to have 4+11+2==17 chars room at the end
// ("^011", max. string length of an int32, "_ ")
Bstrncpy(ournamestart, namestart, sizeof(ournamestart));
ournamestart[sizeof(ournamestart)-1] = 0;
bflushchars();
while (keystatus[0x1] == 0)
{
@ -7746,14 +7751,16 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
idle();
ch = bgetchar();
Bsprintf(buffer,"%s^011%d", namestart, danum);
n = Bstrlen(buffer);
if (totalclock & 32) Bstrcat(buffer,"_ ");
Bsprintf(buffer, "%s^011%d", ournamestart, danum);
n = Bstrlen(buffer); // maximum is 62+4+11 == 77
if (totalclock & 32)
Bstrcat(buffer,"_ ");
// max strlen now 79
_printmessage16("%s", buffer);
if (func != NULL)
{
Bsprintf(buffer, "%s", (char *)func(danum));
Bsnprintf(buffer, sizeof(buffer), "%s", (char *)func(danum));
// printext16(200L-24, ydim-STATUS2DSIZ+20L, editorcolors[9], editorcolors[0], buffer, 0);
printext16(n<<3, ydim-STATUS2DSIZ+128, editorcolors[11], -1, buffer,0);
}
@ -7762,7 +7769,7 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
n = 0;
if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
(n=getnumber_autocomplete(namestart, ch, &danum, flags)))
(n=getnumber_autocomplete(ournamestart, ch, &danum, flags&(1+2))))
{
if (flags==1 || n==0)
printmessage16("%s", buffer);
@ -7794,14 +7801,19 @@ static void getnumber_clearline(void)
// sign: |16: don't draw scene
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
{
char buffer[80], ch;
char buffer[80], ournamestart[80-13], ch;
int32_t danum, oldnum;
uint8_t flags = (sign>>1)&(3|8);
uint8_t flags = (sign&(2|4|8|16))>>1;
sign &= 1;
danum = num;
oldnum = danum;
// need to have 11+2==13 chars room at the end
// (max. string length of an int32, "_ ")
Bstrncpy(ournamestart, namestart, sizeof(ournamestart));
ournamestart[sizeof(ournamestart)-1] = 0;
bflushchars();
while (keystatus[0x1] == 0)
{
@ -7842,19 +7854,22 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
getnumber_clearline();
Bsprintf(buffer,"%s%d",namestart,danum);
if (totalclock & 32) Bstrcat(buffer,"_ ");
Bsprintf(buffer,"%s%d",ournamestart,danum);
// max strlen now 66+11==77
if (totalclock & 32)
Bstrcat(buffer,"_ ");
// max strlen now 79
printmessage256(0, 0, buffer);
if (func != NULL)
{
Bsprintf(buffer, "%s", (char *)func(danum));
Bsnprintf(buffer, sizeof(buffer), "%s", (char *)func(danum));
printmessage256(0, 9, buffer);
}
showframe(1);
if (getnumber_internal1(ch, &danum, maxnumber, sign) ||
getnumber_autocomplete(namestart, ch, &danum, flags&(1+2)))
getnumber_autocomplete(ournamestart, ch, &danum, flags&(1+2)))
{
if (danum != oldnum)
asksave = 1;
@ -7863,6 +7878,9 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
}
}
if (keystatus[0x1] && (flags&4))
oldnum = -1;
clearkeys();
lockclock = totalclock; //Reset timing
@ -9172,7 +9190,7 @@ void _printmessage16(const char *fmt, ...)
va_list va;
va_start(va, fmt);
Bvsnprintf(tmpstr, 156, fmt, va);
Bvsnprintf(tmpstr, sizeof(tmpstr), fmt, va);
va_end(va);
i = 0;

View file

@ -86,6 +86,7 @@ gamearray parm 8
// prints out maphack light definitions based on SE lights in map
defstate printlights
"Print Polymer lights"
var flags
print "--PRLIGHTS--"
@ -119,6 +120,7 @@ defstate printlights
ends
defstate insertlights
"Insert active SE lights"
var sectnum
set k 0
@ -204,8 +206,7 @@ defstate fiddlewithlights
ifeitherctrl mul j 10
switch k
// "break" breaks too far or there's something wrong with the switch -- needs to be looked at
// case 0: break;
case 0: break;
case 1:
{
set k pr_parallaxscale
@ -250,7 +251,7 @@ defstate fiddlewithlights
ifeitherctrl mul j 10
switch k
// case 0: break;
case 0: break;
case 3:
{
set k pr_specularfactor
@ -500,7 +501,16 @@ defstate try_nextsector
ends
defstate collect_teleporting_sectors // (sec)
"Collect telep. sectors"
var numsects
set numsects numsectors, sub numsects 1
ifinteractive
{
getnumberfromuser sec "starting sectnum: " numsects 8
ifl sec 0, return
}
collectsectors collectedsectors sec numsects try_nextsector
for i range numsects
sethighlightsector collectedsectors[i] 1
@ -1186,6 +1196,7 @@ defstate chselshade
ends
defstate correctslopes
"Correct cstat&2/heinum"
for i allsectors
{
set j sector[i].ceilingstat, and j 2

View file

@ -25,6 +25,7 @@ ends
// various tests of m32-script features
defstate arraytest
"Array test"
getarraysize ar tmp
resizearray ar 65536
getticks parm[2]
@ -42,6 +43,7 @@ defstate arraytest
ends
defstate itertest
"Iteration test"
var gi gj gk
// iteration and break test
@ -82,6 +84,7 @@ define MIN_CONSTANT -2147483648
// tests various combinations of constants and labels
defstate consttest
"Constants test"
quote " --- Constants test ---", quote " "
quote "Should be 0:"
@ -154,6 +157,7 @@ defstate consttest
ends
defstate anmtest
"Sprite yoffsets"
var yo
for i range MAXTILES
@ -175,3 +179,67 @@ defstate anmtest
}
}
ends
// switch/break/default regression test, inspired by
// http://forums.duke4.net/topic/1348-mapster32-problems-and-bugs/page__view__findpost__p__101510
defstate switchtest
"'switch' test"
set i 3622
whilevarn i 3779
{
// test for many things at once:
// sorting of key values
switch i
case 3625 set j 666 /* fall-through */
default set j -1 break
case 3622 set j 3919 break
case 3626 set j -100
case 3623 set j 3685 break
case 3627 set j 1234 break
endswitch
// 'break' should always lead us here
ifle i 3627
{
qsprintf TQUOTE "j=%d" j
quote TQUOTE
}
add i 1
}
quote "----"
// same thing, slightly different syntax
set i 3622
whilevarn i 3779
{
switch i
{
case 3625 set j 666
default set j -1 break
case 3622 set j 3919 break
case 3626 set j -100
case 3623 set j 3685 break
case 3627 set j 1234 break
}
endswitch
ifle i 3627
{
qsprintf TQUOTE "j=%d" j
quote TQUOTE
}
add i 1
}
// correct output:
// j=3919
// j=3685
// j=-1
// j=-1
// j=3685
// j=1234
ends

View file

@ -9133,7 +9133,7 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
{
intptr_t oscrofs;
char *tp;
int32_t i, j, slen, ofs;
int32_t i, j, slen, ofs, dontsavehist;
int32_t onumconstants=g_numSavedConstants;
if (parm->numparms==0)
@ -9147,6 +9147,10 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
if (!tp) goto OUTOFMEM;
Bmemcpy(tp, parm->raw+ofs, slen);
// explicitly typed space at beginning of command (really? not eaten by OSD
// code?) or M32script call from 'special functions' menu
dontsavehist = (slen==0 || tp[0]==' ');
// needed so that subsequent commands won't execute old stuff.
tp[slen] = '\n';
tp[slen+1] = '\0';
@ -9184,23 +9188,17 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
vm.g_sp = &sprite[vm.g_i];
}
// If OSD is down, that would interfere with user input, so don't consider
// m32script executed from the console as 'interactive'. Which leaves only
// that from the 'special functions' menu
if (OSD_GetRowsCur() < 0)
vm.miscflags |= VMFLAG_MISC_INTERACTIVE;
VM_Execute(0);
if (vm.updatehighlight)
{
update_highlight();
vm.updatehighlight = 0;
}
M32_PostScriptExec();
if (vm.updatehighlightsector)
{
update_highlightsector();
if (qsetmode != 200)
ovh_whiteoutgrab(1);
vm.updatehighlightsector = 0;
}
if (!(vm.flags&VMFLAG_ERROR))
if (!(vm.flags&VMFLAG_ERROR) && !dontsavehist)
{
int32_t idx, dosave=1;
@ -12507,9 +12505,10 @@ static void GenericSpriteSearch(void)
keystatus[KEYSC_ESC] = 0;
}
// Build edit
////////// SPECIAL FUNCTIONS MENU //////////
static const char *FuncMenuStrings[] =
static int32_t numMenuFunctions = 8;
static char *funcMenuStrings[8*3] =
{
"Replace invalid tiles",
"Delete all spr of tile #",
@ -12519,38 +12518,111 @@ static const char *FuncMenuStrings[] =
"Resize selection",
"Global shade divide",
"Global visibility divide"
// dynamic menu entries start here
};
static ofstype funcMenuStatenum[8*2];
void registerMenuFunction(const char *funcname, int32_t stateidx)
{
char fn[25];
int32_t i;
if (funcname == NULL) // unregister stateidx
{
int32_t j;
for (i=8; i<numMenuFunctions; i++)
if (funcMenuStatenum[i-8]==stateidx)
{
Bfree(funcMenuStrings[i]);
for (j=i; j<numMenuFunctions-1; j++)
{
funcMenuStatenum[j] = funcMenuStatenum[j+1];
funcMenuStrings[j] = funcMenuStrings[j+1];
}
funcMenuStatenum[j] = 0;
funcMenuStrings[j] = NULL;
numMenuFunctions--;
break;
}
return;
}
// register menu entry named FUNCNAME to call the M32script
// state with index STATEIDX
Bstrncpy(fn, funcname, sizeof(fn));
fn[sizeof(fn)-1] = 0;
for (i=8; i<numMenuFunctions; i++)
{
if (funcMenuStatenum[i-8]==stateidx)
{
// same stateidx, different name
Bfree(funcMenuStrings[i]);
funcMenuStrings[i] = Bstrdup(fn);
return;
}
else if (!Bstrcmp(funcMenuStrings[i], fn))
{
// same name, different stateidx
funcMenuStatenum[i-8] = stateidx;
return;
}
}
if (numMenuFunctions == 3*8)
return; // max reached
funcMenuStrings[numMenuFunctions] = Bstrdup(fn);
funcMenuStatenum[numMenuFunctions-8] = stateidx;
numMenuFunctions++;
}
#define MENU_Y_SPACING 8
#define MENU_BASE_Y ydim-STATUS2DSIZ+32
static int32_t correct_picnum(int16_t *picnumptr)
{
int32_t picnum = *picnumptr;
if ((unsigned)picnum >= MAXTILES || tilesizx[picnum] <= 0)
{
*picnumptr = 0;
return 1;
}
return 0;
}
static void FuncMenuOpts(void)
{
int32_t x = 8;
int32_t y = MENU_BASE_Y+16;
int32_t i = 0;
// int32_t x2 = 0;
// static int32_t x2_max = 0;
int32_t i;
int32_t numopts = (sizeof(FuncMenuStrings)/sizeof(FuncMenuStrings[0]));
do
for (i=0; i<numMenuFunctions; i++)
{
// x2 =
printext16(x,y,editorcolors[11],editorcolors[0],FuncMenuStrings[i],0);
// if (x2 > x2_max) x2_max = x2;
if (i==8 || i==16)
{
x += 208;
y = MENU_BASE_Y+16;
}
printext16(x,y,editorcolors[11],editorcolors[0],funcMenuStrings[i],0);
y += MENU_Y_SPACING;
}
while (++i < numopts);
// drawline16(x-1,y,x2_max+1,y,1);
// drawline16(x-1,MENU_BASE_Y-4,x-1,y,1);
// x2 =
printext16(x,MENU_BASE_Y,editorcolors[11],-1,"Special functions",0);
// drawline16(x-1,MENU_BASE_Y-4,x2+1,MENU_BASE_Y-4,1);
// drawline16(x2_max+1,MENU_BASE_Y+16-4,x2_max+1,y-1,1);
//drawline16(x2+1,MENU_BASE_Y+16-1,x2_max+1,MENU_BASE_Y+16-1,1);
printext16(numMenuFunctions>8 ? 216 : 8, MENU_BASE_Y,
editorcolors[11], -1, "Special functions", 0);
clearkeys();
}
static void FuncMenu(void)
@ -12558,6 +12630,15 @@ static void FuncMenu(void)
char disptext[80];
int32_t col=0, row=0, rowmax=7, dispwidth = 24, editval = 0, i = -1, j;
int32_t xpos = 8, ypos = MENU_BASE_Y+16;
int32_t crowmax[3] = {7, -1, -1};
if (numMenuFunctions > 16)
{
crowmax[2] = numMenuFunctions-16-1;
crowmax[1] = 7;
}
else if (numMenuFunctions > 8)
crowmax[1] = numMenuFunctions-8-1;
drawgradient();
@ -12589,27 +12670,15 @@ static void FuncMenu(void)
row--;
}
}
#if 0
#if 1
if (PRESSED_KEYSC(LEFT))
{
/* if (col == 2)
{
printext16(xpos,ypos+row*8,editorcolors[11],0,disptext,0);
col = 1;
xpos = 200;
rowmax = 6;
dispwidth = 24;
disptext[dispwidth] = 0;
if (row > rowmax) row = rowmax;
}
else */
if (col == 1)
if (col==1 || col==2)
{
printext16(xpos,ypos+row*8,editorcolors[11],0,disptext,0);
col = 0;
xpos = 8;
rowmax = 7;
dispwidth = 24;
col--;
xpos -= 208;
rowmax = crowmax[col];
disptext[dispwidth] = 0;
if (row > rowmax) row = rowmax;
}
@ -12617,26 +12686,15 @@ static void FuncMenu(void)
if (PRESSED_KEYSC(RIGHT))
{
if (col == 0)
if ((col==0 || col==1) && crowmax[col+1]>=0)
{
printext16(xpos,ypos+row*8,editorcolors[11],0,disptext,0);
col = 1;
xpos = 200;
rowmax = 0;
dispwidth = 24;
col++;
xpos += 208;
rowmax = crowmax[col];
disptext[dispwidth] = 0;
if (row > rowmax) row = rowmax;
}
/* else if (col == 1)
{
printext16(xpos,ypos+row*8,editorcolors[11],0,disptext,0);
col = 2;
xpos = 400;
rowmax = 6;
dispwidth = 26;
disptext[dispwidth] = 0;
if (row > rowmax) row = rowmax;
} */
}
#endif
if (PRESSED_KEYSC(ENTER))
@ -12644,33 +12702,60 @@ static void FuncMenu(void)
switch (col)
{
case 1:
case 2:
{
for (i=Bsnprintf(disptext,dispwidth,"%s",funcMenuStrings[col*8 + row]); i < dispwidth; i++)
disptext[i] = ' ';
if (editval)
{
char *statename = statesinfo[funcMenuStatenum[(col-1)*8 + row]].name;
int32_t snlen = Bstrlen(statename);
char *tmpscript = Bmalloc(1+5+1+snlen+1);
if (!tmpscript)
break;
tmpscript[0] = ' '; // don't save in history
Bmemcpy(&tmpscript[1], "state", 5);
tmpscript[1+5] = ' ';
Bmemcpy(&tmpscript[1+5+1], statename, snlen);
tmpscript[1+5+1+snlen] = 0;
M32RunScript(tmpscript);
Bfree(tmpscript);
if (vm.flags&VMFLAG_ERROR)
printmessage16("There were errors while executing the menu function");
else
printmessage16("Menu function executed successfully");
}
break;
}
case 0:
switch (row)
{
case 0:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j = 0;
for (i=0; i<MAXSECTORS; i++)
{
if (tilesizx[sector[i].ceilingpicnum] <= 0)
sector[i].ceilingpicnum = 0,j++;
if (tilesizx[sector[i].floorpicnum] <= 0)
sector[i].floorpicnum = 0,j++;
j += correct_picnum(&sector[i].ceilingpicnum);
j += correct_picnum(&sector[i].floorpicnum);
}
for (i=0; i<MAXWALLS; i++)
{
if (tilesizx[wall[i].picnum] <= 0)
wall[i].picnum = 0,j++;
if (tilesizx[wall[i].overpicnum] <= 0)
wall[i].overpicnum = 0,j++;
j += correct_picnum(&wall[i].picnum);
j += correct_picnum(&wall[i].overpicnum);
}
for (i=0; i<MAXSPRITES; i++)
{
if (tilesizx[sprite[i].picnum] <= 0)
sprite[i].picnum = 0,j++;
j += correct_picnum(&sprite[i].picnum);
}
printmessage16("Replaced %d invalid tiles",j);
}
@ -12678,7 +12763,7 @@ static void FuncMenu(void)
break;
case 1:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
Bsprintf(tempbuf,"Delete all sprites of tile #: ");
@ -12697,7 +12782,7 @@ static void FuncMenu(void)
break;
case 2:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Set map sky shade: ",0,128,1);
@ -12713,7 +12798,7 @@ static void FuncMenu(void)
break;
case 3:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Set map sky height: ",0,16777216,1);
@ -12732,7 +12817,7 @@ static void FuncMenu(void)
break;
case 4:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Z offset: ",0,16777216,1);
@ -12753,7 +12838,7 @@ static void FuncMenu(void)
break;
case 5:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Percentage of original: ",100,1000,0);
@ -12794,7 +12879,7 @@ static void FuncMenu(void)
break;
case 6:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Shade divisor: ",1,128,1);
@ -12817,7 +12902,7 @@ static void FuncMenu(void)
break;
case 7:
{
for (i=Bsprintf(disptext,"%s",FuncMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
for (i=Bsprintf(disptext,"%s",funcMenuStrings[row]); i < dispwidth; i++) disptext[i] = ' ';
if (editval)
{
j=getnumber16("Visibility divisor: ",1,128,0);
@ -12838,6 +12923,7 @@ static void FuncMenu(void)
}
break;
}
printext16(xpos,ypos+row*MENU_Y_SPACING,editorcolors[11],editorcolors[1],disptext,0);
showframe(1);

View file

@ -300,6 +300,7 @@ const char *keyw[] =
"ifaimingsprite",
"ifaimingwall",
"ifaimingsector",
"ifinteractive",
// BUILD functions
"resetkey",
@ -359,6 +360,7 @@ const char *keyw[] =
"drawlabel",
"getnumber16",
"getnumber256",
"getnumberfromuser",
"qsprintf",
"qstrcat",
"qstrcpy",
@ -953,7 +955,7 @@ static int32_t parse_integer_literal(int32_t *num)
long lnum;
errno = 0;
lnum = Bstrtol(textptr, NULL, 10);
if (errno || (sizeof(long)>4 && (lnum<INT_MIN || lnum>INT_MAX)))
if (errno || (sizeof(long)>4 && (lnum<INT32_MIN || lnum>INT32_MAX)))
{
C_CUSTOMERROR("integer literal exceeds bitwidth.");
return 1;
@ -1828,6 +1830,29 @@ static int32_t C_ParseCommand(void)
statesinfo[j].numlocals = 0;
Bsprintf(g_szCurrentBlockName, "%s", statesinfo[j].name);
if (C_GetKeyword() < 0)
{
ofstype *oscriptptr = g_scriptPtr;
if (C_GetNextVarOrString() == 1) // inline string
{
const char *menufuncname = (const char *)(oscriptptr+1);
registerMenuFunction(menufuncname, j);
g_scriptPtr = oscriptptr;
}
else
{
C_CUSTOMERROR("expected inline string to be used as menu name.");
return 1;
}
}
else if (j != g_stateCount)
{
// unregister that state with the menu if redefining and no menu name
registerMenuFunction(NULL, j);
}
return 0;
}
@ -2380,7 +2405,7 @@ repeatcase:
C_CUSTOMERROR("found `default' statement when not in switch");
return 1;
}
if (cs.caseScriptPtr && cs.caseScriptPtr[0]!=0)
if (cs.caseScriptPtr && cs.caseScriptPtr[0]!=-1)
{
C_CUSTOMERROR("multiple `default' statements found in switch");
}
@ -2934,6 +2959,7 @@ repeatcase:
case CON_IFAIMINGSPRITE:
case CON_IFAIMINGWALL:
case CON_IFAIMINGSECTOR:
case CON_IFINTERACTIVE:
{
ofstype offset;
ofstype lastScriptOfs = (g_scriptPtr-script-1);
@ -3272,10 +3298,13 @@ repeatcase:
case CON_GETNUMBER16:
case CON_GETNUMBER256:
case CON_GETNUMBERFROMUSER: // <<retvar>> "quote" <max> <flags>(1|2|4|8|(16))
C_GetNextVarType(GV_WRITABLE);
if (C_GetNextVarOrString()==-1)
return 1;
C_GetNextVar();
if (tw==CON_GETNUMBERFROMUSER)
C_GetNextVar();
return 0;
case CON_QSPRINTF:

View file

@ -56,6 +56,9 @@ extern instype *g_scriptPtr;
void C_Compile(const char *filenameortext, int32_t isfilename);
void C_CompilationInfo(void);
void registerMenuFunction(const char *funcname, ofstype scriptofs);
void M32_PostScriptExec(void);
typedef struct
{
int32_t ofs; // offset into script[]
@ -89,6 +92,19 @@ typedef struct {
extern const tokenmap_t iter_tokens[];
enum vmflags
{
VMFLAG_RETURN = 1,
VMFLAG_BREAK = 2,
VMFLAG_ERROR = 4,
};
enum miscvmflags
{
VMFLAG_MISC_UPDATEHL = 1,
VMFLAG_MISC_UPDATEHLSECT = 2,
VMFLAG_MISC_INTERACTIVE = 4,
};
typedef struct {
int32_t g_i;
@ -97,13 +113,10 @@ typedef struct {
int32_t g_st;
spritetype *g_sp;
uint32_t flags; //g_errorFlag, g_returnFlag;
uint32_t updatehighlight;
uint32_t updatehighlightsector;
} vmstate_t;
#define VMFLAG_RETURN 1
#define VMFLAG_BREAK 2
#define VMFLAG_ERROR 4
// 1:updatehighlight, 2:updatehighlightsector, 4:interactive (from menu)?
uint32_t miscflags;
} vmstate_t;
extern vmstate_t vm;
extern vmstate_t vm_default;
@ -434,6 +447,7 @@ enum ScriptKeywords_t
CON_IFAIMINGSPRITE,
CON_IFAIMINGWALL,
CON_IFAIMINGSECTOR,
CON_IFINTERACTIVE,
// BUILD functions
CON_RESETKEY,
@ -495,6 +509,7 @@ enum ScriptKeywords_t
CON_DRAWLABEL,
CON_GETNUMBER16,
CON_GETNUMBER256,
CON_GETNUMBERFROMUSER,
CON_QSPRINTF,
CON_QSTRCAT,
CON_QSTRCPY,

View file

@ -38,12 +38,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
vmstate_t vm;
vmstate_t vm_default =
{
-1,
0,
NULL,
0,
0,
0
-1, // g_i
0, // g_st
NULL, // g_sp
0, // flags
0, // miscflags
};
int32_t g_errorLineNum, g_tw;
@ -135,6 +134,23 @@ void VM_ScriptInfo(void)
}
}
void M32_PostScriptExec(void)
{
if (vm.miscflags&VMFLAG_MISC_UPDATEHL)
{
update_highlight();
vm.miscflags &= ~VMFLAG_MISC_UPDATEHL;
}
if (vm.miscflags&VMFLAG_MISC_UPDATEHLSECT)
{
update_highlightsector();
if (qsetmode != 200)
ovh_whiteoutgrab(1);
vm.miscflags &= ~VMFLAG_MISC_UPDATEHLSECT;
}
}
void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
{
if (iEventID < 0 || iEventID >= MAXEVENTS)
@ -188,19 +204,7 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
message("ERROR executing %s. Event disabled.", label+(iEventID*MAXLABELLEN));
}
if (vm.updatehighlight)
{
update_highlight();
vm.updatehighlight = 0;
}
if (vm.updatehighlightsector)
{
update_highlightsector();
if (qsetmode != 200)
ovh_whiteoutgrab(1);
vm.updatehighlightsector = 0;
}
M32_PostScriptExec();
// restore old values...
Bmemcpy(&vm, &vm_backup, sizeof(vmstate_t));
@ -461,6 +465,7 @@ skip_check:
// }
}
insptr = (instype *)(lCodeInsPtr + lEnd);
vm.flags &= ~VMFLAG_BREAK;
//Bsprintf(g_szBuf,"insptr=%d. ", (int32_t)insptr); AddLog(g_szBuf);
//AddLog("Done Processing Switch");
continue;
@ -1776,7 +1781,7 @@ badindex:
int64_t dax=Gv_GetVarX(*insptr++), day=Gv_GetVarX(*insptr++);
int64_t hypsq = dax*dax + day*day;
if (hypsq > (int64_t)INT_MAX)
if (hypsq > (int64_t)INT32_MAX)
Gv_SetVarX(retvar, (int32_t)sqrt((double)hypsq));
else
Gv_SetVarX(retvar, ksqrt((int32_t)hypsq));
@ -2204,7 +2209,7 @@ badindex:
show2dwall[index>>3] &= ~(1<<(index&7));
}
vm.updatehighlight = 1;
vm.miscflags |= VMFLAG_MISC_UPDATEHL;
continue;
}
@ -2227,7 +2232,7 @@ badindex:
else
hlsectorbitmap[index>>3] &= ~(1<<(index&7));
vm.updatehighlightsector = 1;
vm.miscflags |= VMFLAG_MISC_UPDATEHLSECT;
continue;
}
@ -2368,8 +2373,9 @@ badindex:
OSD_Printf("%s", ScriptQuotes[*insptr++]);
continue;
case CON_GETNUMBER16:
case CON_GETNUMBER256:
case CON_GETNUMBER16: /* deprecated */
case CON_GETNUMBER256: /* deprecated */
case CON_GETNUMBERFROMUSER:
insptr++;
{
int32_t var=*insptr++, quote=*insptr++;
@ -2378,18 +2384,24 @@ badindex:
continue;
{
int32_t max=Gv_GetVarX(*insptr++), sign=(max<=0);
int32_t max=Gv_GetVarX(*insptr++);
int32_t sign = (tw==CON_GETNUMBERFROMUSER) ? Gv_GetVarX(*insptr++) : (max<=0);
char buf[64]; // buffers in getnumber* are 80 bytes long
// no danger of accessing unallocated memory since we took care in C_SetScriptSize()
Bmemcpy(buf, quotetext, sizeof(buf));
Bstrncpy(buf, quotetext, sizeof(buf));
buf[sizeof(buf)-1]='\0';
if (max==0)
max = INT_MAX;
max = INT32_MAX;
//OSD_Printf("max:%d, sign:%d\n", max, sign);
if (tw==CON_GETNUMBER16)
if (tw==CON_GETNUMBERFROMUSER)
{
Gv_SetVarX(var, (qsetmode==200) ?
getnumber256(quotetext, Gv_GetVarX(var), max, sign) :
getnumber16(quotetext, Gv_GetVarX(var), max, sign));
}
else 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));
@ -2995,6 +3007,9 @@ dodefault:
case CON_IFAIMINGSECTOR:
VM_DoConditional(AIMING_AT_CEILING_OR_FLOOR);
continue;
case CON_IFINTERACTIVE:
VM_DoConditional(vm.miscflags&VMFLAG_MISC_INTERACTIVE);
continue;
case CON_GETSOUNDFLAGS:
insptr++;