diff options
Diffstat (limited to 'script_v2.cpp')
-rw-r--r-- | script_v2.cpp | 2124 |
1 files changed, 2124 insertions, 0 deletions
diff --git a/script_v2.cpp b/script_v2.cpp new file mode 100644 index 0000000000..d27bfd2507 --- /dev/null +++ b/script_v2.cpp @@ -0,0 +1,2124 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Change Log: + * $Log$ + * Revision 1.1 2001/10/16 10:01:47 strigeus + * preliminary DOTT support + * + */ + + +#include "stdafx.h" +#include "scumm.h" + +#if defined(DOTT) + +void Scumm::setupOpcodes2() { + static const OpcodeProc opcode_list[256] = { + /* 00 */ + &Scumm::o2_pushByte, + &Scumm::o2_pushWord, + &Scumm::o2_pushByteVar, + &Scumm::o2_pushWordVar, + /* 04 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayRead, + &Scumm::o2_wordArrayRead, + /* 08 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayIndexedRead, + &Scumm::o2_wordArrayIndexedRead, + /* 0C */ + &Scumm::o2_dup, + &Scumm::o2_zero, + &Scumm::o2_eq, + &Scumm::o2_neq, + /* 10 */ + &Scumm::o2_gt, + &Scumm::o2_lt, + &Scumm::o2_le, + &Scumm::o2_ge, + /* 14 */ + &Scumm::o2_add, + &Scumm::o2_sub, + &Scumm::o2_mul, + &Scumm::o2_div, + /* 18 */ + &Scumm::o2_land, + &Scumm::o2_lor, + &Scumm::o2_kill, + &Scumm::o2_invalid, + /* 1C */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 20 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 24 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 28 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 2C */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 30 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 34 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 38 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 3C */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* 40 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_writeByteVar, + &Scumm::o2_writeWordVar, + /* 44 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayWrite, + &Scumm::o2_wordArrayWrite, + /* 48 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayIndexedWrite, + &Scumm::o2_wordArrayIndexedWrite, + /* 4C */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteVarInc, + &Scumm::o2_wordVarInc, + /* 50 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayInc, + &Scumm::o2_wordArrayInc, + /* 54 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteVarDec, + &Scumm::o2_wordVarDec, + /* 58 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_byteArrayDec, + &Scumm::o2_wordArrayDec, + /* 5C */ + &Scumm::o2_jumpTrue, + &Scumm::o2_jumpFalse, + &Scumm::o2_startScriptEx, + &Scumm::o2_startScript, + /* 60 */ + &Scumm::o2_startObject, + &Scumm::o2_setObjectState, + &Scumm::o2_setObjectXY, + &Scumm::o2_invalid, + /* 64 */ + &Scumm::o2_invalid, + &Scumm::o2_stopObjectCode, + &Scumm::o2_stopObjectCode, + &Scumm::o2_endCutscene, + /* 68 */ + &Scumm::o2_cutScene, + &Scumm::o2_stopMusic, + &Scumm::o2_freezeUnfreeze, + &Scumm::o2_cursorCommand, + /* 6C */ + &Scumm::o2_breakHere, + &Scumm::o2_ifClassOfIs, + &Scumm::o2_setClass, + &Scumm::o2_getState, + /* 70 */ + &Scumm::o2_setState, + &Scumm::o2_setOwner, + &Scumm::o2_getOwner, + &Scumm::o2_jump, + /* 74 */ + &Scumm::o2_startSound, + &Scumm::o2_stopSound, + &Scumm::o2_startMusic, + &Scumm::o2_stopObjectScript, + /* 78 */ + &Scumm::o2_panCameraTo, + &Scumm::o2_actorFollowCamera, + &Scumm::o2_setCameraAt, + &Scumm::o2_loadRoom, + /* 7C */ + &Scumm::o2_stopScript, + &Scumm::o2_walkActorToObj, + &Scumm::o2_walkActorTo, + &Scumm::o2_putActorInRoom, + /* 80 */ + &Scumm::o2_putActorAtObject, + &Scumm::o2_faceActor, + &Scumm::o2_animateActor, + &Scumm::o2_doSentence, + /* 84 */ + &Scumm::o2_pickupObject, + &Scumm::o2_loadRoomWithEgo, + &Scumm::o2_invalid, + &Scumm::o2_getRandomNumber, + /* 88 */ + &Scumm::o2_getRandomNumberRange, + &Scumm::o2_invalid, + &Scumm::o2_getActorMoving, + &Scumm::o2_getScriptRunning, + /* 8C */ + &Scumm::o2_getActorRoom, + &Scumm::o2_getObjectX, + &Scumm::o2_getObjectY, + &Scumm::o2_getObjectDir, + /* 90 */ + &Scumm::o2_getActorWalkBox, + &Scumm::o2_getActorCostume, + &Scumm::o2_findInventory, + &Scumm::o2_getInventoryCount, + /* 94 */ + &Scumm::o2_getVerbFromXY, + &Scumm::o2_beginOverride, + &Scumm::o2_endOverride, + &Scumm::o2_setObjectName, + /* 98 */ + &Scumm::o2_isSoundRunning, + &Scumm::o2_setBoxFlags, + &Scumm::o2_createBoxMatrix, + &Scumm::o2_resourceRoutines, + /* 9C */ + &Scumm::o2_roomOps, + &Scumm::o2_actorSet, + &Scumm::o2_verbOps, + &Scumm::o2_getActorFromXY, + /* A0 */ + &Scumm::o2_findObject, + &Scumm::o2_pseudoRoom, + &Scumm::o2_getActorElevation, + &Scumm::o2_getVerbEntrypoint, + /* A4 */ + &Scumm::o2_arrayOps, + &Scumm::o2_saveRestoreVerbs, + &Scumm::o2_drawBox, + &Scumm::o2_invalid, + /* A8 */ + &Scumm::o2_getActorWidth, + &Scumm::o2_wait, + &Scumm::o2_getActorScaleX, + &Scumm::o2_getActorAnimCounter1, + /* AC */ + &Scumm::o2_soundKludge, + &Scumm::o2_isAnyOf, + &Scumm::o2_quitPauseRestart, + &Scumm::o2_isActorInBox, + /* B0 */ + &Scumm::o2_delay, + &Scumm::o2_delayLonger, + &Scumm::o2_delayVeryLong, + &Scumm::o2_stopSentence, + /* B4 */ + &Scumm::o2_print_0, + &Scumm::o2_print_1, + &Scumm::o2_print_2, + &Scumm::o2_print_3, + /* B8 */ + &Scumm::o2_printActor, + &Scumm::o2_printEgo, + &Scumm::o2_talkActor, + &Scumm::o2_talkEgo, + /* BC */ + &Scumm::o2_dim, + &Scumm::o2_invalid, + &Scumm::o2_runVerbCodeQuick, + &Scumm::o2_runScriptQuick, + /* C0 */ + &Scumm::o2_dim2, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* C4 */ + &Scumm::o2_abs, + &Scumm::o2_distObjectObject, + &Scumm::o2_distObjectPt, + &Scumm::o2_distPtPt, + /* C8 */ + &Scumm::o2_invalid, + &Scumm::o2_miscOps, + &Scumm::o2_breakMaybe, + &Scumm::o2_pickOneOf, + /* CC */ + &Scumm::o2_pickOneOfDefault, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* D0 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* D4 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* D8 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* DC */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* E0 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* E4 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* E8 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* EC */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* F0 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* F4 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* F8 */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + /* FC */ + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + &Scumm::o2_invalid, + }; + + _opcodes = opcode_list; +} + +int Scumm::readArray(int array, int index, int base) { + ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); + + assert(ah); + + base += index*ah->dim1_size; + + assert(base>=0 && base < ah->dim1_size*ah->dim2_size); + + if (ah->type==4) { + return ah->data[base]; + } else { + return (int16)READ_LE_UINT16(ah->data + base*2); + } +} + +void Scumm::writeArray(int array, int index, int base, int value) { + ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); + assert(ah); + base += index*ah->dim1_size; + + assert(base>=0 && base < ah->dim1_size*ah->dim2_size); + + if (ah->type==4) { + ah->data[base] = value; + } else { + ((uint16*)ah->data)[base] = TO_LE_16(value); + } +} + +int Scumm::getStackList(int16 *args, uint maxnum) { + uint num, i; + + for (i=0; i<maxnum; i++) + args[i] = 0; + + num = pop(); + + if (num > maxnum) + error("Too many items %d in stack list, max %d", num, maxnum); + + i = num; + while (((int)--i)>=0) { + args[i] = pop(); + } + + return num; +} + +void Scumm::o2_pushByte() { + push(fetchScriptByte()); +} + +void Scumm::o2_pushWord() { + push((int16)fetchScriptWord()); +} + +void Scumm::o2_pushByteVar() { + push(readVar(fetchScriptByte())); +} + +void Scumm::o2_pushWordVar() { + push(readVar(fetchScriptWord())); +} + +void Scumm::o2_invalid() { + error("Invalid opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer); +} + +void Scumm::o2_byteArrayRead() { + int base = pop(); + push(readArray(fetchScriptByte(), 0, base)); +} + +void Scumm::o2_wordArrayRead() { + int base = pop(); + push(readArray(fetchScriptWord(), 0, base)); +} + +void Scumm::o2_byteArrayIndexedRead() { + int base = pop(); + int index = pop(); + push(readArray(fetchScriptByte(), index, base)); +} + +void Scumm::o2_wordArrayIndexedRead() { + int base = pop(); + int index = pop(); + push(readArray(fetchScriptWord(), index, base)); +} + +void Scumm::o2_dup() { + int a = pop(); + push(a); + push(a); +} + +void Scumm::o2_zero() { + push( pop() == 0 ); +} + +void Scumm::o2_eq() { + push( pop() == pop() ); +} + +void Scumm::o2_neq() { + push( pop() != pop() ); +} + +void Scumm::o2_gt() { + int a = pop(); + push( pop() > a ); +} + +void Scumm::o2_lt() { + int a = pop(); + push( pop() < a ); +} + +void Scumm::o2_le() { + int a = pop(); + push( pop() <= a ); +} + +void Scumm::o2_ge() { + int a = pop(); + push( pop() >= a ); +} + +void Scumm::o2_add() { + int a = pop(); + push( pop() + a ); +} + +void Scumm::o2_sub() { + int a = pop(); + push( pop() - a ); +} + +void Scumm::o2_mul() { + int a = pop(); + push( pop() * a ); +} + +void Scumm::o2_div() { + int a = pop(); + if (a==0) error("division by zero"); + push( pop() / a ); +} + +void Scumm::o2_land() { + int a = pop(); + push( pop() && a ); +} + +void Scumm::o2_lor() { + int a = pop(); + push( pop() || a ); +} + +void Scumm::o2_kill() { + pop(); +} + +void Scumm::o2_writeByteVar() { + writeVar(fetchScriptByte(), pop()); +} + +void Scumm::o2_writeWordVar() { + writeVar(fetchScriptWord(), pop()); +} + +void Scumm::o2_byteArrayWrite() { + int a = pop(); + writeArray(fetchScriptByte(), 0, pop(), a); +} + +void Scumm::o2_wordArrayWrite() { + int a = pop(); + writeArray(fetchScriptWord(), 0, pop(), a); +} + +void Scumm::o2_byteArrayIndexedWrite() { + int val = pop(); + int base = pop(); + writeArray(fetchScriptByte(), pop(), base, val); +} + +void Scumm::o2_wordArrayIndexedWrite() { + int val = pop(); + int base = pop(); + writeArray(fetchScriptWord(), pop(), base, val); +} + +void Scumm::o2_byteVarInc() { + int var = fetchScriptByte(); + writeVar(var,readVar(var)+1); +} + +void Scumm::o2_wordVarInc() { + int var = fetchScriptWord(); + writeVar(var,readVar(var)+1); +} + +void Scumm::o2_byteArrayInc() { + int var = fetchScriptByte(); + int base = pop(); + writeArray(var, 0, base, readArray(var, 0, base) + 1); +} + +void Scumm::o2_wordArrayInc() { + int var = fetchScriptWord(); + int base = pop(); + writeArray(var, 0, base, readArray(var, 0, base) + 1); +} + + +void Scumm::o2_byteVarDec() { + int var = fetchScriptByte(); + writeVar(var,readVar(var)-1); +} + +void Scumm::o2_wordVarDec() { + int var = fetchScriptWord(); + writeVar(var,readVar(var)-1); +} + +void Scumm::o2_byteArrayDec() { + int var = fetchScriptByte(); + int base = pop(); + writeArray(var, 0, base, readArray(var, 0, base) - 1); +} + +void Scumm::o2_wordArrayDec() { + int var = fetchScriptWord(); + int base = pop(); + writeArray(var, 0, base, readArray(var, 0, base) - 1); +} + +void Scumm::o2_jumpTrue() { + if (pop()) + o2_jump(); + else + fetchScriptWord(); +} + +void Scumm::o2_jumpFalse() { + if (!pop()) + o2_jump(); + else + fetchScriptWord(); +} + +void Scumm::o2_jump() { + _scriptPointer += (int16)fetchScriptWord(); +} + +void Scumm::o2_startScriptEx() { + int16 args[16]; + int script,flags; + + getStackList(args,sizeof(args)/sizeof(args[0])); + script = pop(); + flags = pop(); + runScript(script, flags&1, flags&2, args); +} + +void Scumm::o2_startScript() { + int16 args[16]; + int script; + getStackList(args,sizeof(args)/sizeof(args[0])); + script = pop(); + runScript(script, 0, 0, args); +} + +void Scumm::o2_startObject() { + int16 args[16]; + int script,entryp; + int flags; + getStackList(args,sizeof(args)/sizeof(args[0])); + entryp = pop(); + script = pop(); + flags = pop(); + runVerbCode(script, entryp, flags&1, flags&2, args); +} + +void Scumm::o2_setObjectState() { + int a = pop(); + if (a==0) a=1; + setObjectState(pop(), a, -1, -1); +} + +void Scumm::o2_setObjectXY() { + int y = pop(); + int x = pop(); + setObjectState(pop(), 1, x, y); +} + +void Scumm::o2_stopObjectCode() { + stopObjectCode(); +} + +void Scumm::o2_endCutscene() { + endCutscene(); +} + +void Scumm::o2_cutScene() { + int16 args[16]; + getStackList(args,sizeof(args)/sizeof(args[0])); + cutscene(args); +} + +void Scumm::o2_stopMusic() { + warning("o2_stopMusic: not implemented"); +} + +void Scumm::o2_freezeUnfreeze() { + int a = pop(); + if (a) + freezeScripts(a); + else + unfreezeScripts(); +} + +void Scumm::o2_cursorCommand() { + int a,num,i; + int16 args[16]; + + switch(fetchScriptByte()) { + case 0x90: + _cursorState = 1; + verbMouseOver(0); + break; + case 0x91: + _cursorState = 0; + verbMouseOver(0); + break; + case 0x92: + _userPut = 1; + break; + case 0x93: + _userPut = 0; + break; + case 0x94: + _cursorState++; + if (_cursorState > 1) + error("Cursor state greater than 1 in script"); + verbMouseOver(0); + break; + case 0x95: + _cursorState--; + verbMouseOver(0); + break; + case 0x96: + _userPut++; + break; + case 0x97: + _userPut--; + break; + case 0x99: + a = pop(); + setCursorImg(a, pop()); + break; + case 0x9A: + a = pop(); + setCursorHotspot2(pop(),a); + break; + case 0x9C: /* init charset */ + initCharset(pop()); + break; + case 0x9D: /* set charset colors */ + getStackList(args,sizeof(args)/sizeof(args[0])); + for (i=0; i<16; i++) + charset._colorMap[i] = _charsetData[string[1].t_charset][i] = args[i]; + break; + case 0xD6: + new_unk_1(pop()); + break; + } + + _vars[VAR_CURSORSTATE] = _cursorState; + _vars[VAR_USERPUT] = _userPut; +} + +void Scumm::o2_breakHere() { + updateScriptPtr(); + _currentScript = 0xFF; +} + +void Scumm::o2_ifClassOfIs() { + int16 args[16]; + int num,obj,cls; + bool b; + int cond = 1; + + num = getStackList(args,sizeof(args)/sizeof(args[0])); + obj = pop(); + + while (--num>=0) { + cls = args[num]; + b = getClass(obj, cls); + if (cls&0x80 && !b || !(cls&0x80) && b) + cond = 0; + } + push(cond); +} + +void Scumm::o2_setClass() { + int16 args[16]; + int num,obj,cls; + + num = getStackList(args,sizeof(args)/sizeof(args[0])); + obj = pop(); + + while (--num>=0) { + cls = args[num]; + if (cls==0) + _classData[num] = 0; + else if (cls&0x80) + putClass(obj, cls, 1); + else + putClass(obj, cls, 0); + } +} + +void Scumm::o2_getState() { + push(getState(pop())); +} + +void Scumm::o2_setState() { + int state = pop(); + int obj = pop(); + + putState(obj, state); + removeObjectFromRoom(obj); + if (_BgNeedsRedraw) + clearDrawObjectQueue(); +} + +void Scumm::o2_setOwner() { + int owner = pop(); + int obj = pop(); + + setOwnerOf(obj, owner); +} + +void Scumm::o2_getOwner() { + push(getOwner(pop())); +} + +void Scumm::o2_startSound() { + addSoundToQueue(pop()); +} + +void Scumm::o2_stopSound() { + unkSoundProc1(pop()); +} + +void Scumm::o2_startMusic() { + addSoundToQueue(pop()); +} + +void Scumm::o2_stopObjectScript() { + stopObjectScript(pop()); +} + +void Scumm::o2_panCameraTo() { + panCameraTo(pop()); +} + +void Scumm::o2_actorFollowCamera() { + actorFollowCamera(pop()); +} + +void Scumm::o2_setCameraAt() { + setCameraAtEx(pop()); +} + +void Scumm::o2_loadRoom() { + int room = pop(); + debug(1,"Loading room %d", room); + startScene(room, 0, 0); + _fullRedraw = 1; +} + +void Scumm::o2_stopScript() { + int script = pop(); + if (script==0) + stopObjectCode(); + else + stopScriptNr(script); +} + +void Scumm::o2_walkActorToObj() { + int obj,dist; + Actor *a, *a2; + int x; + + dist = pop(); + obj = pop(); + a = derefActorSafe(pop(), "o2_walkActorToObj"); + + if (obj >= 17) { + if (whereIsObject(obj)==-1) + return; + getObjectXYPos(obj); + startWalkActor(a, _xPos, _yPos, _dir); + } else { + a2 = derefActorSafe(obj, "o2_walkActorToObj(2)"); + if (a2->room != _currentRoom || + a->room != _currentRoom) + return; + if (dist==0) { + dist = a2->scalex * a2->width / 0xFF; + dist += dist>>1; + } + x = a2->x; + if (x < a->x) + x += dist; + else + x -= dist; + startWalkActor(a, x, a2->y, 0xFF); + } +} + +void Scumm::o2_walkActorTo() { + int x,y; + y = pop(); + x = pop(); + startWalkActor(derefActorSafe(pop(), "o2_walkActorTo"), x, y, 0xFF); +} + +void Scumm::o2_putActorInRoom() { + int room, x, y; + Actor *a; + + room = pop(); + y = pop(); + x = pop(); + a = derefActorSafe(pop(), "o2_putActorInRoom"); + if (room==0xFF) { + room = a->room; + } else { + if (a->visible && _currentRoom != room && _vars[VAR_TALK_ACTOR]==a->number) { + clearMsgQueue(); + } + if (room != 0) + a->room = room; + } + putActor(a, x, y, room); +} + +void Scumm::o2_putActorAtObject() { + int room,obj,x,y; + Actor *a; + + room = pop(); + obj = pop(); + + a = derefActorSafe(pop(), "o2_putActorAtObject"); + if (whereIsObject(obj)!=-1) { + getObjectXYPos(obj); + x = _xPos; + y = _yPos; + } else { + x = 160; + y = 120; + } + if (room == 0xFF) + room = a->room; + putActor(a, x, y, room); +} + +void Scumm::o2_faceActor() { + int act,obj; + obj = pop(); + act = pop(); + faceActorToObj(act, obj); +} + +void Scumm::o2_animateActor() { + int anim = pop(); + int act = pop(); + animateActor(act, anim); +} + +void Scumm::o2_doSentence() { + int a,b,c; + SentenceTab *st; + + a = pop(); + pop(); //dummy pop + b = pop(); + c = pop(); + + st = &sentence[++_sentenceIndex]; + + st->unk5 = c; + st->unk4 = b; + st->unk3 = a; + + if (!(st->unk3&0xFF00)) + st->unk2 = 0; + else + st->unk2 = 1; + + st->unk = 0; +} + +void Scumm::o2_pickupObject() { + int obj, room; + + room = pop(); + obj = pop(); + + if (room==0) + room = _roomResource; + addObjectToInventory(obj, room); + putOwner(obj, _vars[VAR_UNK_ACTOR]); + putClass(obj, 32, 1); + putState(obj, 1); + removeObjectFromRoom(obj); + clearDrawObjectQueue(); + runHook(obj); /* Difference */ +} + +void Scumm::o2_loadRoomWithEgo() { + Actor *a; + int room,obj,x,y; + + y = pop(); + x = pop(); + room = pop(); + obj = pop(); + + a = derefActorSafe(_vars[VAR_UNK_ACTOR], "o_loadRoomWithEgo"); + + putActor(a, 0, 0, room); + dseg_3A76 = 0; + _vars[VAR_WALKTO_OBJ] = obj; + startScene(a->room, a, obj); + _vars[VAR_WALKTO_OBJ] = 0; + + /* startScene maybe modifies VAR_UNK_ACTOR, i hope not */ + camera._destPos = camera._curPos = a->x; + setCameraFollows(a); + _fullRedraw=1; + if (x != -1) { + startWalkActor(a, x, y, 0xFF); + } +} + +void Scumm::o2_getRandomNumber() { + int rnd; + rnd = getRandomNumber(pop()+1); + _vars[VAR_RANDOM_NR] = rnd; + push(rnd); +} + +void Scumm::o2_getRandomNumberRange() { + int max = pop(); + int min = pop(); + int rnd = getRandomNumber(max-min+1) + min; + _vars[VAR_RANDOM_NR] = rnd; + push(rnd); +} + +void Scumm::o2_getActorMoving() { + push(derefActorSafe(pop(),"o2_getActorMoving")->moving); +} + +void Scumm::o2_getScriptRunning() { + push(getScriptRunning(pop())); +} + +void Scumm::o2_getActorRoom() { + push(derefActorSafe(pop(),"o2_getActorRoom")->room); +} + +void Scumm::o2_getObjectX() { + push(getObjX(pop())); +} + +void Scumm::o2_getObjectY() { + push(getObjY(pop())); +} + +void Scumm::o2_getObjectDir() { + push(getObjDir(pop())); +} + +void Scumm::o2_getActorWalkBox() { + push(derefActorSafe(pop(),"o2_getActorWalkBox")->walkbox); +} + +void Scumm::o2_getActorCostume() { + push(derefActorSafe(pop(),"o2_getActorCostume")->costume); +} + +void Scumm::o2_findInventory() { + int index = pop(); + int owner = pop(); + push(findInventory(owner,index)); +} + +void Scumm::o2_getInventoryCount() { + push(getInventoryCount(pop())); +} + +void Scumm::o2_getVerbFromXY() { + int y = pop(); + int x = pop(); + int over = checkMouseOver(x,y); + if (over) + over = _verbs[over].verbid; + push(over); +} + +void Scumm::o2_beginOverride() { + beginOverride(); +} + +void Scumm::o2_endOverride() { + endOverride(); +} + +void Scumm::o2_setObjectName() { + int obj = pop(); + int i; + + if (obj <= _vars[VAR_NUM_ACTOR]) + error("Can't set actor %d name with new-name-of", obj); + + if (!getObjectAddress(obj)) + error("Can't set name of object %d", obj); + + for (i=1; i<50; i++) { + if (_newNames[i] == obj) { + nukeResource(16, i); + _newNames[i] = 0; + break; + } + } + + for (i=1; i<50; i++) { + if (_newNames[i] == 0) { + loadPtrToResource(16, i, NULL); + _newNames[i] = obj; + runHook(0); + return; + } + } + + error("New name of %d overflows name table (max = %d)", obj, 50); +} + +void Scumm::o2_isSoundRunning() { + int snd = pop(); + if (snd) + snd = unkSoundProc23(snd); + push(snd); +} + +void Scumm::o2_setBoxFlags() { + int16 table[65]; + int num,value; + + value = pop(); + num = getStackList(table,sizeof(table)/sizeof(table[0])); + + while (--num>=0) { + setBoxFlags(table[num], value); + } +} + +void Scumm::o2_createBoxMatrix() { + createBoxMatrix(); +} + +void Scumm::o2_resourceRoutines() { + int res; + + switch(fetchScriptByte()) { + case 100: /* load script */ + res = pop(); + ensureResourceLoaded(2, res); + break; + case 101: /* load sound */ + res = pop(); + ensureResourceLoaded(4, res); + break; + case 102: /* load costume */ + res = pop(); + ensureResourceLoaded(3, res); + break; + case 103: /* load room */ + res = pop(); + ensureResourceLoaded(1, res); + break; + case 104: /* nuke script */ + res = pop(); + setResourceFlags(2, res, 0x7F); + break; + case 105: /* nuke sound */ + res = pop(); + setResourceFlags(4, res, 0x7F); + break; + case 106: /* nuke costume */ + res = pop(); + setResourceFlags(3, res, 0x7F); + break; + case 107: /* nuke room */ + res = pop(); + setResourceFlags(1, res, 0x7F); + break; + case 108: /* lock script */ + res = pop(); + if (res >= _numGlobalScripts) + break; + lock(2,res); + break; + case 109:/* lock sound */ + res = pop(); + lock(4,res); + break; + case 110:/* lock costume */ + res = pop(); + lock(3,res); + break; + case 111:/* lock room */ + res = pop(); + if (res > 0x7F) + res = _resourceMapper[res&0x7F]; + lock(1,res); + break; + case 112:/* unlock script */ + res = pop(); + if (res >= _numGlobalScripts) + break; + unlock(2,res); + break; + case 113:/* unlock sound */ + res = pop(); + unlock(4,res); + break; + case 114:/* unlock costume */ + res = pop(); + unlock(3,res); + break; + case 115:/* unlock room */ + res = pop(); + if (res > 0x7F) + res = _resourceMapper[res&0x7F]; + unlock(1,res); + break; + case 116:/* clear heap */ + /* this is actually a scumm message */ + error("clear heap not working yet"); + break; + case 117:/* load charset */ + res = pop(); + loadCharset(res); + break; + case 118:/* nuke charset */ + warning("popping extra argument in nukeCharset"); + res = pop(); + nukeCharset(res); + break; + case 119:/* ? */ + res = pop(); + unkResProc(pop(), res); + break; + default: + error("o2_resourceRoutines: default case"); + } +} + +void Scumm::o2_roomOps() { + int a,b,c,d,e; + + switch(fetchScriptByte()) { + case 172: /* room scroll */ + b = pop(); + a = pop(); + if (a < 160) a=160; + if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3); + if (b < 160) b=160; + if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3); + _vars[VAR_CAMERA_MIN] = a; + _vars[VAR_CAMERA_MAX] = b; + break; + + case 174: /* set screen */ + b = pop(); + a = pop(); + initScreens(0,a,320,b); + break; + + case 175: /* set palette color */ + d = pop(); + c = pop(); + b = pop(); + a = pop(); + setPalColor(d, a, b, c); + break; + + case 176: /* shake on */ + setShake(1); + break; + + case 177: /* shake off */ + setShake(0); + break; + + case 179: + c = pop(); + b = pop(); + a = pop(); + unkRoomFunc2(b,c,a,a,a); + break; + + case 180: + _saveLoadData = pop(); + _saveLoadFlag = pop(); + warning("o2_roomops:180: partially unimplemented"); + break; + + case 181: + a = pop(); + if (a) { + _switchRoomEffect = (byte)(a); + _switchRoomEffect2 = (byte)(a>>8); + } else { + screenEffect(_newEffect); + } + break; + + case 182: + e = pop(); + d = pop(); + c = pop(); + b = pop(); + a = pop(); + unkRoomFunc2(d, e, a, b, c); + break; + + case 183: + e = pop(); + d = pop(); + c = pop(); + b = pop(); + a = pop(); + unkRoomFunc3(d, e, a, b, c); + break; + + case 184: + error("save string not implemented"); + break; + + case 185: + error("load string not implemented"); + break; + + case 186: /* palmanip? */ + d = pop(); + c = pop(); + b = pop(); + a = pop(); + unkRoomFunc4(a, b, c, d, 1); + break; + + case 187: /* color cycle delay */ + b = pop(); + a = pop(); + if (b!=0) + _colorCycleDelays[a] = 0x4000 / (b*0x4C); + else + _colorCycleDelays[a] = 0; + break; + + case 213: /* set palette */ + setPalette(pop()); + break; + + default: + error("o2_roomOps: default case"); + } +} + +void Scumm::o2_actorSet() { + Actor *a; + int i,j,k; + int16 args[8]; + byte b; + + b = fetchScriptByte(); + if (b==197) { + _curActor = pop(); + return; + } + + a = derefActorSafe(_curActor, "o2_actorSet"); + + switch(b) { + case 76: /* actor-costume */ + setActorCostume(a, pop()); + break; + case 77: /* actor-speed */ + j = pop(); + i = pop(); + setActorWalkSpeed(a, i, j); + break; + case 78: /* actor-sound */ + k = getStackList(args, sizeof(args)/sizeof(args[0])); + for (i=0; i<k; i++) + a->sound[i] = args[i]; + break; + case 79: /* actor-walkframe */ + a->walkFrame = pop(); + break; + case 80: /* actor-talkframe */ + a->talkFrame2 = pop(); + a->talkFrame1 = pop(); + break; + case 81: /* actor-standframe */ + a->standFrame = pop(); + break; + case 82: + pop(); + pop(); + pop(); + break; + case 83: + initActor(a, 0); + break; + case 84: /* actor-elevation */ + a->elevation = pop(); + a->needRedraw = true; + a->needBgReset = true; + break; + case 85: /* actor-defaultanims */ + a->initFrame = 1; + a->walkFrame = 2; + a->standFrame = 3; + a->talkFrame1 = 4; + a->talkFrame2 = 5; + break; + case 86: /* actor-palette */ + j = pop(); + i = pop(); + checkRange(31, 0, i, "Illegal palet slot %d"); + a->palette[i] = j; + a->needRedraw = true; + break; + case 87: /* actor-talkcolor */ + a->talkColor = pop(); + break; + case 88: /* actor-name */ + loadPtrToResource(9, a->number, NULL); + break; + case 89: /* actor-initframe */ + a->initFrame = pop(); + break; + case 91: + a->width = pop(); + break; + case 92: + a->scalex = a->scaley = pop(); + a->needRedraw = true; + a->needBgReset = true; + break; + case 93: + a->neverZClip = 0; + break; + case 94: + a->neverZClip = pop(); + break; + case 95: + a->ignoreBoxes = 1; + a->neverZClip = 0; +FixRooms:; + if (a->room==_currentRoom) + putActor(a, a->x, a->y, a->room); + break; + case 96: + a->ignoreBoxes = 0; + a->neverZClip = 0; + goto FixRooms; + case 97: + a->animSpeed = pop(); + a->animProgress = 0; + break; + case 98: + a->data8 = pop(); + break; + case 99: + a->new_1 = pop(); + a->new_2 = pop(); + break; + case 215: + a->new_3 = 1; + break; + case 216: + a->new_3 = 0; + break; + case 217: + initActor(a, 2); + break; + default: + error("o2_actorset: default case"); + } +} + +void Scumm::o2_verbOps() { + int slot,a,b; + VerbSlot *vs; + byte *ptr, op; + + op = fetchScriptByte(); + if(op==196) { + _curVerb = pop(); + _curVerbSlot = getVerbSlot(_curVerb, 0); + checkRange(_maxVerbs-1,0,_curVerbSlot,"Illegal new verb slot %d"); + return; + } + vs = &_verbs[_curVerbSlot]; + slot = _curVerbSlot; + switch(op) { + case 124: /* load img */ + a = pop(); + if (_curVerbSlot) { + setVerbObject(_roomResource,a,slot); + vs->type=1; + } + break; + case 125: + loadPtrToResource(8, slot, NULL); + vs->type = 0; + vs->imgindex = 0; + break; + case 126: + vs->color = pop(); + break; + case 127: + vs->hicolor = pop(); + break; + case 128: + vs->y = pop(); + vs->x = pop(); + break; + case 129: + vs->curmode = 1; + break; + case 130: + vs->curmode = 0; + break; + case 131: + killVerb(slot); + break; + case 132: + slot = getVerbSlot(_curVerb, 0); + if (slot==0) { + for (slot=1; slot<_maxVerbs; slot++) { + if(_verbs[slot].verbid==0) + break; + } + if (slot==_maxVerbs) + error("Too many verbs"); + _curVerbSlot = slot; + } + vs = &_verbs[slot]; + vs->verbid = _curVerb; + vs->color = 2; + vs->hicolor = 0; + vs->dimcolor = 8; + vs->type = 0; + vs->charset_nr = string[0].t_charset; + vs->curmode = 0; + vs->saveid = 0; + vs->key = 0; + vs->center = 0; + vs->imgindex = 0; + break; + case 133: + vs->dimcolor = pop(); + break; + case 134: + vs->curmode = 2; + break; + case 135: + vs->key = pop(); + break; + case 136: + vs->center = 1; + break; + case 137: + a = pop(); + if (a==0) { + ptr = (byte*)""; + } else { + ptr = getResourceAddress(7, a); + } + loadPtrToResource(8, slot, ptr); + vs->type = 0; + vs->imgindex = 0; + break; + case 139: + b = pop(); + a = pop(); + if (slot && a != vs->imgindex) { + setVerbObject(b, a, slot); + vs->type = 1; + vs->imgindex = a; + } + break; + case 140: + vs->bkcolor = pop(); + break; + case 255: + drawVerb(slot, 0); + verbMouseOver(0); + break; + default: + error("o2_verbops: default case"); + } +} + +void Scumm::o2_getActorFromXY() { + int y = pop(); + int x = pop(); + push(getActorFromPos(x,y)); +} + +void Scumm::o2_findObject() { + int y = pop(); + int x = pop(); + int r = findObject(x,y); + push(r); +} + +void Scumm::o2_pseudoRoom() { + int16 list[100]; + int num,a,value; + + num = getStackList(list,sizeof(list)/sizeof(list[0])); + value = pop(); + + while (--num>=0) { + a = list[num]; + if (a > 0x7F) + _resourceMapper[a&0x7F] = value; + } +} + +void Scumm::o2_getActorElevation() { + push(derefActorSafe(pop(),"o2_getActorElevation")->elevation); +} + +void Scumm::o2_getVerbEntrypoint() { + int e = pop(); + int v = pop(); + push(getVerbEntrypoint(v,e)); +} + +void Scumm::o2_arrayOps() { + int a,b,c,d,num; + int16 list[128]; + + switch(fetchScriptByte()) { + case 205: + a = fetchScriptWord(); + pop(); + arrayop_1(a, NULL); + break; + case 208: + a = fetchScriptWord(); + b = pop(); + c = pop(); + d = readVar(a); + if (d==0) { + defineArray(a, 5, 0, b+c); + } + while (c--) { + writeArray(a, 0, b+c, pop()); + } + break; + case 212: + a = fetchScriptWord(); + b = pop(); + num = getStackList(list,sizeof(list)/sizeof(list[0])); + d = readVar(a); + if (d==0) + error("Must DIM a two dimensional array before assigning"); + c = pop(); + while (--num>=0) { + writeArray(a, c, b+num, list[num]); + } + break; + default: + error("o2_arrayOps: default case"); + } +} + +void Scumm::o2_saveRestoreVerbs() { + int a,b,c; + int slot,slot2; + + c = pop(); + b = pop(); + a = pop(); + + switch(fetchScriptByte()) { + case 141: + while (a<=b) { + slot = getVerbSlot(a,0); + if (slot && _verbs[slot].saveid==0) { + _verbs[slot].saveid = c; + drawVerb(slot, 0); + verbMouseOver(0); + } + a++; + } + break; + case 142: + while (a<=b) { + slot = getVerbSlot(a, c); + if (slot) { + slot2 = getVerbSlot(a,0); + if (slot2) + killVerb(slot2); + slot = getVerbSlot(a,c); + _verbs[slot].saveid = 0; + drawVerb(slot, 0); + verbMouseOver(0); + } + a++; + } + break; + case 143: + while (a<=b) { + slot = getVerbSlot(a,c); + if (slot) + killVerb(slot); + a++; + } + break; + default: + error("o2_saveRestoreVerbs: default case"); + } +} + +void Scumm::o2_drawBox() { + int x,y,x2,y2,color; + color = pop(); + y2 = pop(); + x2 = pop(); + y = pop(); + x = pop(); + drawBox(x, y, x2, y2, color); +} + +void Scumm::o2_getActorWidth() { + push(derefActorSafe(pop(),"o2_getActorWidth")->width); +} + +void Scumm::o2_wait() { + byte oldaddr; + + switch(fetchScriptByte()) { + case 168: + if (derefActorSafe(pop(), "o2_wait")->moving) { + _scriptPointer += (int16)fetchScriptWord(); + o2_breakHere(); + } else { + fetchScriptWord(); + } + return; + case 169: + if (_vars[VAR_HAVE_MSG]) + break; + return; + case 170: + if (camera._curPos>>3 != camera._destPos>>3) + break; + return; + case 171: + if (_sentenceIndex!=0xFF) { + if (sentence[_sentenceIndex].unk && + !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) + return; + break; + } + if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) + return; + break; + default: + error("o2_wait: default case"); + } + + _scriptPointer -= 2; + o2_breakHere(); +} + +void Scumm::o2_getActorScaleX() { + push(derefActorSafe(pop(),"o2_getActorScale")->scalex); +} + +void Scumm::o2_getActorAnimCounter1() { + push(derefActorSafe(pop(),"o2_getActorAnimCounter")->cost.animCounter1); +} + +void Scumm::o2_soundKludge() { + int16 list[8]; + getStackList(list,sizeof(list)/sizeof(list[0])); + soundKludge(list); +} + +void Scumm::o2_isAnyOf() { + int16 list[100]; + int num; + int16 val; + + num = getStackList(list,sizeof(list)/sizeof(list[0])); + val = pop(); + + while (--num>=0) { + if (list[num] == val) { + push(1); + return; + } + } + push(0); + return; +} + +void Scumm::o2_quitPauseRestart() { + switch(fetchScriptByte()) { + case 158: + pauseGame(0); + break; + case 160: + shutDown(0); + break; + default: + error("o2_quitPauseRestart: invalid case"); + } +} + +void Scumm::o2_isActorInBox() { + int box = pop(); + Actor *a = derefActorSafe(pop(), "o2_isActorInBox"); + push(checkXYInBoxBounds(box, a->x, a->y)); +} + +void Scumm::o2_delay() { + uint32 delay = (uint16)pop(); + vm.slot[_currentScript].delay = delay; + vm.slot[_currentScript].status = 1; + o2_breakHere(); +} + +void Scumm::o2_delayLonger() { + uint32 delay = (uint16)pop() * 60; + vm.slot[_currentScript].delay = delay; + vm.slot[_currentScript].status = 1; + o2_breakHere(); +} + +void Scumm::o2_delayVeryLong() { + uint32 delay = (uint16)pop() * 3600; + vm.slot[_currentScript].delay = delay; + vm.slot[_currentScript].status = 1; + o2_breakHere(); +} + +void Scumm::o2_stopSentence() { + _sentenceIndex = 0xFF; + stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]); + clearClickedStatus(); +} + +void Scumm::o2_print_0() { + _actorToPrintStrFor = 0xFF; + decodeParseString2(0,0); +} + +void Scumm::o2_print_1() { + decodeParseString2(1,0); +} + +void Scumm::o2_print_2() { + decodeParseString2(2,0); +} + +void Scumm::o2_print_3() { + decodeParseString2(3,0); +} + +void Scumm::o2_printActor() { + decodeParseString2(0,1); +} + +void Scumm::o2_printEgo() { + push(_vars[VAR_UNK_ACTOR]); + decodeParseString2(0,1); +} + +void Scumm::o2_talkActor() { + _actorToPrintStrFor = pop(); + _messagePtr = _scriptPointer; + setStringVars(0); + actorTalk(); + _scriptPointer = _messagePtr; +} + +void Scumm::o2_talkEgo() { + _actorToPrintStrFor = _vars[VAR_UNK_ACTOR]; + _messagePtr = _scriptPointer; + setStringVars(0); + actorTalk(); + _scriptPointer = _messagePtr; +} + +void Scumm::o2_dim() { + byte b; + int data; + + switch(fetchScriptByte()) { + case 199: + data = 5; + break; + case 200: + data = 1; + break; + case 201: + data = 2; + break; + case 202: + data = 3; + break; + case 203: + data = 4; + break; + case 204: + nukeArray(fetchScriptWord()); + return; + default: + error("o2_dim: default case"); + } + + defineArray(fetchScriptWord(), data, 0, pop()); +} + +void Scumm::o2_runVerbCodeQuick() { + int16 args[16]; + int script,entryp; + getStackList(args,sizeof(args)/sizeof(args[0])); + entryp = pop(); + script = pop(); + runVerbCode(script, entryp, 0, 1, args); +} + +void Scumm::o2_runScriptQuick() { + int16 args[16]; + int script; + getStackList(args,sizeof(args)/sizeof(args[0])); + script = pop(); + runScript(script, 0, 1, args); +} + +void Scumm::o2_dim2() { + int a,b,data; + switch(fetchScriptByte()) { + case 199: + data = 5; + break; + case 200: + data = 1; + break; + case 201: + data = 2; + break; + case 202: + data = 3; + break; + case 203: + data = 4; + break; + default: + error("o2_dim2: default case"); + } + + b = pop(); + a = pop(); + defineArray(fetchScriptWord(), data, a, b); +} + +void Scumm::o2_abs() { + push(abs(pop())); +} + + +void Scumm::o2_distObjectObject() { + int a,b; + b = pop(); + a = pop(); + push(getDistanceBetween(true, a, 0, true, b, 0)); +} + +void Scumm::o2_distObjectPt() { + int a,b,c; + c = pop(); + b = pop(); + a = pop(); + push(getDistanceBetween(true, a, 0, false, b, c)); +} + +void Scumm::o2_distPtPt() { + int a,b,c,d; + d = pop(); + c = pop(); + b = pop(); + a = pop(); + push(getDistanceBetween(false, a, b, false, c, d)); +} + +void Scumm::o2_dummy_stacklist() { + error("opcode o2_dummy_stacklist invalid"); +} + +void Scumm::o2_miscOps() { + int16 args[30]; + int i; + + getStackList(args,sizeof(args)/sizeof(args[0])); + switch(args[0]) { + case 3: + warning("o2_miscOps: nothing in 3"); + break; + case 4: + unkMiscOp4(args[1], args[2], args[3], args[4]); + break; + case 5: + unkVirtScreen4(args[1]); + break; + case 6: + _fullRedraw = 1; + redrawBGAreas(); + for (i=0; i<13; i++) + derefActor(i)->needRedraw = true; + processActors(); + screenEffect(args[1]); + break; + case 8: + startManiac(); + break; + case 9: + unkMiscOp9(); + break; + } +} + +void Scumm::o2_breakMaybe() { + ScriptSlot *ss = &vm.slot[_currentScript]; + if (ss->newfield == 0) { + ss->newfield = pop(); + } else { + ss->newfield--; + } + if (ss->newfield) { + _scriptPointer--; + o2_breakHere(); + } +} + +void Scumm::o2_pickOneOf() { + int16 args[100]; + int i,num; + + num = getStackList(args,sizeof(args)/sizeof(args[0])); + i = pop(); + if (i<0 || i>=num) + error("o2_pickOneOf: out of range"); + push(args[i]); +} + +void Scumm::o2_pickOneOfDefault() { + int16 args[100]; + int i,num,def; + + def = pop(); + num = getStackList(args,sizeof(args)/sizeof(args[0])); + i = pop(); + if (i<0 || i>=num) + i = def; + else + i = args[i]; + push(i); +} + +void Scumm::decodeParseString2(int m, int n) { + byte b; + + b = fetchScriptByte(); + + switch(b) { + case 65: + string[m].ypos = pop(); + string[m].xpos = pop(); + string[m].overhead = 0; + break; + case 66: + string[m].color = pop(); + break; + case 67: + string[m].right = pop(); + break; + case 69: + string[m].center = 1; + string[m].overhead = 0; + break; + case 71: + string[m].center = 0; + string[m].overhead = 0; + break; + case 72: + string[m].overhead = 1; + string[m].new_3 = 0; + break; + case 73: + error("decodeParseString2: case 73"); + break; + case 74: + string[m].new_3 = 1; + break; + case 75: + _messagePtr = _scriptPointer; + switch(m) { + case 0: actorTalk(); break; + case 1: drawString(1); break; + case 2: unkMessage1(); break; + case 3: unkMessage2(); break; + } + _scriptPointer = _messagePtr; + return; + + case 0xFE: + setStringVars(m); + if (n) + _actorToPrintStrFor = pop(); + return; + case 0xFF: + string[m].t_xpos = string[m].xpos; + string[m].t_ypos = string[m].ypos; + string[m].t_center = string[m].center; + string[m].t_overhead = string[m].overhead; + string[m].t_new3 = string[m].new_3; + string[m].t_right = string[m].right; + string[m].t_color = string[m].color; + string[m].t_charset = string[m].charset; + return; + default: + error("decodeParseString: default case"); + } +} + +#endif
\ No newline at end of file |