aboutsummaryrefslogtreecommitdiff
path: root/scumm/script_v72he.cpp
diff options
context:
space:
mode:
authorMax Horn2006-02-11 22:45:04 +0000
committerMax Horn2006-02-11 22:45:04 +0000
commit26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch)
tree26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /scumm/script_v72he.cpp
parent2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff)
downloadscummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'scumm/script_v72he.cpp')
-rw-r--r--scumm/script_v72he.cpp2352
1 files changed, 0 insertions, 2352 deletions
diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp
deleted file mode 100644
index 021a74dcc3..0000000000
--- a/scumm/script_v72he.cpp
+++ /dev/null
@@ -1,2352 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-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/config-manager.h"
-#include "common/savefile.h"
-#include "common/system.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v72he, x)
-
-void ScummEngine_v72he::setupOpcodes() {
- static const OpcodeEntryV72he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o72_pushDWord),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o72_getScriptString),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o72_isAnyOf),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o72_resetCutscene),
- OPCODE(o6_invalid),
- OPCODE(o72_findObjectWithClassOf),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o72_getObjectImageX),
- OPCODE(o72_getObjectImageY),
- OPCODE(o72_captureWizImage),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o72_getTimer),
- OPCODE(o72_setTimer),
- OPCODE(o72_getSoundPosition),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o72_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o72_startObject),
- OPCODE(o72_drawObject),
- OPCODE(o72_printWizImage),
- OPCODE(o72_getArrayDimSize),
- /* 64 */
- OPCODE(o72_getNumFreeArrays),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_stopMusic),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o6_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o60_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o70_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_startMusic),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o70_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o70_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o70_resourceRoutines),
- /* 9C */
- OPCODE(o72_roomOps),
- OPCODE(o72_actorOps),
- OPCODE(o72_verbOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o72_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o72_arrayOps),
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o6_invalid),
- OPCODE(o6_isAnyOf),
- OPCODE(o72_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o72_talkActor),
- OPCODE(o72_talkEgo),
- /* BC */
- OPCODE(o72_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o72_dim2dimArray),
- OPCODE(o72_traceStatus),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o72_kernelGetFunctions),
- OPCODE(o70_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o72_drawWizImage),
- OPCODE(o72_debugInput),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o72_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o72_openFile),
- OPCODE(o72_readFile),
- /* DC */
- OPCODE(o72_writeFile),
- OPCODE(o72_findAllObjects),
- OPCODE(o72_deleteFile),
- OPCODE(o72_rename),
- /* E0 */
- OPCODE(o60_soundOps),
- OPCODE(o72_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o72_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o72_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o70_copyString),
- OPCODE(o70_getStringWidth),
- OPCODE(o70_getStringLen),
- OPCODE(o70_appendString),
- /* F0 */
- OPCODE(o70_concatString),
- OPCODE(o70_compareString),
- OPCODE(o70_isResourceLoaded),
- OPCODE(o72_readINI),
- /* F4 */
- OPCODE(o72_writeINI),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o70_getCharIndexInString),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o72_getResourceSize),
- OPCODE(o72_setFilePath),
- OPCODE(o72_setWindowCaption),
- OPCODE(o70_polygonOps),
- /* FC */
- OPCODE(o70_polygonHit),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV72he = opcodes;
-}
-
-void ScummEngine_v72he::executeOpcode(byte i) {
- OpcodeProcV72he op = _opcodesV72he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v72he::getOpcodeDesc(byte i) {
- return _opcodesV72he[i].desc;
-}
-
-static const int arrayDataSizes[] = { 0, 1, 4, 8, 8, 16, 32 };
-
-ScummEngine_v72he::ArrayHeader *ScummEngine_v72he::defineArray(int array, int type, int dim2start, int dim2end,
- int dim1start, int dim1end) {
- int id;
- int size;
- ArrayHeader *ah;
-
- assert(dim2start >= 0 && dim2start <= dim2end);
- assert(dim1start >= 0 && dim1start <= dim1end);
- assert(0 <= type && type <= 6);
-
-
- if (type == kBitArray || type == kNibbleArray)
- type = kByteArray;
-
- nukeArray(array);
-
- id = findFreeArrayId();
-
- debug(9,"defineArray (array %d, dim2start %d, dim2end %d dim1start %d dim1end %d", id, dim2start, dim2end, dim1start, dim1end);
-
- if (array & 0x80000000) {
- error("Can't define bit variable as array pointer");
- }
-
- size = arrayDataSizes[type];
-
- if (_heversion >= 80)
- id |= 0x33539000;
-
- writeVar(array, id);
-
- if (_heversion >= 80)
- id &= ~0x33539000;
-
- size *= dim2end - dim2start + 1;
- size *= dim1end - dim1start + 1;
- size >>= 3;
-
- ah = (ArrayHeader *)res.createResource(rtString, id, size + sizeof(ArrayHeader));
-
- ah->type = TO_LE_32(type);
- ah->dim1start = TO_LE_32(dim1start);
- ah->dim1end = TO_LE_32(dim1end);
- ah->dim2start = TO_LE_32(dim2start);
- ah->dim2end = TO_LE_32(dim2end);
-
- return ah;
-}
-
-int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
- debug(9, "readArray (array %d, idx2 %d, idx1 %d)", readVar(array), idx2, idx1);
-
- if (readVar(array) == 0)
- error("readArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
-
- if (ah == NULL || ah->data == NULL)
- error("readArray: invalid array %d (%d)", array, readVar(array));
-
- if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
- idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
- error("readArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
- array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
- FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
- }
-
- const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (idx2 - FROM_LE_32(ah->dim2start)) - FROM_LE_32(ah->dim1start) + idx1;
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- return ah->data[offset];
-
- case kIntArray:
- return (int16)READ_LE_UINT16(ah->data + offset * 2);
-
- case kDwordArray:
- return (int32)READ_LE_UINT32(ah->data + offset * 4);
- }
-
- return 0;
-}
-
-void ScummEngine_v72he::writeArray(int array, int idx2, int idx1, int value) {
- debug(9, "writeArray (array %d, idx2 %d, idx1 %d, value %d)", readVar(array), idx2, idx1, value);
-
- if (readVar(array) == 0)
- error("writeArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
-
- if (!ah)
- error("writeArray: Invalid array (%d) reference", readVar(array));
-
- if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
- idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
- error("writeArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
- array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
- FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
- }
-
- const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (idx2 - FROM_LE_32(ah->dim2start)) - FROM_LE_32(ah->dim1start) + idx1;
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- ah->data[offset] = value;
- break;
-
- case kIntArray:
- WRITE_LE_UINT16(ah->data + offset * 2, value);
- break;
-
- case kDwordArray:
- WRITE_LE_UINT32(ah->data + offset * 4, value);
- break;
- }
-}
-
-int ScummEngine_v72he::setupStringArray(int size) {
- writeVar(0, 0);
- defineArray(0, kStringArray, 0, 0, 0, size + 1);
- writeArray(0, 0, 0, 0);
- return readVar(0);
-}
-
-void ScummEngine_v72he::readArrayFromIndexFile() {
- int num;
- int a, b, c;
-
- while ((num = _fileHandle->readUint16LE()) != 0) {
- a = _fileHandle->readUint16LE();
- b = _fileHandle->readUint16LE();
- c = _fileHandle->readUint16LE();
-
- if (c == 1)
- defineArray(num, kBitArray, 0, a, 0, b);
- else
- defineArray(num, kDwordArray, 0, a, 0, b);
- }
-}
-
-int ScummEngine_v72he::convertFilePath(byte *dst, bool setFilePath) {
- debug(1, "convertFilePath: original filePath is %s", dst);
-
- // Switch all \ to / for portablity
- int len = resStrLen(dst) + 1;
- for (int i = 0; i < len; i++) {
- if (dst[i] == '\\')
- dst[i] = '/';
- }
-
- // Strip path
- int r = 0;
- if (dst[0] == '.' && dst[1] == '/') {
- r = 2;
- } else if (dst[0] == 'c' && dst[1] == ':') {
- for (r = len; r != 0; r--) {
- if (dst[r - 1] == '/')
- break;
- }
- }
-
- if (setFilePath) {
- char filePath[256];
- sprintf(filePath, "%s%s", _gameDataPath.c_str(), dst + r);
- if (!Common::File::exists(filePath)) {
- sprintf(filePath, "%s%s", _saveFileMan->getSavePath(), dst + r);
- }
- strcpy((char *)dst, filePath);
- debug(1, "convertFilePath: filePath is %s", dst);
- }
-
- return r;
-}
-
-void ScummEngine_v72he::copyScriptString(byte *dst, int dstSize) {
- byte string[1024];
- byte chr;
- int pos = 0;
-
- int array = pop();
- if (array == -1) {
- if (_stringLength == 1)
- error("String stack underflow");
-
- _stringLength -= 2;
- while ((chr = _stringBuffer[_stringLength]) != 0) {
- string[pos] = chr;
- pos++;
-
- if (pos > dstSize)
- error("String too long to pop");
-
- _stringLength--;
- }
-
- string[pos] = 0;
- _stringLength++;
-
- // Reverse string
- int len = resStrLen(string);
- while (len--)
- *dst++ = string[len];
- } else {
- writeVar(0, array);
- while ((chr = readArray(0, 0, pos)) != 0) {
- *dst++ = chr;
- pos++;
- }
- }
- *dst = 0;
-}
-
-void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
- const byte *src;
- int args[31];
- int num, len, val;
- byte chr, string[1024];
- memset(args, 0, sizeof(args));
- memset(string, 0, sizeof(string));
-
- // Get stack list, plus one
- num = pop();
- for (int i = num; i >= 0; i--)
- args[i] = pop();
-
- // Get string
- if (scriptString) {
- len = resStrLen(_scriptPointer) + 1;
- memcpy(string, _scriptPointer, len);
- _scriptPointer += len;
- } else {
- copyScriptString(string, sizeof(string));
- len = resStrLen(string) + 1;
- }
-
- // Decode string
- num = 0;
- val = 0;
- while (len--) {
- chr = string[num++];
- if (chr == '%') {
- chr = string[num++];
- switch(chr) {
- case 'b':
- //dst += sprintf((char *)dst, "%b", args[val++]);
- break;
- case 'c':
- *dst++ = args[val++];
- break;
- case 'd':
- dst += sprintf((char *)dst, "%d", args[val++]);
- break;
- case 's':
- src = getStringAddress(args[val++]);
- if (src) {
- while (*src != 0)
- *dst++ = *src++;
- }
- break;
- case 'x':
- dst += sprintf((char *)dst, "%x", args[val++]);
- break;
- default:
- *dst++ = '%';
- num--;
- break;
- }
- } else {
- *dst++ = chr;
- }
- }
- *dst = 0;
-}
-
-byte *ScummEngine_v70he::heFindResourceData(uint32 tag, byte *ptr) {
- ptr = heFindResource(tag, ptr);
-
- if (ptr == NULL)
- return NULL;
- return ptr + _resourceHeaderSize;
-}
-
-byte *ScummEngine_v70he::heFindResource(uint32 tag, byte *searchin) {
- uint32 curpos, totalsize, size;
-
- debugC(DEBUG_RESOURCE, "heFindResource(%s, %lx)", tag2str(tag), searchin);
-
- assert(searchin);
- searchin += 4;
- _resourceLastSearchSize = totalsize = READ_BE_UINT32(searchin);
- curpos = 8;
- searchin += 4;
-
- while (curpos < totalsize) {
- if (READ_UINT32(searchin) == tag) {
- return searchin;
- }
-
- size = READ_BE_UINT32(searchin + 4);
- if ((int32)size <= 0) {
- error("(%s) Not found in %d... illegal block len %d", tag2str(tag), 0, size);
- return NULL;
- }
-
- curpos += size;
- searchin += size;
- }
-
- return NULL;
-}
-
-byte *ScummEngine_v70he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool errorFlag) {
- if (READ_UINT32(ptr) == MKID('MULT')) {
- byte *offs, *wrap;
- uint32 size;
-
- wrap = heFindResource(MKID('WRAP'), ptr);
- if (wrap == NULL)
- return NULL;
-
- offs = heFindResourceData(MKID('OFFS'), wrap);
- if (offs == NULL)
- return NULL;
-
- size = getResourceDataSize(offs) / 4;
- assert((uint32)state <= (uint32)size);
-
-
- offs += READ_LE_UINT32(offs + state * sizeof(uint32));
- offs = heFindResourceData(tag, offs - 8);
- if (offs)
- return offs;
-
- offs = heFindResourceData(MKID('DEFA'), ptr);
- if (offs == NULL)
- return NULL;
-
- return heFindResourceData(tag, offs - 8);
- } else {
- return heFindResourceData(tag, ptr);
- }
-}
-
-int ScummEngine_v72he::findObject(int x, int y, int num, int *args) {
- int b, cls, i, result;
-
- for (i = 1; i < _numLocalObjects; i++) {
- result = 0;
- if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))
- continue;
-
- // Check polygon bounds
- if (_wiz->polygonDefined(_objs[i].obj_nr)) {
- if (_wiz->polygonHit(_objs[i].obj_nr, x, y))
- result = _objs[i].obj_nr;
- else if (VAR_POLYGONS_ONLY != 0xFF && VAR(VAR_POLYGONS_ONLY))
- continue;
- }
-
- if (!result) {
- // Check object bounds
- if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
- _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
- result = _objs[i].obj_nr;
- }
-
- if (result) {
- if (!num)
- return result;
-
- // Check object class
- cls = args[0];
- b = getClass(_objs[i].obj_nr, cls);
- if ((cls & 0x80 && b) || (!(cls & 0x80) && !b))
- return result;
- }
- }
-
- return 0;
-}
-
-void ScummEngine_v72he::o72_pushDWord() {
- push(fetchScriptDWordSigned());
-}
-
-void ScummEngine_v72he::o72_getScriptString() {
- byte chr;
-
- while ((chr = fetchScriptByte()) != 0) {
- _stringBuffer[_stringLength] = chr;
- _stringLength++;
-
- if (_stringLength >= 4096)
- error("String stack overflow");
- }
-
- _stringBuffer[_stringLength] = 0;
- _stringLength++;
-}
-
-void ScummEngine_v72he::o72_isAnyOf() {
- int args[128];
- int num, value;
-
- num = getStackList(args, ARRAYSIZE(args));
- value = pop();
-
- for (int i = 0; i < num; i++) {
- if (args[i] == value) {
- push(1);
- return;
- }
- }
-
- push(0);
-}
-
-void ScummEngine_v72he::o72_resetCutscene() {
- int idx;
-
- idx = vm.cutSceneStackPointer;
- vm.cutSceneStackPointer = 0;
- vm.cutScenePtr[idx] = 0;
- vm.cutSceneScript[idx] = 0;
-
- VAR(VAR_OVERRIDE) = 0;
-}
-
-void ScummEngine_v72he::o72_findObjectWithClassOf() {
- int args[16], num;
-
- num = getStackList(args, ARRAYSIZE(args));
- int y = pop();
- int x = pop();
- int r = findObject(x, y, num, args);
- push(r);
-}
-
-void ScummEngine_v72he::o72_getObjectImageX() {
- int object = pop();
- int objnum = getObjectIndex(object);
-
- if (objnum == -1) {
- push(0);
- return;
- }
-
- push(_objs[objnum].x_pos / 8);
-}
-
-void ScummEngine_v72he::o72_getObjectImageY() {
- int object = pop();
- int objnum = getObjectIndex(object);
-
- if (objnum == -1) {
- push(0);
- return;
- }
-
- push(_objs[objnum].y_pos / 8);
-}
-
-void ScummEngine_v72he::o72_captureWizImage() {
- Common::Rect grab;
- grab.bottom = pop() + 1;
- grab.right = pop() + 1;
- grab.top = pop();
- grab.left = pop();
- _wiz->captureWizImage(pop(), grab, false, true);
-}
-
-void ScummEngine_v72he::o72_getTimer() {
- int timer = pop();
- byte cmd = fetchScriptByte();
-
- if (cmd == 10 || cmd == 50) {
- push(getHETimer(timer));
- } else {
- push(0);
- }
-}
-
-void ScummEngine_v72he::o72_setTimer() {
- int timer = pop();
- byte cmd = fetchScriptByte();
-
- if (cmd == 158 || cmd == 61) {
- setHETimer(timer);
- } else {
- error("TIMER command %d?", cmd);
- }
-}
-
-void ScummEngine_v72he::o72_getSoundPosition() {
- int snd = pop();
- push(_sound->getSoundPos(snd));
-}
-
-void ScummEngine_v72he::o72_startScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_startObject() {
- int args[25];
- int script, entryp;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- entryp = pop();
- script = pop();
- flags = fetchScriptByte();
- runObjectScript(script, entryp, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_drawObject() {
- byte subOp = fetchScriptByte();
- int state, y, x;
-
- switch (subOp) {
- case 62:
- state = pop();
- y = pop();
- x = pop();
- break;
- case 63:
- state = pop();
- if (state == 0)
- state = 1;
- y = x = -100;
- break;
- case 65:
- state = 1;
- y = pop();
- x = pop();
- break;
- default:
- error("o72_drawObject: default case %d", subOp);
- }
-
- int object = pop();
- int objnum = getObjectIndex(object);
- if (objnum == -1)
- return;
-
- if (y != -100 && x != -100) {
- _objs[objnum].x_pos = x * 8;
- _objs[objnum].y_pos = y * 8;
- }
-
- if (state != -1) {
- addObjectToDrawQue(objnum);
- putState(object, state);
- }
-}
-
-void ScummEngine_v72he::o72_printWizImage() {
- WizImage wi;
- wi.resNum = pop();
- wi.x1 = wi.y1 = 0;
- wi.state = 0;
- wi.flags = kWIFPrint;
- _wiz->displayWizImage(&wi);
-}
-
-void ScummEngine_v72he::o72_getArrayDimSize() {
- byte subOp = fetchScriptByte();
- int32 val1, val2;
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
- if (!ah) {
- push(0);
- return;
- }
-
- switch (subOp) {
- case 1:
- case 3:
- val1 = FROM_LE_32(ah->dim1end);
- val2 = FROM_LE_32(ah->dim1start);
- push(val1 - val2 + 1);
- break;
- case 2:
- val1 = FROM_LE_32(ah->dim2end);
- val2 = FROM_LE_32(ah->dim2start);
- push(val1 - val2 + 1);
- break;
- case 4:
- push(FROM_LE_32(ah->dim1start));
- break;
- case 5:
- push(FROM_LE_32(ah->dim1end));
- break;
- case 6:
- push(FROM_LE_32(ah->dim2start));
- break;
- case 7:
- push(FROM_LE_32(ah->dim2end));
- break;
- default:
- error("o72_getArrayDimSize: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_getNumFreeArrays() {
- byte **addr = res.address[rtString];
- int i, num = 0;
-
- for (i = 1; i < _numArray; i++) {
- if (!addr[i])
- num++;
- }
-
- push (num);
-}
-
-void ScummEngine_v72he::o72_roomOps() {
- int a, b, c, d, e;
- byte filename[100];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 172: // SO_ROOM_SCROLL
- b = pop();
- a = pop();
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
-
- case 174: // SO_ROOM_SCREEN
- b = pop();
- a = pop();
- initScreens(a, _screenHeight);
- break;
-
- case 175: // SO_ROOM_PALETTE
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
-
- case 179: // SO_ROOM_INTENSITY
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
-
- case 180: // SO_ROOM_SAVEGAME
- _saveTemporaryState = true;
- _saveLoadSlot = pop();
- _saveLoadFlag = pop();
- break;
-
- case 181: // SO_ROOM_FADE
- // Defaults to 1 but doesn't use fade effects
- a = pop();
- break;
-
- case 182: // SO_RGB_ROOM_INTENSITY
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
-
- case 213: // SO_ROOM_NEW_PALETTE
- a = pop();
- setPalette(a);
- break;
-
- case 220:
- a = pop();
- b = pop();
- copyPalColor(a, b);
- break;
-
- case 221:
- copyScriptString(filename, sizeof(filename));
- _saveLoadFlag = pop();
- _saveLoadSlot = 1;
- _saveTemporaryState = true;
- break;
-
- case 234:
- b = pop();
- a = pop();
- swapObjects(a, b);
- break;
-
- case 236:
- b = pop();
- a = pop();
- setRoomPalette(a, b);
- break;
-
- default:
- error("o72_roomOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_actorOps() {
- Actor *a;
- int i, j, k;
- int args[32];
- byte string[256];
-
- byte subOp = fetchScriptByte();
- if (subOp == 197) {
- _curActor = pop();
- return;
- }
-
- a = derefActorSafe(_curActor, "o72_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 21: // HE 80+
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; ++i) {
- a->setUserCondition(args[i] & 0x7F, args[i] & 0x80);
- }
- break;
- case 24: // HE 80+
- k = pop();
- if (k == 0)
- k = _rnd.getRandomNumberRng(1, 10);
- a->_heNoTalkAnimation = 1;
- a->setTalkCondition(k);
- break;
- case 43: // HE 90+
- // HE games use reverse order of layering, so we adjust
- a->_layer = -pop();
- a->_needRedraw = true;
- break;
- case 64:
- _actorClipOverride.bottom = pop();
- _actorClipOverride.right = pop();
- _actorClipOverride.top = pop();
- _actorClipOverride.left = pop();
- break;
- case 67: // HE 99+
- a->_clipOverride.bottom = pop();
- a->_clipOverride.right = pop();
- a->_clipOverride.top = pop();
- a->_clipOverride.left = pop();
- break;
- case 65: // HE 98+
- j = pop();
- i = pop();
- a->putActor(i, j, a->_room);
- break;
- case 68: // HE 90+
- k = pop();
- debug(0,"o72_actorOps: case 68 (%d)", k);
- break;
- case 76: // SO_COSTUME
- a->setActorCostume(pop());
- break;
- case 77: // SO_STEP_DIST
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 78: // SO_SOUND
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; i++)
- a->_sound[i] = args[i];
- break;
- case 79: // SO_WALK_ANIMATION
- a->_walkFrame = pop();
- break;
- case 80: // SO_TALK_ANIMATION
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 81: // SO_STAND_ANIMATION
- a->_standFrame = pop();
- break;
- case 82: // SO_ANIMATION
- // dummy case in scumm6
- pop();
- pop();
- pop();
- break;
- case 83: // SO_DEFAULT
- a->initActor(0);
- break;
- case 84: // SO_ELEVATION
- a->setElevation(pop());
- break;
- case 85: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 86: // SO_PALETTE
- j = pop();
- i = pop();
- checkRange(255, 0, i, "Illegal palette slot %d");
- a->remapActorPaletteColor(i, j);
- a->_needRedraw = true;
- break;
- case 87: // SO_TALK_COLOR
- a->_talkColor = pop();
- break;
- case 88: // SO_ACTOR_NAME
- copyScriptString(string, sizeof(string));
- loadPtrToResource(rtActorName, a->_number, string);
- break;
- case 89: // SO_INIT_ANIMATION
- a->_initFrame = pop();
- break;
- case 91: // SO_ACTOR_WIDTH
- a->_width = pop();
- break;
- case 92: // SO_SCALE
- i = pop();
- a->setScale(i, i);
- break;
- case 93: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 94: // SO_ALWAYS_ZCLIP
- a->_forceClip = pop();
- break;
- case 95: // SO_IGNORE_BOXES
- a->_ignoreBoxes = 1;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 96: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = 0;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 97: // SO_ANIMATION_SPEED
- a->setAnimSpeed(pop());
- break;
- case 98: // SO_SHADOW
- a->_heXmapNum = pop();
- a->_needRedraw = true;
- break;
- case 99: // SO_TEXT_OFFSET
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
- case 156: // HE 72+
- a->_charset = pop();
- break;
- case 175: // HE 99+
- a->_hePaletteNum = pop();
- a->_needRedraw = true;
- break;
- case 198: // SO_ACTOR_VARIABLE
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 215: // SO_ACTOR_IGNORE_TURNS_ON
- a->_ignoreTurns = true;
- break;
- case 216: // SO_ACTOR_IGNORE_TURNS_OFF
- a->_ignoreTurns = false;
- break;
- case 217: // SO_ACTOR_NEW
- a->initActor(2);
- break;
- case 218:
- a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
- break;
- case 219:
- a->_drawToBackBuf = false;
- a->_needRedraw = true;
- a->_needBgReset = true;
- break;
- case 225:
- {
- copyScriptString(string, sizeof(string));
- int slot = pop();
-
- int len = resStrLen(string) + 1;
- memcpy(a->_heTalkQueue[slot].sentence, string, len);
-
- a->_heTalkQueue[slot].posX = a->_talkPosX;
- a->_heTalkQueue[slot].posY = a->_talkPosY;
- a->_heTalkQueue[slot].color = a->_talkColor;
- break;
- }
- default:
- error("o72_actorOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_verbOps() {
- int slot, a, b;
- VerbSlot *vs;
- byte name[200];
-
- byte subOp = fetchScriptByte();
- if (subOp == 196) {
- _curVerb = pop();
- _curVerbSlot = getVerbSlot(_curVerb, 0);
- checkRange(_numVerbs - 1, 0, _curVerbSlot, "Illegal new verb slot %d");
- return;
- }
- vs = &_verbs[_curVerbSlot];
- slot = _curVerbSlot;
- switch (subOp) {
- case 124: // SO_VERB_IMAGE
- a = pop();
- if (_curVerbSlot) {
- setVerbObject(_roomResource, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 125: // SO_VERB_NAME
- copyScriptString(name, sizeof(name));
- loadPtrToResource(rtVerb, slot, name);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 126: // SO_VERB_COLOR
- vs->color = pop();
- break;
- case 127: // SO_VERB_HICOLOR
- vs->hicolor = pop();
- break;
- case 128: // SO_VERB_AT
- vs->curRect.top = pop();
- vs->curRect.left = pop();
- break;
- case 129: // SO_VERB_ON
- vs->curmode = 1;
- break;
- case 130: // SO_VERB_OFF
- vs->curmode = 0;
- break;
- case 131: // SO_VERB_DELETE
- slot = getVerbSlot(pop(), 0);
- killVerb(slot);
- break;
- case 132: // SO_VERB_NEW
- slot = getVerbSlot(_curVerb, 0);
- if (slot == 0) {
- for (slot = 1; slot < _numVerbs; slot++) {
- if (_verbs[slot].verbid == 0)
- break;
- }
- if (slot == _numVerbs)
- error("Too many verbs");
- _curVerbSlot = slot;
- }
- vs = &_verbs[slot];
- vs->verbid = _curVerb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
- case 133: // SO_VERB_DIMCOLOR
- vs->dimcolor = pop();
- break;
- case 134: // SO_VERB_DIM
- vs->curmode = 2;
- break;
- case 135: // SO_VERB_KEY
- vs->key = pop();
- break;
- case 136: // SO_VERB_CENTER
- vs->center = 1;
- break;
- case 137: // SO_VERB_NAME_STR
- a = pop();
- if (a == 0) {
- loadPtrToResource(rtVerb, slot, (const byte *)"");
- } else {
- loadPtrToResource(rtVerb, slot, getStringAddress(a));
- }
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 139: // SO_VERB_IMAGE_IN_ROOM
- b = pop();
- a = pop();
-
- if (slot && a != vs->imgindex) {
- setVerbObject(b, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 140: // SO_VERB_BAKCOLOR
- vs->bkcolor = pop();
- break;
- case 255:
- drawVerb(slot, 0);
- verbMouseOver(0);
- break;
- default:
- error("o72_verbops: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_findObject() {
- int y = pop();
- int x = pop();
- int r = findObject(x, y, 0, 0);
- push(r);
-}
-
-void ScummEngine_v72he::o72_arrayOps() {
- ArrayHeader *ah;
- byte string[1024];
- int dim1end, dim1start, dim2end, dim2start;
- int id, len, b, c, list[128];
- int offs, tmp, tmp2;
- uint tmp3;
-
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
- debug(9,"o72_arrayOps: array %d case %d", array, subOp);
-
- switch (subOp) {
- case 7: // SO_ASSIGN_STRING
- copyScriptString(string, sizeof(string));
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
-
- case 126:
- len = getStackList(list, ARRAYSIZE(list));
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
- tmp2 = 0;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, list[tmp2++]);
- if (tmp2 == len)
- tmp2 = 0;
- tmp++;
- }
- dim2start++;
- }
- break;
- case 127:
- {
- int a2_dim1end = pop();
- int a2_dim1start = pop();
- int a2_dim2end = pop();
- int a2_dim2start = pop();
- int array2 = fetchScriptWord();
- int a1_dim1end = pop();
- int a1_dim1start = pop();
- int a1_dim2end = pop();
- int a1_dim2start = pop();
- if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
- error("Source and dest ranges size are mismatched");
- }
- copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
- }
- break;
- case 128:
- b = pop();
- c = pop();
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
-
- offs = (b >= c) ? 1 : -1;
- tmp2 = c;
- tmp3 = c - b + 1;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, tmp2);
- if (--tmp3 == 0) {
- tmp2 = c;
- tmp3 = c - b + 1;
- } else {
- tmp2 += offs;
- }
- tmp++;
- }
- dim2start++;
- }
- break;
- case 194:
- decodeScriptString(string);
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
- case 208: // SO_ASSIGN_INT_LIST
- b = pop();
- c = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, 0, 0, 0, b + c - 1);
- }
- while (c--) {
- writeArray(array, 0, b + c, pop());
- }
- break;
- case 212: // SO_ASSIGN_2DIM_LIST
- len = getStackList(list, ARRAYSIZE(list));
- id = readVar(array);
- if (id == 0)
- error("Must DIM a two dimensional array before assigning");
- c = pop();
- while (--len >= 0) {
- writeArray(array, c, len, list[len]);
- }
- break;
- default:
- error("o72_arrayOps: default case %d (array %d)", subOp, array);
- }
-}
-
-void ScummEngine_v72he::o72_systemOps() {
- byte string[1024];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 22: // HE80+
- clearDrawObjectQueue();
- break;
- case 26: // HE80+
- gdi.copyVirtScreenBuffers(Common::Rect(_screenWidth, _screenHeight));
- updatePalette();
- break;
- case 158:
- restart();
- break;
- case 160:
- // Confirm shutdown
- shutDown();
- break;
- case 244:
- shutDown();
- break;
- case 251:
- copyScriptString(string, sizeof(string));
- debug(0, "Start executable (%s)", string);
- break;
- case 252:
- copyScriptString(string, sizeof(string));
- debug(0, "Start game (%s)", string);
- break;
- default:
- error("o72_systemOps invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_talkActor() {
- Actor *a;
-
- int act = pop();
-
- _string[0].loadDefault();
-
- // A value of 225 can occur when examining the gold in the mine of pajama, after mining the gold.
- // This is a script bug, the script should set the subtitle color, not actor number.
- // This script bug was fixed in the updated version of pajama.
- if (act == 225) {
- _string[0].color = act;
- } else {
- _actorToPrintStrFor = act;
- if (_actorToPrintStrFor != 0xFF) {
- a = derefActor(_actorToPrintStrFor, "o72_talkActor");
- _string[0].color = a->_talkColor;
- }
- }
-
- actorTalk(_scriptPointer);
-
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-}
-
-void ScummEngine_v72he::o72_talkEgo() {
- push(VAR(VAR_EGO));
- o72_talkActor();
-}
-
-void ScummEngine_v72he::o72_dimArray() {
- int data;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 2: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 3: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 4: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 5: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 6:
- data = kDwordArray;
- break;
- case 7: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- case 204: // SO_UNDIM_ARRAY
- nukeArray(fetchScriptWord());
- return;
- default:
- error("o72_dimArray: default case %d", subOp);
- }
-
- defineArray(fetchScriptWord(), data, 0, 0, 0, pop());
-}
-
-
-void ScummEngine_v72he::o72_dim2dimArray() {
- int data, dim1end, dim2end;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 2: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 3: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 4: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 5: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 6:
- data = kDwordArray;
- break;
- case 7: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o72_dim2dimArray: default case %d", subOp);
- }
-
- dim1end = pop();
- dim2end = pop();
- defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
-}
-
-void ScummEngine_v72he::o72_traceStatus() {
- byte string[80];
-
- copyScriptString(string, sizeof(string));
- pop();
-}
-
-void ScummEngine_v72he::o72_kernelGetFunctions() {
- int args[29];
- ArrayHeader *ah;
- getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1:
- writeVar(0, 0);
- ah = defineArray(0, kByteArray, 0, 0, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
- virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
- push(readVar(0));
- break;
- default:
- error("o72_kernelGetFunctions: default case %d", args[0]);
- }
-}
-
-void ScummEngine_v72he::o72_drawWizImage() {
- WizImage wi;
- wi.flags = pop();
- wi.y1 = pop();
- wi.x1 = pop();
- wi.resNum = pop();
- wi.state = 0;
- _wiz->displayWizImage(&wi);
-}
-
-void ScummEngine_v72he::o72_debugInput() {
- byte string[255];
-
- copyScriptString(string, sizeof(string));
- int len = resStrLen(string) + 1;
-
- writeVar(0, 0);
- ArrayHeader *ah = defineArray(0, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- push(readVar(0));
- debug(1,"o72_debugInput: String %s", string);
-}
-
-void ScummEngine_v72he::o72_jumpToScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- stopObjectCode();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_openFile() {
- int mode, slot, i;
- byte filename[256];
-
- mode = pop();
- copyScriptString(filename, sizeof(filename));
-
- debug(1,"Original filename %s", filename);
-
- // There are Macintosh specific versions of HE7.2 games.
- if (_heversion >= 80 && _platform == Common::kPlatformMacintosh) {
- // Work around for filename difference in HE7 file, needs to
- // open 'Water (7)' instead of 'Water Worries (7)'.
- if (_gameId == GID_WATER && _heversion == 99 && !strcmp((char *)filename, "Water.he7")) {
- strcpy((char *)filename, "Water (7)");
- } else {
- char buf1[128];
- buf1[0] = '\0';
- generateSubstResFileName((char *)filename, buf1, sizeof(buf1));
- if (buf1[0]) {
- strcpy((char *)filename, buf1);
- }
- }
- }
-
- int r = convertFilePath(filename);
- debug(1,"Final filename to %s", filename + r);
-
- slot = -1;
- for (i = 1; i < 17; i++) {
- if (_hFileTable[i].isOpen() == false) {
- slot = i;
- break;
- }
- }
-
- if (slot != -1) {
- switch(mode) {
- case 1:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _saveFileMan->getSavePath());
- if (_hFileTable[slot].isOpen() == false)
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _gameDataPath.c_str());
- break;
- case 2:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileWriteMode, _saveFileMan->getSavePath());
- break;
- default:
- error("o72_openFile(): wrong open file mode %d", mode);
- }
-
- if (_hFileTable[slot].isOpen() == false)
- slot = -1;
-
- }
- debug(1, "o72_openFile: slot %d, mode %d", slot, mode);
- push(slot);
-}
-
-int ScummEngine_v72he::readFileToArray(int slot, int32 size) {
- if (size == 0)
- size = _hFileTable[slot].size() - _hFileTable[slot].pos();
-
- writeVar(0, 0);
- ArrayHeader *ah = defineArray(0, kByteArray, 0, 0, 0, size);
-
- if (_hFileTable[slot].isOpen())
- _hFileTable[slot].read(ah->data, size + 1);
-
- return readVar(0);
-}
-
-void ScummEngine_v72he::o72_readFile() {
- int slot, val;
- int32 size;
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 4:
- slot = pop();
- val = _hFileTable[slot].readByte();
- push(val);
- break;
- case 5:
- slot = pop();
- val = _hFileTable[slot].readUint16LE();
- push(val);
- break;
- case 6:
- slot = pop();
- val = _hFileTable[slot].readUint32LE();
- push(val);
- break;
- case 8:
- fetchScriptByte();
- size = pop();
- slot = pop();
- val = readFileToArray(slot, size);
- push(val);
- break;
- default:
- error("o72_readFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::writeFileFromArray(int slot, int32 resID) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
- int32 size = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
-
- _hFileTable[slot].write(ah->data, size);
-}
-
-void ScummEngine_v72he::o72_writeFile() {
- int32 resID = pop();
- int slot = pop();
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 4:
- _hFileTable[slot].writeByte(resID);
- break;
- case 5:
- _hFileTable[slot].writeUint16LE(resID);
- break;
- case 6:
- _hFileTable[slot].writeUint32LE(resID);
- break;
- case 8:
- fetchScriptByte();
- writeFileFromArray(slot, resID);
- break;
- default:
- error("o72_writeFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_findAllObjects() {
- int room = pop();
- int i;
-
- if (room != _currentRoom)
- error("o72_findAllObjects: current room is not %d", room);
-
- writeVar(0, 0);
- defineArray(0, kDwordArray, 0, 0, 0, _numLocalObjects);
- writeArray(0, 0, 0, _numLocalObjects);
-
- for (i = 1; i < _numLocalObjects; i++) {
- writeArray(0, 0, i, _objs[i].obj_nr);
- }
-
- push(readVar(0));
-}
-
-void ScummEngine_v72he::o72_deleteFile() {
- byte filename[256];
-
- copyScriptString(filename, sizeof(filename));
- debug(1, "stub o72_deleteFile(%s)", filename);
-}
-
-void ScummEngine_v72he::o72_rename() {
- byte oldFilename[100],newFilename[100];
-
- copyScriptString(newFilename, sizeof(newFilename));
- copyScriptString(oldFilename, sizeof(oldFilename));
-
- debug(1, "stub o72_rename(%s to %s)", oldFilename, newFilename);
-}
-
-void ScummEngine_v72he::o72_getPixel() {
- byte area;
-
- int y = pop();
- int x = pop();
- byte subOp = fetchScriptByte();
-
- VirtScreen *vs = findVirtScreen(y);
- if (vs == NULL || x > _screenWidth - 1 || x < 0) {
- push(-1);
- return;
- }
-
- switch (subOp) {
- case 9: // HE 100
- case 218:
- area = *vs->getBackPixels(x, y - vs->topline);
- break;
- case 8: // HE 100
- case 219:
- area = *vs->getPixels(x, y - vs->topline);
- break;
- default:
- error("o72_getPixel: default case %d", subOp);
- }
- push(area);
-}
-
-void ScummEngine_v72he::o72_pickVarRandom() {
- int num;
- int args[100];
- int32 dim1end;
-
- num = getStackList(args, ARRAYSIZE(args));
- int value = fetchScriptWord();
-
- if (readVar(value) == 0) {
- defineArray(value, kDwordArray, 0, 0, 0, num);
- if (num > 0) {
- int16 counter = 0;
- do {
- writeArray(value, 0, counter + 1, args[counter]);
- } while (++counter < num);
- }
-
- shuffleArray(value, 1, num);
- writeArray(value, 0, 0, 2);
- push(readArray(value, 0, 1));
- return;
- }
-
- num = readArray(value, 0, 0);
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
- dim1end = FROM_LE_32(ah->dim1end);
-
- if (dim1end < num) {
- int32 var_2 = readArray(value, 0, num - 1);
- shuffleArray(value, 1, dim1end);
- if (readArray(value, 0, 1) == var_2) {
- num = 2;
- } else {
- num = 1;
- }
- }
-
- writeArray(value, 0, 0, num + 1);
- push(readArray(value, 0, num));
-}
-
-void ScummEngine_v72he::o72_redimArray() {
- int newX, newY;
- newY = pop();
- newX = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 5:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kIntArray);
- break;
- case 4:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kByteArray);
- break;
- case 6:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kDwordArray);
- break;
- default:
- error("o72_redimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v72he::redimArray(int arrayId, int newDim2start, int newDim2end,
- int newDim1start, int newDim1end, int type) {
- int newSize, oldSize;
-
- if (readVar(arrayId) == 0)
- error("redimArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
-
- if (!ah)
- error("redimArray: Invalid array (%d) reference", readVar(arrayId));
-
- newSize = arrayDataSizes[type];
- oldSize = arrayDataSizes[FROM_LE_32(ah->type)];
-
- newSize *= (newDim1end - newDim1start + 1) * (newDim2end - newDim2start + 1);
- oldSize *= (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
-
- newSize >>= 3;
- oldSize >>= 3;
-
- if (newSize != oldSize)
- error("redimArray: array %d redim mismatch", readVar(arrayId));
-
- ah->type = TO_LE_32(type);
- ah->dim1start = TO_LE_32(newDim1start);
- ah->dim1end = TO_LE_32(newDim1end);
- ah->dim2start = TO_LE_32(newDim2start);
- ah->dim2end = TO_LE_32(newDim2end);
-}
-
-void ScummEngine_v72he::checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end) {
- if (dim1end < dim1start) {
- error("Across max %d smaller than min %d", dim1end, dim1start);
- }
- if (dim2end < dim2start) {
- error("Down max %d smaller than min %d", dim2end, dim2start);
- }
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- assert(ah);
- if (ah->dim2start > dim2start || ah->dim2end < dim2end || ah->dim1start > dim1start || ah->dim1end < dim1end) {
- error("Invalid array access (%d,%d,%d,%d) limit (%d,%d,%d,%d)", dim2start, dim2end, dim1start, dim1end, ah->dim2start, ah->dim2end, ah->dim1start, ah->dim1end);
- }
-}
-
-void ScummEngine_v72he::copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
- int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end)
-{
- byte *dst, *src;
- int dstPitch, srcPitch;
- int rowSize;
- checkArrayLimits(array1, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end);
- checkArrayLimits(array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
- int a12_num = a1_dim2end - a1_dim2start + 1;
- int a11_num = a1_dim1end - a1_dim1start + 1;
- int a22_num = a2_dim2end - a2_dim2start + 1;
- int a21_num = a2_dim1end - a2_dim1start + 1;
- if (a22_num != a12_num || a21_num != a11_num) {
- error("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
- }
-
- if (array1 != array2) {
- ArrayHeader *ah1 = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
- assert(ah1);
- ArrayHeader *ah2 = (ArrayHeader *)getResourceAddress(rtString, readVar(array2));
- assert(ah2);
- if (FROM_LE_32(ah1->type) == FROM_LE_32(ah2->type)) {
- copyArrayHelper(ah1, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah2, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
- memcpy(dst, src, rowSize);
- dst += dstPitch;
- src += srcPitch;
- }
- } else {
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start) {
- int a2dim1 = a2_dim1start;
- int a1dim1 = a1_dim1start;
- for (; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1) {
- int val = readArray(array2, a2_dim2start, a2dim1);
- writeArray(array1, a1_dim2start, a1dim1, val);
- }
- }
- }
- } else {
- if (a2_dim2start != a1_dim2start || a2_dim1start != a1_dim1start) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
- assert(ah);
- if (a2_dim2start > a1_dim2start) {
- copyArrayHelper(ah, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- } else {
- copyArrayHelper(ah, a1_dim2end, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah, a2_dim2end, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- }
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
- memcpy(dst, src, rowSize);
- dst += dstPitch;
- src += srcPitch;
- }
- }
- }
-}
-
-void ScummEngine_v72he::copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num) {
- const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
- const int offset = pitch * (idx2 - FROM_LE_32(ah->dim2start)) + idx1 - FROM_LE_32(ah->dim1start);
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- *num = len1 - idx1 + 1;
- *size = pitch;
- *data = ah->data + offset;
- break;
- case kIntArray:
- *num = (len1 - idx1) * 2 + 2;
- *size = pitch * 2;
- *data = ah->data + offset * 2;
- break;
- case kDwordArray:
- *num = (len1 - idx1) * 4 + 4;
- *size = pitch * 4;
- *data = ah->data + offset * 4;
- break;
- default:
- error("Invalid array type", FROM_LE_32(ah->type));
- }
-}
-
-void ScummEngine_v72he::o72_readINI() {
- byte option[128];
- ArrayHeader *ah;
- const char *entry;
- int len;
-
- copyScriptString(option, sizeof(option));
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- if (!strcmp((char *)option, "NoPrinting")) {
- push(1);
- } else if (!strcmp((char *)option, "TextOn")) {
- push(ConfMan.getBool("subtitles"));
- } else {
- push(ConfMan.getInt((char *)option));
- }
- break;
- case 77: // HE 100
- case 7: // string
- entry = (ConfMan.get((char *)option).c_str());
-
- writeVar(0, 0);
- len = resStrLen((const byte *)entry);
- ah = defineArray(0, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, entry, len);
-
- push(readVar(0));
- break;
- default:
- error("o72_readINI: default type %d", subOp);
- }
-
- debug(1, "o72_readINI: Option %s", option);
-}
-
-void ScummEngine_v72he::o72_writeINI() {
- int value;
- byte option[256], string[1024];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- value = pop();
- copyScriptString(option, sizeof(option));
- ConfMan.set((char *)option, value);
- debug(1, "o72_writeINI: Option %s Value %d", option, value);
- break;
- case 77: // HE 100
- case 7: // string
- copyScriptString(string, sizeof(string));
- copyScriptString(option, sizeof(option));
-
- // Filter out useless settings
- if (!strcmp((char *)option, "HETest") || !strcmp((char *)option, "Version"))
- return;
-
- // Filter out confusing subtitle setting
- if (!strcmp((char *)option, "TextOn"))
- return;
-
- // Filter out confusing path settings
- if (!strcmp((char *)option, "DownLoadPath") || !strcmp((char *)option, "GameResourcePath") || !strcmp((char *)option, "SaveGamePath"))
- return;
-
- ConfMan.set((char *)option, (char *)string);
- debug(1, "o72_writeINI: Option %s String %s", option, string);
- break;
- default:
- error("o72_writeINI: default type %d", subOp);
- }
-
- ConfMan.flushToDisk();
-}
-
-void ScummEngine_v72he::o72_getResourceSize() {
- const byte *ptr;
- int size, type;
-
- int resid = pop();
- if (_heversion == 72) {
- push(getSoundResourceSize(resid));
- return;
- }
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 13:
- push (getSoundResourceSize(resid));
- return;
- case 14:
- type = rtRoomImage;
- break;
- case 15:
- type = rtImage;
- break;
- case 16:
- type = rtCostume;
- break;
- case 17:
- type = rtScript;
- break;
- default:
- error("o80_getResourceSize: default type %d", subOp);
- }
-
- ptr = getResourceAddress(type, resid);
- assert(ptr);
- size = READ_BE_UINT32(ptr + 4) - 8;
- push(size);
-}
-
-void ScummEngine_v72he::o72_setFilePath() {
- // File related
- byte filename[255];
- copyScriptString(filename, sizeof(filename));
- debug(1,"o72_setFilePath: %s", filename);
-}
-
-void ScummEngine_v72he::o72_setWindowCaption() {
- byte name[1024];
- copyScriptString(name, sizeof(name));
- byte subOp = fetchScriptByte();
-
- debug(1,"o72_setWindowCaption: (%d) %s", subOp, name);
-}
-
-void ScummEngine_v72he::decodeParseString(int m, int n) {
- Actor *a;
- int i, colors, size;
- int args[31];
- byte name[1024];
-
- byte b = fetchScriptByte();
-
- switch (b) {
- case 65: // SO_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 66: // SO_COLOR
- _string[m].color = pop();
- break;
- case 67: // SO_CLIPPED
- _string[m].right = pop();
- break;
- case 69: // SO_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 71: // SO_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 72: // SO_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 73: // SO_SAY_VOICE
- error("decodeParseString: case 73");
- break;
- case 74: // SO_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 75: // SO_TEXTSTRING
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
- break;
- case 194:
- decodeScriptString(name, true);
- printString(m, name);
- break;
- case 0xE1:
- {
- byte *dataPtr = getResourceAddress(rtTalkie, pop());
- byte *text = findWrappedBlock(MKID('TEXT'), dataPtr, 0, 0);
- size = getResourceDataSize(text);
- memcpy(name, text, size);
- printString(m, name);
- }
- break;
- case 0xF9:
- colors = pop();
- if (colors == 1) {
- _string[m].color = pop();
- } else {
- push(colors);
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- _string[m].color = _charsetColorMap[0];
- }
- break;
- case 0xFE:
- _string[m].loadDefault();
- if (n) {
- _actorToPrintStrFor = pop();
- if (_actorToPrintStrFor != 0xFF) {
- a = derefActor(_actorToPrintStrFor, "decodeParseString");
- _string[0].color = a->_talkColor;
- }
- }
- break;
- case 0xFF:
- _string[m].saveDefault();
- break;
- default:
- error("decodeParseString: default case 0x%x", b);
- }
-}
-
-} // End of namespace Scumm