diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/gob.cpp | 10 | ||||
-rw-r--r-- | engines/gob/module.mk | 2 | ||||
-rw-r--r-- | engines/gob/parse.cpp | 1023 | ||||
-rw-r--r-- | engines/gob/parse.h | 32 | ||||
-rw-r--r-- | engines/gob/parse_v1.cpp | 834 | ||||
-rw-r--r-- | engines/gob/parse_v2.cpp | 1062 |
6 files changed, 1030 insertions, 1933 deletions
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 9eeb82ad6f..1de6245297 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -332,6 +332,7 @@ bool GobEngine::initGameParts() { _palAnim = new PalAnim(this); _vidPlayer = new VideoPlayer(this); _sound = new Sound(this); + _parse = new Parse(this); switch (_gameType) { case kGameTypeGeisha: @@ -340,7 +341,6 @@ bool GobEngine::initGameParts() { _init = new Init_v1(this); _video = new Video_v1(this); _inter = new Inter_v1(this); - _parse = new Parse_v1(this); _mult = new Mult_v1(this); _draw = new Draw_v1(this); _game = new Game_v1(this); @@ -353,7 +353,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_Fascination(this); - _parse = new Parse_v1(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_Fascination(this); @@ -368,7 +367,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_v2(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -382,7 +380,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_Bargon(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_Bargon(this); _game = new Game_v2(this); @@ -397,7 +394,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v3(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -411,7 +407,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v3(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -425,7 +420,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v4(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -442,7 +436,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v5(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -457,7 +450,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v6(this); _inter = new Inter_v6(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v6(this); diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 9111db9121..22a5cd37b9 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -44,8 +44,6 @@ MODULE_OBJS := \ mult_v2.o \ palanim.o \ parse.o \ - parse_v1.o \ - parse_v2.o \ scenery.o \ scenery_v1.o \ scenery_v2.o \ diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index 81a7da6389..0fa46097a3 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -456,6 +456,16 @@ void Parse::printVarIndex() { return; } +int16 Parse::getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9) { + if (arg_0 < 0) + return 0; + + if (arg_2 > arg_0) + return arg_0; + + return arg_2 - 1; +} + int Parse::cmpHelper(byte *operPtr, int32 *valPtr) { byte var_C = operPtr[-3]; int cmpTemp = 0; @@ -472,5 +482,1018 @@ int Parse::cmpHelper(byte *operPtr, int32 *valPtr) { return cmpTemp; } +int16 Parse::parseVarIndex(uint16 *arg_0, uint16 *arg_4) { + int16 temp2; + byte *arrDesc; + int16 dim; + int16 dimCount; + int16 operation; + int16 temp; + int16 offset; + int16 val; + uint32 varPos = 0; + + operation = *_vm->_global->_inter_execPtr++; + + while ((operation == 14) || (operation == 15)) { + if (operation == 14) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + if (arg_0) + *arg_0 = READ_LE_UINT16(_vm->_global->_inter_execPtr); + if (arg_4) + *arg_4 = 14; + + _vm->_global->_inter_execPtr += 2; + + debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); + + if (*_vm->_global->_inter_execPtr != 97) + return varPos; + + _vm->_global->_inter_execPtr++; + + } else if (operation == 15) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + uint16 var_0C = _vm->_inter->load16(); + if (arg_0) + *arg_0 = var_0C; + if (arg_4) + *arg_4 = 15; + + uint8 var_A = *_vm->_global->_inter_execPtr++; + + byte *var_12 = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += var_A; + + uint16 var_6 = 0; + + for (int i = 0; i < var_A; i++) { + temp2 = parseValExpr(OP_END_MARKER); + + int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); + + var_6 = var_6 * var_12[i] + ax; + } + + varPos += var_6 * var_0C * 4; + + debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); + + if (*_vm->_global->_inter_execPtr != 97) + return varPos; + + _vm->_global->_inter_execPtr++; + } + + operation = *_vm->_global->_inter_execPtr++; + } + + if (arg_0) + *arg_0 = 0; + if (arg_4) + *arg_4 = operation; + + debugC(5, kDebugParser, "var parse = %d", operation); + switch (operation) { + case OP_ARRAY_UINT8: + case OP_ARRAY_UINT32: + case OP_ARRAY_UINT16: + case OP_ARRAY_STR: + temp = _vm->_inter->load16(); + dimCount = *_vm->_global->_inter_execPtr++; + arrDesc = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += dimCount; + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = arrDesc[dim] * offset + temp2; + } + if (operation == OP_ARRAY_UINT8) + return varPos + temp + offset; + if (operation == OP_ARRAY_UINT32) + return varPos + (temp + offset) * 4; + if (operation == OP_ARRAY_UINT16) + return varPos + (temp + offset) * 2; + temp *= 4; + offset *= 4; + if (*_vm->_global->_inter_execPtr == 13) { + _vm->_global->_inter_execPtr++; + temp += parseValExpr(OP_END_MARKER); + } + return varPos + offset * _vm->_global->_inter_animDataSize + temp; + + case OP_LOAD_VAR_INT16: + return varPos + _vm->_inter->load16() * 2; + + case OP_LOAD_VAR_INT8: + return varPos + _vm->_inter->load16(); + + case 23: + case 24: + case OP_LOAD_VAR_STR: + temp = _vm->_inter->load16() * 4; + debugC(5, kDebugParser, "oper = %d", + (int16) *_vm->_global->_inter_execPtr); + if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { + _vm->_global->_inter_execPtr++; + val = parseValExpr(OP_END_MARKER); + temp += val; + debugC(5, kDebugParser, "parse subscript = %d", val); + } + return varPos + temp; + + default: + return 0; + } +} + +int16 Parse::parseValExpr(byte stopToken) { + int16 values[20]; + byte operStack[20]; + int16 *valPtr; + byte *operPtr; + byte *arrDesc; + byte operation; + int16 temp2; + int16 dim; + int16 dimCount; + int16 temp; + int16 offset; + int16 stkPos; + int16 brackPos; + static int16 flag = 0; + int16 oldflag; + uint32 varPos = 0; + + memset(values, 0, 20 * sizeof(int16)); + + oldflag = flag; + if (flag == 0) { + flag = 1; + printExpr(stopToken); + } + + stkPos = -1; + operPtr = operStack - 1; + valPtr = values - 1; + + while (1) { + operation = *_vm->_global->_inter_execPtr++; + + while ((operation == 14) || (operation == 15)) { + if (operation == 14) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + _vm->_global->_inter_execPtr += 3; + } else if (operation == 15) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + uint16 var_0C = _vm->_inter->load16(); + uint8 var_A = *_vm->_global->_inter_execPtr++; + + byte *var_12 = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += var_A; + + uint16 var_6 = 0; + + for (int i = 0; i < var_A; i++) { + temp2 = parseValExpr(OP_END_MARKER); + + int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); + + var_6 = var_6 * var_12[i] + ax; + } + + varPos += var_6 * var_0C * 4; + + _vm->_global->_inter_execPtr++; + } + + debugC(2, kDebugParser, "parseValExpr: Prefix %d (%d)", varPos, operation); + + operation = *_vm->_global->_inter_execPtr++; + } + + stkPos++; + operPtr++; + valPtr++; + + if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { + *operPtr = OP_LOAD_IMM_INT16; + switch (operation) { + case OP_ARRAY_UINT8: + case OP_ARRAY_UINT32: + case OP_ARRAY_UINT16: + case OP_ARRAY_STR: + temp = _vm->_inter->load16(); + dimCount = *_vm->_global->_inter_execPtr++; + arrDesc = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += dimCount; + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = arrDesc[dim] * offset + temp2; + } + if (operation == OP_ARRAY_UINT8) + *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); + else if (operation == OP_ARRAY_UINT32) + *valPtr = (uint16) READ_VARO_UINT32(varPos + temp * 4 + offset * 4); + else if (operation == OP_ARRAY_UINT16) + *valPtr = READ_VARO_UINT16(varPos + temp * 2 + offset * 2); + else if (operation == OP_ARRAY_STR) { + _vm->_global->_inter_execPtr++; + temp2 = parseValExpr(OP_END_MARKER); + *valPtr = READ_VARO_UINT8(varPos + temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + } + break; + + case OP_LOAD_VAR_INT16: + *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); + break; + + case OP_LOAD_VAR_INT8: + *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); + break; + + case OP_LOAD_IMM_INT32: + *valPtr = (uint16) READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += 4; + break; + + case OP_LOAD_IMM_INT16: + *valPtr = _vm->_inter->load16(); + break; + + case OP_LOAD_IMM_INT8: + *valPtr = (int8) *_vm->_global->_inter_execPtr++; + break; + + case 23: + *valPtr = (uint16) READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); + break; + + case 24: + *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); + break; + + case OP_LOAD_VAR_STR: + temp = _vm->_inter->load16() * 4; + _vm->_global->_inter_execPtr++; + temp += parseValExpr(OP_END_MARKER); + *valPtr = READ_VARO_UINT8(varPos + temp); + break; + + case OP_FUNC: + operation = *_vm->_global->_inter_execPtr++; + parseExpr(OP_END_EXPR, 0); + + if (operation == FUNC_SQR) { + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + } else if (operation == FUNC_ABS) { + if (_vm->_global->_inter_resVal < 0) + _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; + } else if (operation == FUNC_RAND) { + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); + } + *valPtr = _vm->_global->_inter_resVal; + break; + + } // switch + if ((stkPos > 0) && (operPtr[-1] == OP_NEG)) { + stkPos--; + operPtr--; + valPtr--; + operPtr[0] = OP_LOAD_IMM_INT16; + valPtr[0] = -valPtr[1]; + } + + if ((stkPos > 0) && (operPtr[-1] >= OP_MUL) && (operPtr[-1] <= OP_BITAND)) { + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + + switch (operPtr[1]) { + case OP_MUL: + valPtr[0] *= valPtr[2]; + break; + + case OP_DIV: + valPtr[0] /= valPtr[2]; + break; + + case OP_MOD: + valPtr[0] %= valPtr[2]; + break; + + case OP_BITAND: + valPtr[0] &= valPtr[2]; + break; + } + } // if ((stkPos > 0) && (cmdPtr[-1] >= OP_MUL) && (cmdPtr[-1] <= OP_BITAND)) + varPos = 0; + continue; + } + + if ((operation >= OP_NEG) && (operation <= OP_BEGIN_EXPR)) { + *operPtr = operation; + continue; + } + + while (stkPos >= 2) { + if (operPtr[-2] == OP_BEGIN_EXPR) { + stkPos--; + operPtr--; + valPtr--; + + operPtr[-1] = operPtr[0]; + valPtr[-1] = valPtr[0]; + if ((stkPos > 1) && (operPtr[-2] == OP_NEG)) { + operPtr[-2] = OP_LOAD_IMM_INT16; + valPtr[-2] = -valPtr[-1]; + + stkPos--; + operPtr--; + valPtr--; + } + + if ((stkPos > 2) && (operPtr[-2] >= OP_MUL) && (operPtr[-2] <= OP_BITAND)) { + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + switch (operPtr[0]) { + case OP_MUL: + valPtr[-1] *= valPtr[1]; + break; + + case OP_DIV: + valPtr[-1] /= valPtr[1]; + break; + + case OP_MOD: + valPtr[-1] %= valPtr[1]; + break; + + case OP_BITAND: + valPtr[-1] &= valPtr[1]; + break; + } + } + if (operation == OP_END_EXPR) + break; + } // operPtr[-2] == OP_BEGIN_EXPR + + for (brackPos = (stkPos - 2); (brackPos > 0) && + (operStack[brackPos] < OP_OR) && (operStack[brackPos] != OP_BEGIN_EXPR); + brackPos--) + ; + + if ((operStack[brackPos] >= OP_OR) || (operStack[brackPos] == OP_BEGIN_EXPR)) + brackPos++; + + if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) + break; + + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + switch (operPtr[0]) { + case OP_ADD: + values[brackPos] += valPtr[1]; + continue; + case OP_SUB: + values[brackPos] -= valPtr[1]; + continue; + case OP_BITOR: + values[brackPos] |= valPtr[1]; + continue; + case OP_MUL: + valPtr[-1] *= valPtr[1]; + continue; + case OP_DIV: + valPtr[-1] /= valPtr[1]; + continue; + case OP_MOD: + valPtr[-1] %= valPtr[1]; + continue; + case OP_BITAND: + valPtr[-1] &= valPtr[1]; + continue; + } + } + + if (operation != OP_END_EXPR) { + if (operation != stopToken) { + debugC(5, kDebugParser, "stoptoken error: %d != %d", + operation, stopToken); + } + flag = oldflag; + return values[0]; + } + + stkPos--; + operPtr--; + valPtr--; + } +} + +int16 Parse::parseExpr(byte stopToken, byte *arg_2) { + int32 values[20]; + byte operStack[20]; + int32 prevPrevVal; + int32 prevVal; + int32 curVal; + int32 *valPtr; + byte *operPtr; + byte *arrDescPtr; + byte operation; + int16 dimCount; + int16 temp; + int16 temp2; + int16 offset; + int16 dim; + bool var_1A; + int16 stkPos; + int16 brackStart; + uint32 varPos = 0; + + memset(operStack, 0, 20); + + stkPos = -1; + operPtr = operStack - 1; + valPtr = values - 1; + + while (true) { + operation = *_vm->_global->_inter_execPtr++; + + while ((operation == 14) || (operation == 15)) { + if (operation == 14) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + _vm->_global->_inter_execPtr += 2; + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } else if (operation == 15) { + uint16 n = _vm->_inter->load16(); + varPos += n * 4; + + uint16 var_0C = _vm->_inter->load16(); + uint8 var_A = *_vm->_global->_inter_execPtr++; + + byte *var_12 = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += var_A; + + uint16 var_6 = 0; + + for (int i = 0; i < var_A; i++) { + temp2 = parseValExpr(OP_END_MARKER); + + int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); + + var_6 = var_6 * var_12[i] + ax; + } + + varPos += var_6 * var_0C * 4; + + if (*_vm->_global->_inter_execPtr == 97) + _vm->_global->_inter_execPtr++; + } + + debugC(2, kDebugParser, "parseExpr: Prefix %d (%d)", varPos, operation); + + operation = *_vm->_global->_inter_execPtr++; + } + + stkPos++; + operPtr++; + valPtr++; + + if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { + switch (operation) { + case OP_ARRAY_UINT8: + case OP_ARRAY_UINT32: + case OP_ARRAY_UINT16: + case OP_ARRAY_STR: + *operPtr = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; + temp = _vm->_inter->load16(); + dimCount = *_vm->_global->_inter_execPtr++; + arrDescPtr = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += dimCount; + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = offset * arrDescPtr[dim] + temp2; + } + if (operation == OP_ARRAY_UINT8) + *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); + else if (operation == OP_ARRAY_UINT32) + *valPtr = READ_VARO_UINT32(varPos + temp * 4 + offset * 4); + else if (operation == OP_ARRAY_UINT16) + *valPtr = (int16) READ_VARO_UINT16(varPos + temp * 2 + offset * 2); + else if (operation == OP_ARRAY_STR) { + *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( + varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), + kInterVar); + if (*_vm->_global->_inter_execPtr == 13) { + _vm->_global->_inter_execPtr++; + temp2 = parseValExpr(OP_END_MARKER); + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT8(varPos + temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + } + } + break; + + case OP_LOAD_VAR_INT16: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); + break; + + case OP_LOAD_VAR_INT8: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); + break; + + case OP_LOAD_IMM_INT32: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += 4; + break; + + case OP_LOAD_IMM_INT16: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = _vm->_inter->load16(); + break; + + case OP_LOAD_IMM_INT8: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int8) *_vm->_global->_inter_execPtr++; + break; + + case OP_LOAD_IMM_STR: + *operPtr = OP_LOAD_IMM_STR; + *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); + _vm->_global->_inter_execPtr += + strlen((char *) _vm->_global->_inter_execPtr) + 1; + break; + + case 23: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); + break; + + case 24: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); + break; + + case OP_LOAD_VAR_STR: + *operPtr = OP_LOAD_IMM_STR; + temp = _vm->_inter->load16() * 4; + *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp), kInterVar); + if (*_vm->_global->_inter_execPtr == 13) { + _vm->_global->_inter_execPtr++; + temp += parseValExpr(OP_END_MARKER); + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT8(varPos + temp); + } + break; + + case OP_FUNC: + operation = *_vm->_global->_inter_execPtr++; + parseExpr(OP_END_EXPR, 0); + + switch (operation) { + case FUNC_SQRT1: + case FUNC_SQRT2: + case FUNC_SQRT3: + curVal = 1; + prevVal = 1; + + do { + prevPrevVal = prevVal; + prevVal = curVal; + curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; + } while ((curVal != prevVal) && (curVal != prevPrevVal)); + _vm->_global->_inter_resVal = curVal; + break; + + case FUNC_SQR: + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + break; + + case FUNC_ABS: + if (_vm->_global->_inter_resVal < 0) + _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; + break; + + case FUNC_RAND: + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); + break; + } + + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = _vm->_global->_inter_resVal; + break; + } + + if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { + stkPos--; + operPtr--; + valPtr--; + + if (*operPtr == OP_NEG) { + *operPtr = OP_LOAD_IMM_INT16; + valPtr[0] = -valPtr[1]; + } else + *operPtr = (operPtr[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; + } + + if (stkPos <= 0) { + varPos = 0; + continue; + } + + switch (operPtr[-1]) { + case OP_ADD: + if (operPtr[-2] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); + valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + } + break; + + case OP_MUL: + valPtr[-2] *= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-2] /= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-2] %= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-2] &= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + } + varPos = 0; + continue; + } // (op >= OP_ARRAY_UINT8) && (op <= OP_FUNC) + + if ((operation == stopToken) || (operation == OP_OR) || + (operation == OP_AND) || (operation == OP_END_EXPR)) { + while (stkPos >= 2) { + var_1A = false; + if ((operPtr[-2] == OP_BEGIN_EXPR) && + ((operation == OP_END_EXPR) || (operation == stopToken))) { + operPtr[-2] = operPtr[-1]; + if ((operPtr[-2] == OP_LOAD_IMM_INT16) || (operPtr[-2] == OP_LOAD_IMM_STR)) + valPtr[-2] = valPtr[-1]; + + stkPos--; + operPtr--; + valPtr--; + + if (stkPos > 1) { + if (operPtr[-2] == OP_NEG) { + operPtr[-2] = OP_LOAD_IMM_INT16; + valPtr[-2] = -valPtr[-1]; + stkPos--; + operPtr--; + valPtr--; + } else if (operPtr[-2] == OP_NOT) { + operPtr[-2] = (operPtr[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; + stkPos--; + operPtr--; + valPtr--; + } + } // stkPos > 1 + + if (stkPos > 2) { + switch (operPtr[-2]) { + case OP_MUL: + valPtr[-3] *= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-3] /= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-3] %= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-3] &= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + } // switch + } // stkPos > 2 + + if (operation != stopToken) + break; + } // if ((operPtr[-2] == OP_BEGIN_EXPR) && ...) + + for (brackStart = (stkPos - 2); (brackStart > 0) && + (operStack[brackStart] < OP_OR) && (operStack[brackStart] != OP_BEGIN_EXPR); + brackStart--) + ; + + if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) + brackStart++; + + switch (operPtr[-2]) { + case OP_ADD: + if (operStack[brackStart] == OP_LOAD_IMM_INT16) { + values[brackStart] += valPtr[-1]; + } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); + values[brackStart] = + encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); + } + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + continue; + + case OP_SUB: + values[brackStart] -= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + continue; + + case OP_BITOR: + values[brackStart] |= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + continue; + + case OP_MUL: + valPtr[-3] *= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-3] /= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-3] %= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-3] &= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_OR: + // (x OR false) == x + // (x OR true) == true + if (operPtr[-3] == GOB_FALSE) + operPtr[-3] = operPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_AND: + // (x AND false) == false + // (x AND true) == x + if (operPtr[-3] == GOB_TRUE) + operPtr[-3] = operPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_LESS: + operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_LEQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_GREATER: + operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_GEQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_EQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_NEQ: { + int cmpTemp = 0; + + if (operPtr[-3] == OP_LOAD_IMM_INT16) { + cmpTemp = valPtr[-3] - valPtr[-1]; + } else if (operPtr[-3] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); + valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + // FIXME: Why scumm_stricmp here and strcmp everywhere else? + cmpTemp = scumm_stricmp(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); + } + operPtr[-3] = (cmpTemp != 0) ? GOB_TRUE : GOB_FALSE; + //operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + } + + default: + var_1A = true; + break; + } // switch + + if (var_1A) + break; + } // while (stkPos >= 2) + + if ((operation == OP_OR) || (operation == OP_AND)) { + if (operPtr[-1] == OP_LOAD_IMM_INT16) { + if (valPtr[-1] != 0) + operPtr[-1] = GOB_TRUE; + else + operPtr[-1] = GOB_FALSE; + } + + if (((operation == OP_OR) && (operPtr[-1] == GOB_TRUE)) || + ((operation == OP_AND) && (operPtr[-1] == GOB_FALSE))) { + if ((stkPos > 1) && (operPtr[-2] == OP_BEGIN_EXPR)) { + skipExpr(OP_END_EXPR); + operPtr[-2] = operPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + } else { + skipExpr(stopToken); + } + operation = _vm->_global->_inter_execPtr[-1]; + if ((stkPos > 0) && (operPtr[-1] == OP_NOT)) { + if (operPtr[0] == GOB_FALSE) + operPtr[-1] = GOB_TRUE; + else + operPtr[-1] = GOB_FALSE; + + stkPos--; + operPtr--; + valPtr--; + } + } else + operPtr[0] = operation; + } else { + stkPos--; + operPtr--; + valPtr--; + } + + if (operation != stopToken) + continue; + + if (arg_2 != 0) + *arg_2 = operStack[0]; + + switch (operStack[0]) { + case OP_NOT: + if (arg_2 != 0) + *arg_2 ^= 1; + break; + + case OP_LOAD_IMM_INT16: + _vm->_global->_inter_resVal = values[0]; + break; + + case OP_LOAD_IMM_STR: + if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); + break; + + case 23: + case 24: + break; + + default: + _vm->_global->_inter_resVal = 0; + if (arg_2 != 0) + *arg_2 = OP_LOAD_IMM_INT16; + break; + } + return 0; + } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) + + if ((operation < OP_NEG) || (operation > OP_NOT)) { + if ((operation < OP_LESS) || (operation > OP_NEQ)) + continue; + + if (stkPos > 2) { + if (operPtr[-2] == OP_ADD) { + if (operPtr[-3] == OP_LOAD_IMM_INT16) { + valPtr[-3] += valPtr[-1]; + } else if (operPtr[-3] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); + valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); + } + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + + } else if (operPtr[-2] == OP_SUB) { + valPtr[-3] -= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + } else if (operPtr[-2] == OP_BITOR) { + valPtr[-3] |= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + } + } + } + *operPtr = operation; + } +} } // End of namespace Gob diff --git a/engines/gob/parse.h b/engines/gob/parse.h index d72b4d5c2b..01f5762b6d 100644 --- a/engines/gob/parse.h +++ b/engines/gob/parse.h @@ -97,14 +97,15 @@ public: void skipExpr(char stopToken); void printExpr(char stopToken); void printVarIndex(void); - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0) = 0; - virtual int16 parseValExpr(byte stopToken = 99) = 0; - virtual int16 parseExpr(byte stopToken, byte *resultPtr) = 0; + + int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0); + int16 parseValExpr(byte stopToken = 99); + int16 parseExpr(byte stopToken, byte *resultPtr); Parse(GobEngine *vm); virtual ~Parse() {} -protected: +private: enum PointerType { kExecPtr = 0, kInterVar = 1, @@ -118,31 +119,10 @@ protected: void printExpr_internal(char stopToken); + int16 getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9); int cmpHelper(byte *operPtr, int32 *valPtr); }; -class Parse_v1 : public Parse { -public: - Parse_v1(GobEngine *vm); - virtual ~Parse_v1() {} - - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0); - virtual int16 parseValExpr(byte stopToken = 99); - virtual int16 parseExpr(byte stopToken, byte *resultPtr); -}; - -class Parse_v2 : public Parse_v1 { -public: - Parse_v2(GobEngine *vm); - virtual ~Parse_v2() {} - - virtual int16 getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9); - - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0); - virtual int16 parseValExpr(byte stopToken = 99); - virtual int16 parseExpr(byte stopToken, byte *resultPtr); -}; - } // End of namespace Gob #endif // GOB_PARSE_H diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp deleted file mode 100644 index c993d6ca70..0000000000 --- a/engines/gob/parse_v1.cpp +++ /dev/null @@ -1,834 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/endian.h" - -#include "gob/gob.h" -#include "gob/parse.h" -#include "gob/global.h" -#include "gob/inter.h" - -namespace Gob { - -Parse_v1::Parse_v1(GobEngine *vm) : Parse(vm) { -} - -int16 Parse_v1::parseVarIndex(uint16 *arg_0, uint16 *arg_4) { - int16 temp2; - byte *arrDesc; - int16 dim; - int16 dimCount; - int16 operation; - int16 temp; - int16 offset; - int16 val; - - operation = *_vm->_global->_inter_execPtr++; - debugC(5, kDebugParser, "var parse = %d", operation); - switch (operation) { - case 23: - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", - (int16) *_vm->_global->_inter_execPtr); - - if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - val = parseValExpr(OP_END_MARKER); - temp += val; - debugC(5, kDebugParser, "parse subscript = %d", val); - } - return temp; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - temp = _vm->_inter->load16() * 4; - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - offset *= 4; - if (operation != OP_ARRAY_STR) - return temp + offset; - - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - } - return offset * _vm->_global->_inter_animDataSize + temp; - - default: - return 0; - } -} - -int16 Parse_v1::parseValExpr(byte stopToken) { - int16 values[20]; - byte operStack[20]; - int16 *valPtr; - byte *operPtr; - byte *arrDesc; - byte 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; - printExpr(stopToken); - } - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - stkPos++; - operPtr++; - valPtr++; - - operation = *_vm->_global->_inter_execPtr++; - if ((operation >= OP_LOAD_IMM_INT32) && (operation <= OP_FUNC)) { - *operPtr = OP_LOAD_IMM_INT16; - switch (operation) { - case OP_LOAD_IMM_INT32: - *valPtr = READ_LE_UINT32(_vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *valPtr = _vm->_inter->load16(); - break; - - case 23: - *valPtr = (uint16) VAR(_vm->_inter->load16()); - break; - - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(temp); - break; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT32) { - *valPtr = (uint16) VAR(temp + offset); - } else { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * - _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - if (operation == FUNC_SQR) { - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - } else if (operation == FUNC_ABS) { - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - } else if (operation == FUNC_RAND) { - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - } - *valPtr = _vm->_global->_inter_resVal; - break; - - } // switch - if ((stkPos > 0) && (operPtr[-1] == OP_NEG)) { - stkPos--; - operPtr--; - valPtr--; - operPtr[0] = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } - - if ((stkPos > 0) && (operPtr[-1] >= OP_MUL) && (operPtr[-1] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - switch (operPtr[1]) { - case OP_MUL: - valPtr[0] *= valPtr[2]; - break; - - case OP_DIV: - valPtr[0] /= valPtr[2]; - break; - - case OP_MOD: - valPtr[0] %= valPtr[2]; - break; - - case OP_BITAND: - valPtr[0] &= valPtr[2]; - break; - } - } // if ((stkPos > 0) && (cmdPtr[-1] >= OP_MUL) && (cmdPtr[-1] <= OP_BITAND)) - continue; - } - - if ((operation >= OP_NEG) && (operation <= OP_BEGIN_EXPR)) { - *operPtr = operation; - continue; - } - - while (stkPos >= 2) { - if (operPtr[-2] == OP_BEGIN_EXPR) { - stkPos--; - operPtr--; - valPtr--; - - operPtr[-1] = operPtr[0]; - valPtr[-1] = valPtr[0]; - if ((stkPos > 1) && (operPtr[-2] == OP_NEG)) { - valPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - } - - if ((stkPos > 2) && (operPtr[-2] >= OP_MUL) && (operPtr[-2] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_MUL: - operPtr[-1] *= operPtr[1]; - break; - - case OP_DIV: - operPtr[-1] /= operPtr[1]; - break; - - case OP_MOD: - operPtr[-1] %= operPtr[1]; - break; - - case OP_BITAND: - operPtr[-1] &= operPtr[1]; - break; - } - } - if (operation == OP_END_EXPR) - break; - } // operPtr[-2] == OP_BEGIN_EXPR - - for (brackPos = (stkPos - 2); (brackPos > 0) && - (operStack[brackPos] < OP_OR) && (operStack[brackPos] != OP_BEGIN_EXPR); - brackPos--) - ; - - if ((operStack[brackPos] >= OP_OR) || (operStack[brackPos] == OP_BEGIN_EXPR)) - brackPos++; - - if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) - break; - - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_ADD: - values[brackPos] += valPtr[1]; - continue; - case OP_SUB: - values[brackPos] -= valPtr[1]; - continue; - case OP_BITOR: - values[brackPos] |= valPtr[1]; - continue; - case OP_MUL: - valPtr[-1] *= valPtr[1]; - continue; - case OP_DIV: - valPtr[-1] /= valPtr[1]; - continue; - case OP_MOD: - valPtr[-1] %= valPtr[1]; - continue; - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - continue; - } - } - - if (operation != OP_END_EXPR) { - if (operation != stopToken) - debugC(5, kDebugParser, "stoptoken error: %d != %d", - operation, stopToken); - - flag = oldflag; - return values[0]; - } - - stkPos--; - operPtr--; - valPtr--; - } -} - -int16 Parse_v1::parseExpr(byte stopToken, byte *arg_2) { - int32 values[20]; - byte operStack[20]; - int32 prevPrevVal; - int32 prevVal; - int32 curVal; - int32 *valPtr; - byte *operPtr; - byte *arrDescPtr; - byte operation; - int16 dimCount; - int16 temp; - int16 temp2; - uint16 offset; - int16 dim; - bool var_1A; - int16 stkPos; - int16 brackStart; - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - stkPos++; - operPtr++; - valPtr++; - operation = *_vm->_global->_inter_execPtr++; - if ((operation >= OP_LOAD_IMM_INT32) && (operation <= OP_FUNC)) { - switch (operation) { - case OP_LOAD_IMM_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_LE_UINT32(_vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_STR: - *operPtr = OP_LOAD_IMM_STR; - *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case 23: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = VAR(_vm->_inter->load16()); - break; - - case OP_LOAD_VAR_STR: - *operPtr = OP_LOAD_IMM_STR; - temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(temp), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(temp); - } - break; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - *operPtr = operation - 6; - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - dim = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = offset * arrDescPtr[dim] + temp2; - } - - if (operation == OP_ARRAY_UINT32) { - *valPtr = VAR(temp + offset); - break; - } - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( - temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - switch (operation) { - case FUNC_SQR: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - - case FUNC_SQRT1: - case FUNC_SQRT2: - case FUNC_SQRT3: - curVal = 1; - prevVal = 1; - - do { - prevPrevVal = prevVal; - prevVal = curVal; - curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while ((curVal != prevVal) && (curVal != prevPrevVal)); - _vm->_global->_inter_resVal = curVal; - break; - - case FUNC_RAND: - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - break; - - case FUNC_ABS: - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - break; - } - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_global->_inter_resVal; - } - - if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { - stkPos--; - operPtr--; - valPtr--; - - if (*operPtr == OP_NEG) { - *operPtr = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } else if (*operPtr == OP_NOT) { - if (operPtr[1] == GOB_FALSE) - *operPtr = GOB_TRUE; - else - *operPtr = GOB_FALSE; - } - } - - if (stkPos <= 0) - continue; - - switch (operPtr[-1]) { - case OP_ADD: - if (operPtr[-2] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); - valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - break; - - case OP_MUL: - valPtr[-2] *= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-2] /= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-2] %= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-2] &= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - continue; - } // (op >= OP_LOAD_IMM_INT32) && (op <= OP_FUNC) - - if ((operation == stopToken) || (operation == OP_OR) || - (operation == OP_AND) || (operation == OP_END_EXPR)) { - while (stkPos >= 2) { - var_1A = false; - if ((operPtr[-2] == OP_BEGIN_EXPR) && - ((operation == OP_END_EXPR) || (operation == stopToken))) { - operPtr[-2] = operPtr[-1]; - if ((operPtr[-2] == OP_LOAD_IMM_INT16) || (operPtr[-2] == OP_LOAD_IMM_STR)) - valPtr[-2] = valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - - if (stkPos > 1) { - if (operPtr[-2] == OP_NEG) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - stkPos--; - operPtr--; - valPtr--; - } else if (operPtr[-2] == OP_NOT) { - if (operPtr[-1] == GOB_FALSE) - operPtr[-2] = GOB_TRUE; - else - operPtr[-2] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } // stkPos > 1 - - if (stkPos > 2) { - switch (operPtr[-2]) { - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } // switch - } // stkPos > 2 - - if (operation != stopToken) - break; - } // if ((operPtr[-2] == OP_BEGIN_EXPR) && ...) - - for (brackStart = (stkPos - 2); (brackStart > 0) && - (operStack[brackStart] < OP_OR) && (operStack[brackStart] != OP_BEGIN_EXPR); - brackStart--) - ; - - if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) - brackStart++; - - switch (operPtr[-2]) { - case OP_ADD: - if (operStack[brackStart] == OP_LOAD_IMM_INT16) { - values[brackStart] += valPtr[-1]; - } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); - values[brackStart] = - encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_SUB: - values[brackStart] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_BITOR: - values[brackStart] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_OR: - // (x OR false) == x - // (x OR true) == true - if (operPtr[-3] == GOB_FALSE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_AND: - // (x AND false) == false - // (x AND true) == x - if (operPtr[-3] == GOB_TRUE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LESS: - operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GREATER: - operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_EQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_NEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - default: - var_1A = true; - break; - } // switch - - if (var_1A) - break; - } // while (stkPos >= 2) - - if ((operation == OP_OR) || (operation == OP_AND)) { - if (operPtr[-1] == OP_LOAD_IMM_INT16) { - if (valPtr[-1] != 0) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - } - - if (((operation == OP_OR) && (operPtr[-1] == GOB_TRUE)) || - ((operation == OP_AND) && (operPtr[-1] == GOB_FALSE))) { - if ((stkPos > 1) && (operPtr[-2] == OP_BEGIN_EXPR)) { - skipExpr(OP_END_EXPR); - operPtr[-2] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else - skipExpr(stopToken); - - operation = _vm->_global->_inter_execPtr[-1]; - if ((stkPos > 0) && (operPtr[-1] == OP_NOT)) { - if (operPtr[0] == GOB_FALSE) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } else - operPtr[0] = operation; - } else { - stkPos--; - operPtr--; - valPtr--; - } - - if (operation != stopToken) - continue; - - if (arg_2 != 0) - *arg_2 = operStack[0]; - - switch (operStack[0]) { - case OP_LOAD_IMM_INT16: - _vm->_global->_inter_resVal = values[0]; - break; - - case OP_LOAD_IMM_STR: - if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); - break; - - case OP_NOT: - if (arg_2 != 0) - *arg_2 ^= 1; - break; - - case 23: - case 24: - break; - - default: - _vm->_global->_inter_resVal = 0; - if (arg_2 != 0) - *arg_2 = OP_LOAD_IMM_INT16; - break; - } - return 0; - } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) - - if (operation < OP_NEG || operation > OP_NOT) { - if (operation < OP_LESS || operation > OP_NEQ) - continue; - - if (stkPos > 2) { - if (operPtr[-2] == OP_ADD) { - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - valPtr[-3] += valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - } else if (operPtr[-2] == OP_SUB) { - valPtr[-3] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else if (operPtr[-2] == OP_BITOR) { - valPtr[-3] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - } - } - *operPtr = operation; - } -} - -} // End of namespace Gob diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp deleted file mode 100644 index e7f91650b5..0000000000 --- a/engines/gob/parse_v2.cpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/endian.h" - -#include "gob/gob.h" -#include "gob/parse.h" -#include "gob/global.h" -#include "gob/inter.h" - -namespace Gob { - -Parse_v2::Parse_v2(GobEngine *vm) : Parse_v1(vm) { -} - -int16 Parse_v2::parseVarIndex(uint16 *arg_0, uint16 *arg_4) { - int16 temp2; - byte *arrDesc; - int16 dim; - int16 dimCount; - int16 operation; - int16 temp; - int16 offset; - int16 val; - uint32 varPos = 0; - - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - if (arg_0) - *arg_0 = READ_LE_UINT16(_vm->_global->_inter_execPtr); - if (arg_4) - *arg_4 = 14; - - _vm->_global->_inter_execPtr += 2; - - debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); - - if (*_vm->_global->_inter_execPtr != 97) - return varPos; - - _vm->_global->_inter_execPtr++; - - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - if (arg_0) - *arg_0 = var_0C; - if (arg_4) - *arg_4 = 15; - - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); - - if (*_vm->_global->_inter_execPtr != 97) - return varPos; - - _vm->_global->_inter_execPtr++; - } - - operation = *_vm->_global->_inter_execPtr++; - } - - if (arg_0) - *arg_0 = 0; - if (arg_4) - *arg_4 = operation; - - debugC(5, kDebugParser, "var parse = %d", operation); - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT8) - return varPos + temp + offset; - if (operation == OP_ARRAY_UINT32) - return varPos + (temp + offset) * 4; - if (operation == OP_ARRAY_UINT16) - return varPos + (temp + offset) * 2; - temp *= 4; - offset *= 4; - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - } - return varPos + offset * _vm->_global->_inter_animDataSize + temp; - - case OP_LOAD_VAR_INT16: - return varPos + _vm->_inter->load16() * 2; - - case OP_LOAD_VAR_INT8: - return varPos + _vm->_inter->load16(); - - case 23: - case 24: - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", - (int16) *_vm->_global->_inter_execPtr); - if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - val = parseValExpr(OP_END_MARKER); - temp += val; - debugC(5, kDebugParser, "parse subscript = %d", val); - } - return varPos + temp; - - default: - return 0; - } -} - -int16 Parse_v2::parseValExpr(byte stopToken) { - int16 values[20]; - byte operStack[20]; - int16 *valPtr; - byte *operPtr; - byte *arrDesc; - byte operation; - int16 temp2; - int16 dim; - int16 dimCount; - int16 temp; - int16 offset; - int16 stkPos; - int16 brackPos; - static int16 flag = 0; - int16 oldflag; - uint32 varPos = 0; - - memset(values, 0, 20 * sizeof(int16)); - - oldflag = flag; - if (flag == 0) { - flag = 1; - printExpr(stopToken); - } - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (1) { - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - _vm->_global->_inter_execPtr += 3; - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - _vm->_global->_inter_execPtr++; - } - - debugC(2, kDebugParser, "parseValExpr: Prefix %d (%d)", varPos, operation); - - operation = *_vm->_global->_inter_execPtr++; - } - - stkPos++; - operPtr++; - valPtr++; - - if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { - *operPtr = OP_LOAD_IMM_INT16; - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT8) - *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); - else if (operation == OP_ARRAY_UINT32) - *valPtr = (uint16) READ_VARO_UINT32(varPos + temp * 4 + offset * 4); - else if (operation == OP_ARRAY_UINT16) - *valPtr = READ_VARO_UINT16(varPos + temp * 2 + offset * 2); - else if (operation == OP_ARRAY_STR) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(varPos + temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_LOAD_VAR_INT16: - *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); - break; - - case OP_LOAD_VAR_INT8: - *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: - *valPtr = (uint16) READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_INT8: - *valPtr = (int8) *_vm->_global->_inter_execPtr++; - break; - - case 23: - *valPtr = (uint16) READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); - break; - - case 24: - *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(varPos + temp); - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - if (operation == FUNC_SQR) { - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - } else if (operation == FUNC_ABS) { - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - } else if (operation == FUNC_RAND) { - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - } - *valPtr = _vm->_global->_inter_resVal; - break; - - } // switch - if ((stkPos > 0) && (operPtr[-1] == OP_NEG)) { - stkPos--; - operPtr--; - valPtr--; - operPtr[0] = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } - - if ((stkPos > 0) && (operPtr[-1] >= OP_MUL) && (operPtr[-1] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - switch (operPtr[1]) { - case OP_MUL: - valPtr[0] *= valPtr[2]; - break; - - case OP_DIV: - valPtr[0] /= valPtr[2]; - break; - - case OP_MOD: - valPtr[0] %= valPtr[2]; - break; - - case OP_BITAND: - valPtr[0] &= valPtr[2]; - break; - } - } // if ((stkPos > 0) && (cmdPtr[-1] >= OP_MUL) && (cmdPtr[-1] <= OP_BITAND)) - varPos = 0; - continue; - } - - if ((operation >= OP_NEG) && (operation <= OP_BEGIN_EXPR)) { - *operPtr = operation; - continue; - } - - while (stkPos >= 2) { - if (operPtr[-2] == OP_BEGIN_EXPR) { - stkPos--; - operPtr--; - valPtr--; - - operPtr[-1] = operPtr[0]; - valPtr[-1] = valPtr[0]; - if ((stkPos > 1) && (operPtr[-2] == OP_NEG)) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - } - - if ((stkPos > 2) && (operPtr[-2] >= OP_MUL) && (operPtr[-2] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_MUL: - valPtr[-1] *= valPtr[1]; - break; - - case OP_DIV: - valPtr[-1] /= valPtr[1]; - break; - - case OP_MOD: - valPtr[-1] %= valPtr[1]; - break; - - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - break; - } - } - if (operation == OP_END_EXPR) - break; - } // operPtr[-2] == OP_BEGIN_EXPR - - for (brackPos = (stkPos - 2); (brackPos > 0) && - (operStack[brackPos] < OP_OR) && (operStack[brackPos] != OP_BEGIN_EXPR); - brackPos--) - ; - - if ((operStack[brackPos] >= OP_OR) || (operStack[brackPos] == OP_BEGIN_EXPR)) - brackPos++; - - if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) - break; - - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_ADD: - values[brackPos] += valPtr[1]; - continue; - case OP_SUB: - values[brackPos] -= valPtr[1]; - continue; - case OP_BITOR: - values[brackPos] |= valPtr[1]; - continue; - case OP_MUL: - valPtr[-1] *= valPtr[1]; - continue; - case OP_DIV: - valPtr[-1] /= valPtr[1]; - continue; - case OP_MOD: - valPtr[-1] %= valPtr[1]; - continue; - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - continue; - } - } - - if (operation != OP_END_EXPR) { - if (operation != stopToken) { - debugC(5, kDebugParser, "stoptoken error: %d != %d", - operation, stopToken); - } - flag = oldflag; - return values[0]; - } - - stkPos--; - operPtr--; - valPtr--; - } -} - -int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { - int32 values[20]; - byte operStack[20]; - int32 prevPrevVal; - int32 prevVal; - int32 curVal; - int32 *valPtr; - byte *operPtr; - byte *arrDescPtr; - byte operation; - int16 dimCount; - int16 temp; - int16 temp2; - int16 offset; - int16 dim; - bool var_1A; - int16 stkPos; - int16 brackStart; - uint32 varPos = 0; - - memset(operStack, 0, 20); - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - _vm->_global->_inter_execPtr += 2; - if (*_vm->_global->_inter_execPtr == 97) - _vm->_global->_inter_execPtr++; - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - if (*_vm->_global->_inter_execPtr == 97) - _vm->_global->_inter_execPtr++; - } - - debugC(2, kDebugParser, "parseExpr: Prefix %d (%d)", varPos, operation); - - operation = *_vm->_global->_inter_execPtr++; - } - - stkPos++; - operPtr++; - valPtr++; - - if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - *operPtr = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = offset * arrDescPtr[dim] + temp2; - } - if (operation == OP_ARRAY_UINT8) - *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); - else if (operation == OP_ARRAY_UINT32) - *valPtr = READ_VARO_UINT32(varPos + temp * 4 + offset * 4); - else if (operation == OP_ARRAY_UINT16) - *valPtr = (int16) READ_VARO_UINT16(varPos + temp * 2 + offset * 2); - else if (operation == OP_ARRAY_STR) { - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( - varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varPos + temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - } - break; - - case OP_LOAD_VAR_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); - break; - - case OP_LOAD_VAR_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) *_vm->_global->_inter_execPtr++; - break; - - case OP_LOAD_IMM_STR: - *operPtr = OP_LOAD_IMM_STR; - *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case 23: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); - break; - - case 24: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_STR: - *operPtr = OP_LOAD_IMM_STR; - temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp), kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varPos + temp); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - switch (operation) { - case FUNC_SQRT1: - case FUNC_SQRT2: - case FUNC_SQRT3: - curVal = 1; - prevVal = 1; - - do { - prevPrevVal = prevVal; - prevVal = curVal; - curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while ((curVal != prevVal) && (curVal != prevPrevVal)); - _vm->_global->_inter_resVal = curVal; - break; - - case FUNC_SQR: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - - case FUNC_ABS: - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - break; - - case FUNC_RAND: - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - break; - } - - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_global->_inter_resVal; - break; - } - - if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { - stkPos--; - operPtr--; - valPtr--; - - if (*operPtr == OP_NEG) { - *operPtr = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } else - *operPtr = (operPtr[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; - } - - if (stkPos <= 0) { - varPos = 0; - continue; - } - - switch (operPtr[-1]) { - case OP_ADD: - if (operPtr[-2] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); - valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - break; - - case OP_MUL: - valPtr[-2] *= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-2] /= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-2] %= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-2] &= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - varPos = 0; - continue; - } // (op >= OP_ARRAY_UINT8) && (op <= OP_FUNC) - - if ((operation == stopToken) || (operation == OP_OR) || - (operation == OP_AND) || (operation == OP_END_EXPR)) { - while (stkPos >= 2) { - var_1A = false; - if ((operPtr[-2] == OP_BEGIN_EXPR) && - ((operation == OP_END_EXPR) || (operation == stopToken))) { - operPtr[-2] = operPtr[-1]; - if ((operPtr[-2] == OP_LOAD_IMM_INT16) || (operPtr[-2] == OP_LOAD_IMM_STR)) - valPtr[-2] = valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - - if (stkPos > 1) { - if (operPtr[-2] == OP_NEG) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - stkPos--; - operPtr--; - valPtr--; - } else if (operPtr[-2] == OP_NOT) { - operPtr[-2] = (operPtr[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; - stkPos--; - operPtr--; - valPtr--; - } - } // stkPos > 1 - - if (stkPos > 2) { - switch (operPtr[-2]) { - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } // switch - } // stkPos > 2 - - if (operation != stopToken) - break; - } // if ((operPtr[-2] == OP_BEGIN_EXPR) && ...) - - for (brackStart = (stkPos - 2); (brackStart > 0) && - (operStack[brackStart] < OP_OR) && (operStack[brackStart] != OP_BEGIN_EXPR); - brackStart--) - ; - - if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) - brackStart++; - - switch (operPtr[-2]) { - case OP_ADD: - if (operStack[brackStart] == OP_LOAD_IMM_INT16) { - values[brackStart] += valPtr[-1]; - } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); - values[brackStart] = - encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_SUB: - values[brackStart] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_BITOR: - values[brackStart] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_OR: - // (x OR false) == x - // (x OR true) == true - if (operPtr[-3] == GOB_FALSE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_AND: - // (x AND false) == false - // (x AND true) == x - if (operPtr[-3] == GOB_TRUE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LESS: - operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GREATER: - operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_EQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_NEQ: { - int cmpTemp = 0; - - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - cmpTemp = valPtr[-3] - valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - // FIXME: Why scumm_stricmp here and strcmp everywhere else? - cmpTemp = scumm_stricmp(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - operPtr[-3] = (cmpTemp != 0) ? GOB_TRUE : GOB_FALSE; - //operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - - default: - var_1A = true; - break; - } // switch - - if (var_1A) - break; - } // while (stkPos >= 2) - - if ((operation == OP_OR) || (operation == OP_AND)) { - if (operPtr[-1] == OP_LOAD_IMM_INT16) { - if (valPtr[-1] != 0) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - } - - if (((operation == OP_OR) && (operPtr[-1] == GOB_TRUE)) || - ((operation == OP_AND) && (operPtr[-1] == GOB_FALSE))) { - if ((stkPos > 1) && (operPtr[-2] == OP_BEGIN_EXPR)) { - skipExpr(OP_END_EXPR); - operPtr[-2] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else { - skipExpr(stopToken); - } - operation = _vm->_global->_inter_execPtr[-1]; - if ((stkPos > 0) && (operPtr[-1] == OP_NOT)) { - if (operPtr[0] == GOB_FALSE) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } else - operPtr[0] = operation; - } else { - stkPos--; - operPtr--; - valPtr--; - } - - if (operation != stopToken) - continue; - - if (arg_2 != 0) - *arg_2 = operStack[0]; - - switch (operStack[0]) { - case OP_NOT: - if (arg_2 != 0) - *arg_2 ^= 1; - break; - - case OP_LOAD_IMM_INT16: - _vm->_global->_inter_resVal = values[0]; - break; - - case OP_LOAD_IMM_STR: - if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); - break; - - case 23: - case 24: - break; - - default: - _vm->_global->_inter_resVal = 0; - if (arg_2 != 0) - *arg_2 = OP_LOAD_IMM_INT16; - break; - } - return 0; - } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) - - if ((operation < OP_NEG) || (operation > OP_NOT)) { - if ((operation < OP_LESS) || (operation > OP_NEQ)) - continue; - - if (stkPos > 2) { - if (operPtr[-2] == OP_ADD) { - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - valPtr[-3] += valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - } else if (operPtr[-2] == OP_SUB) { - valPtr[-3] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else if (operPtr[-2] == OP_BITOR) { - valPtr[-3] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - } - } - *operPtr = operation; - } -} - -int16 Parse_v2::getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9) { - if (arg_0 < 0) - return 0; - - if (arg_2 > arg_0) - return arg_0; - - return arg_2 - 1; -} - -} // End of namespace Gob |