mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-29 05:03:29 +00:00
f35ac50111
Now it should store all variables in the native endianness, instead of storing half in LE and the other half in the native endianness. Addresses and assignments can be tracked by modifying the macros if necessary. Also, meaningful constants can now be assigned to script variable numbers (if one were so inclined) svn-id: r17523
1228 lines
23 KiB
C++
1228 lines
23 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2004 Ivan Dubrov
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Header$
|
|
*
|
|
*/
|
|
#include "gob/gob.h"
|
|
#include "gob/global.h"
|
|
#include "gob/parse.h"
|
|
#include "gob/util.h"
|
|
#include "gob/inter.h"
|
|
|
|
namespace Gob {
|
|
|
|
int16 parse_parseExpr(char arg_0, byte *arg_2) {
|
|
int32 values[20];
|
|
byte operStack[20];
|
|
int32 prevPrevVal;
|
|
int32 prevVal;
|
|
int32 curVal;
|
|
int32 *valPtr;
|
|
char *operPtr;
|
|
byte *arrDescPtr;
|
|
char var_C;
|
|
byte operation;
|
|
int16 dimCount;
|
|
int16 temp;
|
|
int16 temp2;
|
|
uint16 offset;
|
|
int16 dim;
|
|
char var_1A;
|
|
int16 stkPos;
|
|
int16 brackStart;
|
|
|
|
stkPos = -1;
|
|
operPtr = (char *)(operStack - 1);
|
|
valPtr = values - 1;
|
|
|
|
while (1) {
|
|
stkPos++;
|
|
operPtr++;
|
|
valPtr++;
|
|
operation = *inter_execPtr++;
|
|
if (operation >= 19 && operation <= 29) {
|
|
switch (operation) {
|
|
case 19:
|
|
*operPtr = 20;
|
|
*valPtr = READ_LE_UINT32(inter_execPtr);
|
|
inter_execPtr += 4;
|
|
break;
|
|
|
|
case 20:
|
|
*operPtr = 20;
|
|
*valPtr = inter_load16();
|
|
break;
|
|
|
|
case 22:
|
|
*operPtr = 22;
|
|
*valPtr = (int32)inter_execPtr;
|
|
inter_execPtr += strlen(inter_execPtr) + 1;
|
|
break;
|
|
|
|
case 23:
|
|
*operPtr = 20;
|
|
*valPtr = VAR(inter_load16());
|
|
break;
|
|
|
|
case 25:
|
|
*operPtr = 22;
|
|
temp = inter_load16() * 4;
|
|
*valPtr = (int32)(inter_variables + temp);
|
|
if (*inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
temp += parse_parseValExpr();
|
|
*operPtr = 20;
|
|
//XXX: Checkme
|
|
*valPtr = *(inter_variables + temp);
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
case 28:
|
|
*operPtr = operation - 6;
|
|
temp = inter_load16();
|
|
dimCount = *inter_execPtr++;
|
|
arrDescPtr = (byte *)inter_execPtr;
|
|
inter_execPtr += dimCount;
|
|
offset = 0;
|
|
dim = 0;
|
|
for (dim = 0; dim < dimCount; dim++) {
|
|
temp2 = parse_parseValExpr();
|
|
offset = offset * arrDescPtr[dim] + temp2;
|
|
}
|
|
|
|
if (operation == 26) {
|
|
*valPtr = VAR(temp + offset);
|
|
break;
|
|
}
|
|
*valPtr = (int32)(inter_variables + temp * 4 + offset * inter_animDataSize * 4);
|
|
if (*inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
temp2 = parse_parseValExpr();
|
|
*operPtr = 20;
|
|
//XXX: Checkme
|
|
*valPtr = *(inter_variables + temp * 4 + offset * 4 * inter_animDataSize + temp2);
|
|
}
|
|
break;
|
|
|
|
case 29:
|
|
operation = *inter_execPtr++;
|
|
parse_parseExpr(10, 0);
|
|
|
|
switch (operation) {
|
|
case 5:
|
|
inter_resVal = inter_resVal * inter_resVal;
|
|
break;
|
|
|
|
case 0:
|
|
case 1:
|
|
case 6:
|
|
curVal = 1;
|
|
prevVal = 1;
|
|
|
|
do {
|
|
prevPrevVal = prevVal;
|
|
prevVal = curVal;
|
|
curVal = (curVal + inter_resVal / curVal) / 2;
|
|
} while (curVal != prevVal && curVal != prevPrevVal);
|
|
inter_resVal = curVal;
|
|
break;
|
|
|
|
case 10:
|
|
inter_resVal = util_getRandom(inter_resVal);
|
|
break;
|
|
|
|
case 7:
|
|
if (inter_resVal < 0)
|
|
inter_resVal = -inter_resVal;
|
|
break;
|
|
}
|
|
*operPtr = 20;
|
|
*valPtr = inter_resVal;
|
|
}
|
|
|
|
if (stkPos > 0 && (operPtr[-1] == 1 || operPtr[-1] == 11)) {
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
|
|
if (*operPtr == 1) {
|
|
*operPtr = 20;
|
|
valPtr[0] = -valPtr[1];
|
|
} else if (*operPtr == 11) {
|
|
if (operPtr[1] == 23)
|
|
*operPtr = 24;
|
|
else
|
|
*operPtr = 23;
|
|
}
|
|
}
|
|
|
|
if (stkPos <= 0)
|
|
continue;
|
|
|
|
switch (operPtr[-1]) {
|
|
case 2:
|
|
if (operPtr[-2] == 22) {
|
|
if ((char *)valPtr[-2] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-2]);
|
|
valPtr[-2] = (int32)inter_resStr;
|
|
}
|
|
strcat((char *)valPtr[-2], (char *)valPtr[0]);
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
valPtr[-2] *= valPtr[0];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 6:
|
|
valPtr[-2] /= valPtr[0];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 7:
|
|
valPtr[-2] %= valPtr[0];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 8:
|
|
valPtr[-2] &= valPtr[0];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
}
|
|
continue;
|
|
} // op>= 19 && op <= 29
|
|
|
|
if (operation == arg_0 || operation == 30 || operation == 31 || operation == 10) {
|
|
while (stkPos >= 2) {
|
|
var_1A = 0;
|
|
if (operPtr[-2] == 9 && (operation == 10 || operation == arg_0)) {
|
|
operPtr[-2] = operPtr[-1];
|
|
if (operPtr[-2] == 20 || operPtr[-2] == 22)
|
|
valPtr[-2] = valPtr[-1];
|
|
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
|
|
if (stkPos > 1) {
|
|
if (operPtr[-2] == 1) {
|
|
operPtr[-2] = 20;
|
|
valPtr[-2] = -valPtr[-1];
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
} else if (operPtr[-2] == 11) {
|
|
if (operPtr[-1] == 23)
|
|
operPtr[-2] = 24;
|
|
else
|
|
operPtr[-2] = 23;
|
|
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
}
|
|
} // stkPos > 1
|
|
|
|
if (stkPos > 2) {
|
|
switch (operPtr[-2]) {
|
|
case 5:
|
|
valPtr[-3] *= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
case 6:
|
|
valPtr[-3] /= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 7:
|
|
valPtr[-3] %= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 8:
|
|
valPtr[-3] &= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
} // switch
|
|
} // stkPos > 2
|
|
|
|
if (operation != arg_0)
|
|
break;
|
|
} // if(operPtr[-2] == 9 && ...)
|
|
|
|
for (brackStart = stkPos - 2; brackStart > 0 &&
|
|
operStack[brackStart] < 30 &&
|
|
operStack[brackStart] != 9; brackStart--);
|
|
|
|
if (operStack[brackStart] >= 30 || operStack[brackStart] == 9)
|
|
brackStart++;
|
|
|
|
switch (operPtr[-2]) {
|
|
case 2:
|
|
if (operStack[brackStart] == 20) {
|
|
values[brackStart] += valPtr[-1];
|
|
} else if (operStack[brackStart] == 22) {
|
|
if ((char *)values[brackStart]
|
|
!= inter_resStr) {
|
|
strcpy(inter_resStr, (char *)values[brackStart]);
|
|
values[brackStart] = (int32)inter_resStr;
|
|
}
|
|
strcat((char *)values[brackStart], (char *)valPtr[-1]);
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
continue;
|
|
|
|
case 3:
|
|
values[brackStart] -= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
continue;
|
|
|
|
case 4:
|
|
values[brackStart] |= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
continue;
|
|
|
|
case 5:
|
|
valPtr[-3] *= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 6:
|
|
valPtr[-3] /= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 7:
|
|
valPtr[-3] %= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 8:
|
|
valPtr[-3] &= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 30:
|
|
if (operPtr[-3] == 23)
|
|
operPtr[-3] = operPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 31:
|
|
if (operPtr[-3] == 24)
|
|
operPtr[-3] = operPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 32:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] < valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) < 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 33:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] <= valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) <= 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 34:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] > valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) > 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 35:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] >= valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) >= 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 36:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] == valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) == 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
case 37:
|
|
var_C = operPtr[-3];
|
|
operPtr[-3] = 23;
|
|
if (var_C == 20) {
|
|
if (valPtr[-3] != valPtr[-1])
|
|
operPtr[-3] = 24;
|
|
} else if (var_C == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
if (strcmp((char *)valPtr[-3], (char *)valPtr[-1]) != 0)
|
|
operPtr[-3] = 24;
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
break;
|
|
|
|
default:
|
|
var_1A = 1;
|
|
break;
|
|
} // switch
|
|
|
|
if (var_1A != 0)
|
|
break;
|
|
} // while(stkPos >= 2)
|
|
|
|
if (operation == 30 || operation == 31) {
|
|
if (operPtr[-1] == 20) {
|
|
if (valPtr[-1] != 0)
|
|
operPtr[-1] = 24;
|
|
else
|
|
operPtr[-1] = 23;
|
|
}
|
|
|
|
if ((operation == 30 && operPtr[-1] == 24) ||
|
|
(operation == 31 && operPtr[-1] == 23)) {
|
|
if (stkPos > 1 && operPtr[-2] == 9) {
|
|
parse_skipExpr(10);
|
|
operPtr[-2] = operPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
} else {
|
|
parse_skipExpr(arg_0);
|
|
}
|
|
operation = inter_execPtr[-1];
|
|
if (stkPos > 0 && operPtr[-1] == 11) {
|
|
if (operPtr[0] == 23)
|
|
operPtr[-1] = 24;
|
|
else
|
|
operPtr[-1] = 23;
|
|
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
}
|
|
} else
|
|
operPtr[0] = operation;
|
|
} else {
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
}
|
|
|
|
if (operation != arg_0)
|
|
continue;
|
|
|
|
if (arg_2 != 0)
|
|
*arg_2 = operStack[0];
|
|
|
|
switch (operStack[0]) {
|
|
case 20:
|
|
inter_resVal = values[0];
|
|
break;
|
|
|
|
case 22:
|
|
if ((char *)values[0] != inter_resStr)
|
|
strcpy(inter_resStr,
|
|
(char *)values[0]);
|
|
break;
|
|
|
|
case 11:
|
|
if (arg_2 != 0)
|
|
*arg_2 ^= 1;
|
|
break;
|
|
|
|
case 23:
|
|
case 24:
|
|
break;
|
|
|
|
default:
|
|
inter_resVal = 0;
|
|
if (arg_2 != 0)
|
|
*arg_2 = 20;
|
|
break;
|
|
}
|
|
return 0;
|
|
} // operation == arg_0 || operation == 30 || operation == 31 || operation == 10
|
|
|
|
if (operation < 1 || operation > 11) {
|
|
if (operation < 32 || operation > 37)
|
|
continue;
|
|
|
|
if (stkPos > 2) {
|
|
if (operPtr[-2] == 2) {
|
|
if (operPtr[-3] == 20) {
|
|
valPtr[-3] += valPtr[-1];
|
|
} else if (operPtr[-3] == 22) {
|
|
if ((char *)valPtr[-3] != inter_resStr) {
|
|
strcpy(inter_resStr, (char *)valPtr[-3]);
|
|
valPtr[-3] = (int32)inter_resStr;
|
|
}
|
|
strcat((char *)valPtr[-3], (char *)valPtr[-1]);
|
|
}
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
|
|
} else if (operPtr[-2] == 3) {
|
|
valPtr[-3] -= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
} else if (operPtr[-2] == 4) {
|
|
valPtr[-3] |= valPtr[-1];
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
}
|
|
}
|
|
}
|
|
*operPtr = operation;
|
|
}
|
|
}
|
|
|
|
void parse_skipExpr(char arg_0) {
|
|
int16 dimCount;
|
|
char operation;
|
|
int16 num;
|
|
int16 dim;
|
|
|
|
num = 0;
|
|
while (1) {
|
|
operation = *inter_execPtr++;
|
|
|
|
if (operation >= 19 && operation <= 29) {
|
|
switch (operation) {
|
|
case 20:
|
|
case 23:
|
|
inter_execPtr += 2;
|
|
break;
|
|
|
|
case 19:
|
|
inter_execPtr += 4;
|
|
break;
|
|
|
|
case 22:
|
|
inter_execPtr += strlen(inter_execPtr) + 1;
|
|
break;
|
|
|
|
case 25:
|
|
inter_execPtr += 2;
|
|
if (*inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
parse_skipExpr(12);
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
case 28:
|
|
dimCount = inter_execPtr[2];
|
|
inter_execPtr += 3 + dimCount; // ???
|
|
for (dim = 0; dim < dimCount; dim++)
|
|
parse_skipExpr(12);
|
|
|
|
if (operation == 28 && *inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
parse_skipExpr(12);
|
|
}
|
|
break;
|
|
|
|
case 29:
|
|
inter_execPtr++;
|
|
parse_skipExpr(10);
|
|
}
|
|
continue;
|
|
} // if(operation >= 19 && operation <= 29)
|
|
|
|
if (operation == 9) {
|
|
num++;
|
|
continue;
|
|
}
|
|
|
|
if (operation == 11 || (operation >= 1 && operation <= 8))
|
|
continue;
|
|
|
|
if (operation >= 30 && operation <= 37)
|
|
continue;
|
|
|
|
if (operation == 10)
|
|
num--;
|
|
|
|
if (operation != arg_0)
|
|
continue;
|
|
|
|
if (arg_0 != 10 || num < 0)
|
|
return;
|
|
}
|
|
}
|
|
|
|
int16 parse_parseValExpr() {
|
|
int16 values[20];
|
|
byte operStack[20];
|
|
int16 *valPtr;
|
|
byte *operPtr;
|
|
byte *arrDesc;
|
|
unsigned operation;
|
|
int16 temp2;
|
|
int16 dim;
|
|
int16 dimCount;
|
|
int16 temp;
|
|
int16 offset;
|
|
int16 stkPos;
|
|
int16 brackPos;
|
|
static int16 flag = 0;
|
|
int16 oldflag;
|
|
|
|
oldflag = flag;
|
|
if (flag == 0) {
|
|
flag = 1;
|
|
parse_printExpr(99);
|
|
}
|
|
|
|
stkPos = -1;
|
|
operPtr = operStack - 1;
|
|
valPtr = values - 1;
|
|
|
|
while (1) {
|
|
stkPos++;
|
|
operPtr++;
|
|
valPtr++;
|
|
|
|
operation = *inter_execPtr++;
|
|
if (operation >= 19 && operation <= 29) {
|
|
*operPtr = 20;
|
|
switch (operation) {
|
|
case 19:
|
|
*valPtr = READ_LE_UINT32(inter_execPtr);
|
|
inter_execPtr += 4;
|
|
break;
|
|
|
|
case 20:
|
|
*valPtr = inter_load16();
|
|
break;
|
|
|
|
case 23:
|
|
*valPtr = (uint16)VAR(inter_load16());
|
|
break;
|
|
|
|
case 25:
|
|
temp = inter_load16() * 4;
|
|
inter_execPtr++;
|
|
temp += parse_parseValExpr();
|
|
//XXX: Checkme
|
|
*valPtr = *(inter_variables + temp);
|
|
break;
|
|
|
|
case 26:
|
|
case 28:
|
|
temp = inter_load16();
|
|
dimCount = *inter_execPtr++;
|
|
arrDesc = (byte*)inter_execPtr;
|
|
inter_execPtr += dimCount;
|
|
offset = 0;
|
|
for (dim = 0; dim < dimCount; dim++) {
|
|
temp2 = parse_parseValExpr();
|
|
offset = arrDesc[dim] * offset + temp2;
|
|
}
|
|
if (operation == 26) {
|
|
*valPtr = (uint16)VAR(temp + offset);
|
|
} else {
|
|
inter_execPtr++;
|
|
temp2 = parse_parseValExpr();
|
|
//XXX: Checkme
|
|
*valPtr = *(inter_variables + temp * 4 + offset * 4 * inter_animDataSize + temp2);
|
|
}
|
|
break;
|
|
|
|
case 29:
|
|
operation = *inter_execPtr++;
|
|
parse_parseExpr(10, 0);
|
|
|
|
if (operation == 5) {
|
|
inter_resVal = inter_resVal * inter_resVal;
|
|
} else if (operation == 7) {
|
|
if (inter_resVal < 0)
|
|
inter_resVal = -inter_resVal;
|
|
} else if (operation == 10) {
|
|
inter_resVal = util_getRandom(inter_resVal);
|
|
}
|
|
*valPtr = inter_resVal;
|
|
break;
|
|
|
|
} // switch
|
|
if (stkPos > 0 && operPtr[-1] == 1) {
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
operPtr[0] = 20;
|
|
valPtr[0] = -valPtr[1];
|
|
}
|
|
|
|
if (stkPos > 0 && operPtr[-1] > 4 && operPtr[-1] < 9) {
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
|
|
switch (operPtr[1]) {
|
|
case 5:
|
|
valPtr[0] *= valPtr[2];
|
|
break;
|
|
|
|
case 6:
|
|
valPtr[0] /= valPtr[2];
|
|
break;
|
|
|
|
case 7:
|
|
valPtr[0] %= valPtr[2];
|
|
break;
|
|
|
|
case 8:
|
|
valPtr[0] &= valPtr[2];
|
|
break;
|
|
}
|
|
} // if(stkPos > 0 && cmdPtr[-1] > 4 && cmdPtr[-1] < 9)
|
|
continue;
|
|
}
|
|
|
|
if (operation >= 1 && operation <= 9) {
|
|
*operPtr = operation;
|
|
continue;
|
|
}
|
|
|
|
while (stkPos >= 2) {
|
|
if (operPtr[-2] == 9) {
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
|
|
operPtr[-1] = operPtr[0];
|
|
valPtr[-1] = valPtr[0];
|
|
if (stkPos > 1 && operPtr[-2] == 1) {
|
|
valPtr[-2] = 20;
|
|
valPtr[-2] = -valPtr[-1];
|
|
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
}
|
|
|
|
if (stkPos > 2 && operPtr[-2] > 4
|
|
&& operPtr[-2] < 9) {
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
switch (operPtr[0]) {
|
|
case 5:
|
|
operPtr[-1] *= operPtr[1];
|
|
break;
|
|
|
|
case 6:
|
|
operPtr[-1] /= operPtr[1];
|
|
break;
|
|
|
|
case 7:
|
|
operPtr[-1] %= operPtr[1];
|
|
break;
|
|
|
|
case 8:
|
|
operPtr[-1] &= operPtr[1];
|
|
break;
|
|
}
|
|
}
|
|
if (operation == 10)
|
|
break;
|
|
} // operPtr[-2] == 9
|
|
|
|
for (brackPos = stkPos - 2; brackPos > 0 &&
|
|
operStack[brackPos] < 30
|
|
&& operStack[brackPos] != 9; brackPos--);
|
|
|
|
if (operStack[brackPos] >= 30
|
|
|| operStack[brackPos] == 9)
|
|
brackPos++;
|
|
|
|
if (operPtr[-2] < 2 || operPtr[-2] > 8)
|
|
break;
|
|
|
|
stkPos -= 2;
|
|
operPtr -= 2;
|
|
valPtr -= 2;
|
|
switch (operPtr[0]) {
|
|
case 2:
|
|
values[brackPos] += valPtr[1];
|
|
continue;
|
|
case 3:
|
|
values[brackPos] -= valPtr[1];
|
|
continue;
|
|
case 4:
|
|
values[brackPos] |= valPtr[1];
|
|
continue;
|
|
case 5:
|
|
valPtr[-1] *= valPtr[1];
|
|
continue;
|
|
case 6:
|
|
valPtr[-1] /= valPtr[1];
|
|
continue;
|
|
case 7:
|
|
valPtr[-1] %= valPtr[1];
|
|
continue;
|
|
case 8:
|
|
valPtr[-1] &= valPtr[1];
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (operation != 10) {
|
|
flag = oldflag;
|
|
return values[0];
|
|
}
|
|
|
|
stkPos--;
|
|
operPtr--;
|
|
valPtr--;
|
|
}
|
|
}
|
|
|
|
int16 parse_parseVarIndex() {
|
|
int16 temp2;
|
|
char *arrDesc;
|
|
int16 dim;
|
|
int16 dimCount;
|
|
int16 operation;
|
|
int16 temp;
|
|
int16 offset;
|
|
int16 val;
|
|
|
|
operation = *inter_execPtr++;
|
|
debug(5, "var parse = %d\n", operation);
|
|
switch (operation) {
|
|
case 23:
|
|
case 25:
|
|
temp = inter_load16() * 4;
|
|
debug(5, "oper = %d\n", (int16)*inter_execPtr);
|
|
if (operation == 25 && *inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
val = parse_parseValExpr();
|
|
temp += val;
|
|
debug(5, "parse subscript = %d\n", val);
|
|
}
|
|
return temp;
|
|
|
|
case 26:
|
|
case 28:
|
|
temp = inter_load16() * 4;
|
|
dimCount = *inter_execPtr++;
|
|
arrDesc = inter_execPtr;
|
|
inter_execPtr += dimCount;
|
|
offset = 0;
|
|
for (dim = 0; dim < dimCount; dim++) {
|
|
temp2 = parse_parseValExpr();
|
|
offset = arrDesc[dim] * offset + temp2;
|
|
}
|
|
offset *= 4;
|
|
if (operation != 28)
|
|
return temp + offset;
|
|
|
|
if (*inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
temp += parse_parseValExpr();
|
|
}
|
|
return offset * inter_animDataSize + temp;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void parse_printExpr(char arg_0) {
|
|
int16 dimCount;
|
|
char operation;
|
|
int16 num;
|
|
int16 dim;
|
|
char *arrDesc;
|
|
char func;
|
|
char saved = 0;
|
|
static char *savedPos = 0;
|
|
|
|
if (savedPos == 0) {
|
|
savedPos = inter_execPtr;
|
|
saved = 1;
|
|
}
|
|
|
|
num = 0;
|
|
while (1) {
|
|
operation = *inter_execPtr++;
|
|
|
|
if (operation >= 19 && operation <= 29) {
|
|
switch (operation) {
|
|
case 19:
|
|
debug(5, "%l", READ_LE_UINT32(inter_execPtr));
|
|
inter_execPtr += 4;
|
|
break;
|
|
|
|
case 20:
|
|
debug(5, "%d", inter_load16());
|
|
break;
|
|
|
|
case 22:
|
|
debug(5, "\42%s\42", inter_execPtr);
|
|
inter_execPtr += strlen(inter_execPtr) + 1;
|
|
break;
|
|
|
|
case 23:
|
|
debug(5, "var_%d", inter_load16());
|
|
break;
|
|
|
|
case 25:
|
|
debug(5, "(&var_%d)", inter_load16());
|
|
if (*inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
debug(5, "{");
|
|
parse_printExpr(12);
|
|
// debug(5, "}");
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
case 28:
|
|
if (operation == 28)
|
|
debug(5, "(&");
|
|
|
|
debug(5, "var_%d[", inter_load16());
|
|
dimCount = *inter_execPtr++;
|
|
arrDesc = inter_execPtr;
|
|
inter_execPtr += dimCount;
|
|
for (dim = 0; dim < dimCount; dim++) {
|
|
parse_printExpr(12);
|
|
debug(5, " of %d", (int16)arrDesc[dim]);
|
|
if (dim != dimCount - 1)
|
|
debug(5, ",");
|
|
}
|
|
debug(5, "]");
|
|
if (operation == 28)
|
|
debug(5, ")");
|
|
|
|
if (operation == 28 && *inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
debug(5, "{");
|
|
parse_printExpr(12);
|
|
// debug(5, "}");
|
|
}
|
|
break;
|
|
|
|
case 29:
|
|
func = *inter_execPtr++;
|
|
if (func == 5)
|
|
debug(5, "sqr(");
|
|
else if (func == 10)
|
|
debug(5, "rand(");
|
|
else if (func == 7)
|
|
debug(5, "abs(");
|
|
else if (func == 0 || func == 1 || func == 6)
|
|
debug(5, "sqrt(");
|
|
else
|
|
debug(5, "id(");
|
|
parse_printExpr(10);
|
|
break;
|
|
|
|
case 12:
|
|
debug(5, "}");
|
|
break;
|
|
|
|
default:
|
|
debug(5, "<%d>", (int16)operation);
|
|
break;
|
|
}
|
|
continue;
|
|
} // if(operation >= 19 && operation <= 29)
|
|
switch (operation) {
|
|
case 9:
|
|
debug(5, "(");
|
|
break;
|
|
|
|
case 11:
|
|
debug(5, "!");
|
|
break;
|
|
|
|
case 10:
|
|
debug(5, ")");
|
|
break;
|
|
|
|
case 1:
|
|
debug(5, "-");
|
|
break;
|
|
|
|
case 2:
|
|
debug(5, "+");
|
|
break;
|
|
|
|
case 3:
|
|
debug(5, "-");
|
|
break;
|
|
|
|
case 4:
|
|
debug(5, "|");
|
|
break;
|
|
|
|
case 5:
|
|
debug(5, "*");
|
|
break;
|
|
|
|
case 6:
|
|
debug(5, "/");
|
|
break;
|
|
|
|
case 7:
|
|
debug(5, "%");
|
|
break;
|
|
|
|
case 8:
|
|
debug(5, "&");
|
|
break;
|
|
|
|
case 30:
|
|
debug(5, "||");
|
|
break;
|
|
|
|
case 31:
|
|
debug(5, "&&");
|
|
break;
|
|
|
|
case 32:
|
|
debug(5, "<");
|
|
break;
|
|
|
|
case 33:
|
|
debug(5, "<=");
|
|
break;
|
|
|
|
case 34:
|
|
debug(5, ">");
|
|
break;
|
|
|
|
case 35:
|
|
debug(5, ">=");
|
|
break;
|
|
|
|
case 36:
|
|
debug(5, "==");
|
|
break;
|
|
|
|
case 37:
|
|
debug(5, "!=");
|
|
break;
|
|
|
|
case 99:
|
|
debug(5, "\n");
|
|
break;
|
|
|
|
case 12:
|
|
debug(5, "}");
|
|
break;
|
|
|
|
default:
|
|
debug(5, "<%d>", (int16)operation);
|
|
break;
|
|
}
|
|
|
|
if (operation == 9) {
|
|
num++;
|
|
continue;
|
|
}
|
|
|
|
if (operation == 11 || (operation >= 1 && operation <= 8))
|
|
continue;
|
|
|
|
if (operation >= 30 && operation <= 37)
|
|
continue;
|
|
|
|
if (operation == 10)
|
|
num--;
|
|
|
|
if (operation == arg_0) {
|
|
if (arg_0 != 10 || num < 0) {
|
|
|
|
if (saved != 0) {
|
|
inter_execPtr = savedPos;
|
|
savedPos = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void parse_printVarIndex() {
|
|
char *arrDesc;
|
|
int16 dim;
|
|
int16 dimCount;
|
|
int16 operation;
|
|
int16 temp;
|
|
|
|
char *pos = inter_execPtr;
|
|
|
|
operation = *inter_execPtr++;
|
|
switch (operation) {
|
|
case 23:
|
|
case 25:
|
|
temp = inter_load16() * 4;
|
|
debug(5, "&var_%d", temp);
|
|
if (operation == 25 && *inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
debug(5, "+");
|
|
parse_printExpr(99);
|
|
}
|
|
break;
|
|
|
|
case 26:
|
|
case 28:
|
|
debug(5, "&var_%d[", inter_load16());
|
|
dimCount = *inter_execPtr++;
|
|
arrDesc = inter_execPtr;
|
|
inter_execPtr += dimCount;
|
|
for (dim = 0; dim < dimCount; dim++) {
|
|
parse_printExpr(12);
|
|
debug(5, " of %d", (int16)arrDesc[dim]);
|
|
if (dim != dimCount - 1)
|
|
debug(5, ",");
|
|
}
|
|
debug(5, "]");
|
|
|
|
if (operation == 28 && *inter_execPtr == 13) {
|
|
inter_execPtr++;
|
|
debug(5, "+");
|
|
parse_printExpr(99);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
debug(5, "var_0");
|
|
break;
|
|
}
|
|
debug(5, "\n");
|
|
inter_execPtr = pos;
|
|
return;
|
|
}
|
|
|
|
} // End of namespace Gob
|