scummvm/engines/gob/parse.cpp
Sven Hesse 2dc7cb2cd4 Major clean-up, including:
- Cutting down the code-dup
- Plucking leaks
- Removing dead/unused code
- Properly naming "word_2342F"-style variables and functions (removing the warnings alongside)
- Fleshing out the "stubby" functions
- Moving functions and variables to more appropriate/logical places
- Re-ordering functions and variables
- Re-structuring functions
- Moving the IMD stuff into a new "Imd" class in the new imd.cpp/.h (still to be completely implemented and cleaned up)
- Formatting
- Getting rid off the classes "Anim", "Pack" and "Timer", along with their files

svn-id: r26252
2007-03-20 14:51:57 +00:00

450 lines
8.8 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 Ivan Dubrov
* Copyright (C) 2004-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "gob/gob.h"
#include "gob/parse.h"
#include "gob/global.h"
#include "gob/game.h"
#include "gob/inter.h"
namespace Gob {
Parse::Parse(GobEngine *vm) : _vm(vm) {
}
int32 Parse::encodePtr(char *ptr, int type) {
int32 offset = 0;
switch (type) {
case kExecPtr:
offset = ptr - _vm->_game->_totFileData;
break;
case kInterVar:
offset = ptr - _vm->_global->_inter_variables;
break;
case kResStr:
offset = ptr - _vm->_global->_inter_resStr;
break;
default:
error("encodePtr: Unknown pointer type");
}
assert((offset & 0xF0000000) == 0);
return (type << 28) | offset;
}
char *Parse::decodePtr(int32 n) {
char *ptr;
switch (n >> 28) {
case kExecPtr:
ptr = _vm->_game->_totFileData;
break;
case kInterVar:
ptr = _vm->_global->_inter_variables;
break;
case kResStr:
ptr = _vm->_global->_inter_resStr;
break;
default:
error("decodePtr: Unknown pointer type");
}
return ptr + (n & 0x0FFFFFFF);
}
void Parse::skipExpr(char stopToken) {
int16 dimCount;
char operation;
int16 num;
int16 dim;
num = 0;
while (1) {
operation = *_vm->_global->_inter_execPtr++;
if ((operation >= 16) && (operation <= 29)) {
switch (operation) {
case 17:
case 18:
case 20:
case 23:
case 24:
_vm->_global->_inter_execPtr += 2;
break;
case 19:
_vm->_global->_inter_execPtr += 4;
break;
case 21:
_vm->_global->_inter_execPtr += 1;
break;
case 22:
_vm->_global->_inter_execPtr +=
strlen(_vm->_global->_inter_execPtr) + 1;
break;
case 25:
_vm->_global->_inter_execPtr += 2;
if (*_vm->_global->_inter_execPtr == 13) {
_vm->_global->_inter_execPtr++;
skipExpr(12);
}
break;
case 16:
case 26:
case 27:
case 28:
dimCount = _vm->_global->_inter_execPtr[2];
// skip header and dimensions
_vm->_global->_inter_execPtr += 3 + dimCount;
// skip indices
for (dim = 0; dim < dimCount; dim++)
skipExpr(12);
if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) {
_vm->_global->_inter_execPtr++;
skipExpr(12);
}
break;
case 29:
_vm->_global->_inter_execPtr++;
skipExpr(10);
}
continue;
} // if ((operation >= 16) && (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 != stopToken)
continue;
if ((stopToken != 10) || (num < 0))
return;
}
}
void Parse::printExpr(char stopToken) {
// Expression printing disabled by default
return;
char* savedPos = _vm->_global->_inter_execPtr;
printExpr_internal(stopToken);
// restore IP to start of expression
_vm->_global->_inter_execPtr = savedPos;
}
void Parse::printExpr_internal(char stopToken) {
int16 dimCount;
char operation;
int16 num;
int16 dim;
char *arrDesc;
char func;
num = 0;
while (1) {
operation = *_vm->_global->_inter_execPtr++;
if ((operation >= 16) && (operation <= 29)) {
// operands
switch (operation) {
case 17: // uint16 variable load
debugN(5, "var16_%d", _vm->_inter->load16());
break;
case 18: // uint8 variable load:
debugN(5, "var8_%d", _vm->_inter->load16());
break;
case 19: // uint32 immediate
debugN(5, "%d", READ_LE_UINT32(_vm->_global->_inter_execPtr));
_vm->_global->_inter_execPtr += 4;
break;
case 20: // uint16 immediate
debugN(5, "%d", _vm->_inter->load16());
break;
case 21: // uint8 immediate
debugN(5, "%d", *_vm->_global->_inter_execPtr++);
break;
case 22: // string immediate
debugN(5, "\42%s\42", _vm->_global->_inter_execPtr);
_vm->_global->_inter_execPtr +=
strlen(_vm->_global->_inter_execPtr) + 1;
break;
case 23: // uint32 variable load
case 24: // uint32 variable load as uint16
debugN(5, "var_%d", _vm->_inter->load16());
break;
case 25: // string variable load
debugN(5, "(&var_%d)", _vm->_inter->load16());
if (*_vm->_global->_inter_execPtr == 13) {
_vm->_global->_inter_execPtr++;
debugN(5, "{");
printExpr_internal(12); // this also prints the closing }
}
break;
case 16: // uint8 array access
case 26: // uint32 array access
case 27: // uint16 array access
case 28: // string array access
debugN(5, "\n");
if (operation == 28)
debugN(5, "(&");
debugN(5, "var_%d[", _vm->_inter->load16());
dimCount = *_vm->_global->_inter_execPtr++;
arrDesc = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += dimCount;
for (dim = 0; dim < dimCount; dim++) {
printExpr_internal(12);
debugN(5, " of %d", (int16)arrDesc[dim]);
if (dim != dimCount - 1)
debugN(5, ",");
}
debugN(5, "]");
if (operation == 28)
debugN(5, ")");
if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) {
_vm->_global->_inter_execPtr++;
debugN(5, "{");
printExpr_internal(12); // this also prints the closing }
}
break;
case 29: // function
func = *_vm->_global->_inter_execPtr++;
if (func == 5)
debugN(5, "sqr(");
else if (func == 10)
debugN(5, "rand(");
else if (func == 7)
debugN(5, "abs(");
else if ((func == 0) || (func == 1) || (func == 6))
debugN(5, "sqrt(");
else
debugN(5, "id(");
printExpr_internal(10);
break;
}
continue;
} // if ((operation >= 16) && (operation <= 29))
// operators
switch (operation) {
case 9:
debugN(5, "(");
break;
case 11:
debugN(5, "!");
break;
case 10:
debugN(5, ")");
break;
case 1:
debugN(5, "-");
break;
case 2:
debugN(5, "+");
break;
case 3:
debugN(5, "-");
break;
case 4:
debugN(5, "|");
break;
case 5:
debugN(5, "*");
break;
case 6:
debugN(5, "/");
break;
case 7:
debugN(5, "%%");
break;
case 8:
debugN(5, "&");
break;
case 30:
debugN(5, "||");
break;
case 31:
debugN(5, "&&");
break;
case 32:
debugN(5, "<");
break;
case 33:
debugN(5, "<=");
break;
case 34:
debugN(5, ">");
break;
case 35:
debugN(5, ">=");
break;
case 36:
debugN(5, "==");
break;
case 37:
debugN(5, "!=");
break;
case 99:
debugN(5, "\n");
break;
case 12:
debugN(5, "}");
if (stopToken != 12) {
debugN(5, "Closing paren without opening?");
}
break;
default:
debugN(5, "<%d>", (int16) operation);
error("printExpr: invalid operator in expression");
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 == stopToken) {
if ((stopToken != 10) || (num < 0)) {
return;
}
}
}
}
void Parse::printVarIndex() {
char *arrDesc;
int16 dim;
int16 dimCount;
int16 operation;
int16 temp;
char *pos = _vm->_global->_inter_execPtr;
operation = *_vm->_global->_inter_execPtr++;
switch (operation) {
case 23:
case 25:
temp = _vm->_inter->load16() * 4;
debugN(5, "&var_%d", temp);
if ((operation == 25) && (*_vm->_global->_inter_execPtr == 13)) {
_vm->_global->_inter_execPtr++;
debugN(5, "+");
printExpr(12);
}
break;
case 26:
case 28:
debugN(5, "&var_%d[", _vm->_inter->load16());
dimCount = *_vm->_global->_inter_execPtr++;
arrDesc = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += dimCount;
for (dim = 0; dim < dimCount; dim++) {
printExpr(12);
debugN(5, " of %d", (int16)arrDesc[dim]);
if (dim != dimCount - 1)
debugN(5, ",");
}
debugN(5, "]");
if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) {
_vm->_global->_inter_execPtr++;
debugN(5, "+");
printExpr(12);
}
break;
default:
debugN(5, "var_0");
break;
}
debugN(5, "\n");
_vm->_global->_inter_execPtr = pos;
return;
}
} // End of namespace Gob