diff options
author | Max Horn | 2006-02-11 22:45:04 +0000 |
---|---|---|
committer | Max Horn | 2006-02-11 22:45:04 +0000 |
commit | 26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch) | |
tree | 26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /scumm/script_v72he.cpp | |
parent | 2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff) | |
download | scummvm-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.cpp | 2352 |
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 |