aboutsummaryrefslogtreecommitdiff
path: root/scumm/script_v2.cpp
diff options
context:
space:
mode:
authorMax Horn2002-08-21 16:07:07 +0000
committerMax Horn2002-08-21 16:07:07 +0000
commitce46866403fdcc479cf9d67e4d430409b15dadc3 (patch)
tree75ebfaa1ed13f549959d76d3ce101c3e66f5451b /scumm/script_v2.cpp
parent662256f25dbe43abf67077a804e225738765f009 (diff)
downloadscummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.tar.gz
scummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.tar.bz2
scummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.zip
Initial revision
svn-id: r4785
Diffstat (limited to 'scumm/script_v2.cpp')
-rw-r--r--scumm/script_v2.cpp3141
1 files changed, 3141 insertions, 0 deletions
diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp
new file mode 100644
index 0000000000..5f85f746c2
--- /dev/null
+++ b/scumm/script_v2.cpp
@@ -0,0 +1,3141 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001/2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+
+#include "stdafx.h"
+#include "scumm.h"
+#include "actor.h"
+#include "smush.h"
+
+#include "sound/mididrv.h"
+#include "scumm/imuse.h"
+
+void Scumm::setupOpcodes2()
+{
+ static const OpcodeProc opcode_list[256] = {
+ /* 00 */
+ &Scumm::o6_pushByte,
+ &Scumm::o6_pushWord,
+ &Scumm::o6_pushByteVar,
+ &Scumm::o6_pushWordVar,
+ /* 04 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayRead,
+ &Scumm::o6_wordArrayRead,
+ /* 08 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayIndexedRead,
+ &Scumm::o6_wordArrayIndexedRead,
+ /* 0C */
+ &Scumm::o6_dup,
+ &Scumm::o6_zero,
+ &Scumm::o6_eq,
+ &Scumm::o6_neq,
+ /* 10 */
+ &Scumm::o6_gt,
+ &Scumm::o6_lt,
+ &Scumm::o6_le,
+ &Scumm::o6_ge,
+ /* 14 */
+ &Scumm::o6_add,
+ &Scumm::o6_sub,
+ &Scumm::o6_mul,
+ &Scumm::o6_div,
+ /* 18 */
+ &Scumm::o6_land,
+ &Scumm::o6_lor,
+ &Scumm::o6_kill,
+ &Scumm::o6_invalid,
+ /* 1C */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 20 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 24 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 28 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 2C */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 30 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 34 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 38 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 3C */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* 40 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_writeByteVar,
+ &Scumm::o6_writeWordVar,
+ /* 44 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayWrite,
+ &Scumm::o6_wordArrayWrite,
+ /* 48 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayIndexedWrite,
+ &Scumm::o6_wordArrayIndexedWrite,
+ /* 4C */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteVarInc,
+ &Scumm::o6_wordVarInc,
+ /* 50 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayInc,
+ &Scumm::o6_wordArrayInc,
+ /* 54 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteVarDec,
+ &Scumm::o6_wordVarDec,
+ /* 58 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_byteArrayDec,
+ &Scumm::o6_wordArrayDec,
+ /* 5C */
+ &Scumm::o6_jumpTrue,
+ &Scumm::o6_jumpFalse,
+ &Scumm::o6_startScriptEx,
+ &Scumm::o6_startScript,
+ /* 60 */
+ &Scumm::o6_startObject,
+ &Scumm::o6_setObjectState,
+ &Scumm::o6_setObjectXY,
+ &Scumm::o6_drawBlastObject,
+ /* 64 */
+ &Scumm::o6_setBlastObjectWindow,
+ &Scumm::o6_stopObjectCode,
+ &Scumm::o6_stopObjectCode,
+ &Scumm::o6_endCutscene,
+ /* 68 */
+ &Scumm::o6_cutScene,
+ &Scumm::o6_stopMusic,
+ &Scumm::o6_freezeUnfreeze,
+ &Scumm::o6_cursorCommand,
+ /* 6C */
+ &Scumm::o6_breakHere,
+ &Scumm::o6_ifClassOfIs,
+ &Scumm::o6_setClass,
+ &Scumm::o6_getState,
+ /* 70 */
+ &Scumm::o6_setState,
+ &Scumm::o6_setOwner,
+ &Scumm::o6_getOwner,
+ &Scumm::o6_jump,
+ /* 74 */
+ &Scumm::o6_startSound,
+ &Scumm::o6_stopSound,
+ &Scumm::o6_startMusic,
+ &Scumm::o6_stopObjectScript,
+ /* 78 */
+ &Scumm::o6_panCameraTo,
+ &Scumm::o6_actorFollowCamera,
+ &Scumm::o6_setCameraAt,
+ &Scumm::o6_loadRoom,
+ /* 7C */
+ &Scumm::o6_stopScript,
+ &Scumm::o6_walkActorToObj,
+ &Scumm::o6_walkActorTo,
+ &Scumm::o6_putActorInRoom,
+ /* 80 */
+ &Scumm::o6_putActorAtObject,
+ &Scumm::o6_faceActor,
+ &Scumm::o6_animateActor,
+ &Scumm::o6_doSentence,
+ /* 84 */
+ &Scumm::o6_pickupObject,
+ &Scumm::o6_loadRoomWithEgo,
+ &Scumm::o6_invalid,
+ &Scumm::o6_getRandomNumber,
+ /* 88 */
+ &Scumm::o6_getRandomNumberRange,
+ &Scumm::o6_invalid,
+ &Scumm::o6_getActorMoving,
+ &Scumm::o6_getScriptRunning,
+ /* 8C */
+ &Scumm::o6_getActorRoom,
+ &Scumm::o6_getObjectX,
+ &Scumm::o6_getObjectY,
+ &Scumm::o6_getObjectOldDir,
+ /* 90 */
+ &Scumm::o6_getActorWalkBox,
+ &Scumm::o6_getActorCostume,
+ &Scumm::o6_findInventory,
+ &Scumm::o6_getInventoryCount,
+ /* 94 */
+ &Scumm::o6_getVerbFromXY,
+ &Scumm::o6_beginOverride,
+ &Scumm::o6_endOverride,
+ &Scumm::o6_setObjectName,
+ /* 98 */
+ &Scumm::o6_isSoundRunning,
+ &Scumm::o6_setBoxFlags,
+ &Scumm::o6_createBoxMatrix,
+ &Scumm::o6_resourceRoutines,
+ /* 9C */
+ &Scumm::o6_roomOps,
+ &Scumm::o6_actorSet,
+ &Scumm::o6_verbOps,
+ &Scumm::o6_getActorFromXY,
+ /* A0 */
+ &Scumm::o6_findObject,
+ &Scumm::o6_pseudoRoom,
+ &Scumm::o6_getActorElevation,
+ &Scumm::o6_getVerbEntrypoint,
+ /* A4 */
+ &Scumm::o6_arrayOps,
+ &Scumm::o6_saveRestoreVerbs,
+ &Scumm::o6_drawBox,
+ &Scumm::o6_invalid,
+ /* A8 */
+ &Scumm::o6_getActorWidth,
+ &Scumm::o6_wait,
+ &Scumm::o6_getActorScaleX,
+ &Scumm::o6_getActorAnimCounter1,
+ /* AC */
+ &Scumm::o6_soundKludge,
+ &Scumm::o6_isAnyOf,
+ &Scumm::o6_quitPauseRestart,
+ &Scumm::o6_isActorInBox,
+ /* B0 */
+ &Scumm::o6_delay,
+ &Scumm::o6_delayLonger,
+ &Scumm::o6_delayVeryLong,
+ &Scumm::o6_stopSentence,
+ /* B4 */
+ &Scumm::o6_print_0,
+ &Scumm::o6_print_1,
+ &Scumm::o6_print_2,
+ &Scumm::o6_print_3,
+ /* B8 */
+ &Scumm::o6_printActor,
+ &Scumm::o6_printEgo,
+ &Scumm::o6_talkActor,
+ &Scumm::o6_talkEgo,
+ /* BC */
+ &Scumm::o6_dim,
+ &Scumm::o5_dummy,
+ &Scumm::o6_runVerbCodeQuick,
+ &Scumm::o6_runScriptQuick,
+ /* C0 */
+ &Scumm::o6_dim2,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* C4 */
+ &Scumm::o6_abs,
+ &Scumm::o6_distObjectObject,
+ &Scumm::o6_distObjectPt,
+ &Scumm::o6_distPtPt,
+ /* C8 */
+ &Scumm::o6_kernelFunction,
+ &Scumm::o6_miscOps,
+ &Scumm::o6_breakMaybe,
+ &Scumm::o6_pickOneOf,
+ /* CC */
+ &Scumm::o6_pickOneOfDefault,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* D0 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_getAnimateVariable,
+ &Scumm::o6_invalid,
+ /* D4 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_jumpToScript,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* D8 */
+ &Scumm::o6_isRoomScriptRunning,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* DC */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* E0 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* E4 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* E8 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* EC */
+ &Scumm::o6_getActorPriority,
+ &Scumm::o6_getObjectNewDir,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* F0 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* F4 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* F8 */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ /* FC */
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ &Scumm::o6_invalid,
+ };
+
+ static const char *opcode_lookup[] = {
+ /* 00 */
+ "o6_pushByte",
+ "o6_pushWord",
+ "o6_pushByteVar",
+ "o6_pushWordVar",
+ /* 04 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayRead",
+ "o6_wordArrayRead",
+ /* 08 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayIndexedRead",
+ "o6_wordArrayIndexedRead",
+ /* 0C */
+ "o6_dup",
+ "o6_zero",
+ "o6_eq",
+ "o6_neq",
+ /* 10 */
+ "o6_gt",
+ "o6_lt",
+ "o6_le",
+ "o6_ge",
+ /* 14 */
+ "o6_add",
+ "o6_sub",
+ "o6_mul",
+ "o6_div",
+ /* 18 */
+ "o6_land",
+ "o6_lor",
+ "o6_kill",
+ "o6_invalid",
+ /* 1C */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 20 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 24 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 28 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 2C */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 30 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 34 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 38 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 3C */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* 40 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_writeByteVar",
+ "o6_writeWordVar",
+ /* 44 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayWrite",
+ "o6_wordArrayWrite",
+ /* 48 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayIndexedWrite",
+ "o6_wordArrayIndexedWrite",
+ /* 4C */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteVarInc",
+ "o6_wordVarInc",
+ /* 50 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayInc",
+ "o6_wordArrayInc",
+ /* 54 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteVarDec",
+ "o6_wordVarDec",
+ /* 58 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_byteArrayDec",
+ "o6_wordArrayDec",
+ /* 5C */
+ "o6_jumpTrue",
+ "o6_jumpFalse",
+ "o6_startScriptEx",
+ "o6_startScript",
+ /* 60 */
+ "o6_startObject",
+ "o6_setObjectState",
+ "o6_setObjectXY",
+ "o6_drawBlastObject",
+ /* 64 */
+ "o6_invalid",
+ "o6_stopObjectCode",
+ "o6_stopObjectCode",
+ "o6_endCutscene",
+ /* 68 */
+ "o6_cutScene",
+ "o6_stopMusic",
+ "o6_freezeUnfreeze",
+ "o6_cursorCommand",
+ /* 6C */
+ "o6_breakHere",
+ "o6_ifClassOfIs",
+ "o6_setClass",
+ "o6_getState",
+ /* 70 */
+ "o6_setState",
+ "o6_setOwner",
+ "o6_getOwner",
+ "o6_jump",
+ /* 74 */
+ "o6_startSound",
+ "o6_stopSound",
+ "o6_startMusic",
+ "o6_stopObjectScript",
+ /* 78 */
+ "o6_panCameraTo",
+ "o6_actorFollowCamera",
+ "o6_setCameraAt",
+ "o6_loadRoom",
+ /* 7C */
+ "o6_stopScript",
+ "o6_walkActorToObj",
+ "o6_walkActorTo",
+ "o6_putActorInRoom",
+ /* 80 */
+ "o6_putActorAtObject",
+ "o6_faceActor",
+ "o6_animateActor",
+ "o6_doSentence",
+ /* 84 */
+ "o6_pickupObject",
+ "o6_loadRoomWithEgo",
+ "o6_invalid",
+ "o6_getRandomNumber",
+ /* 88 */
+ "o6_getRandomNumberRange",
+ "o6_invalid",
+ "o6_getActorMoving",
+ "o6_getScriptRunning",
+ /* 8C */
+ "o6_getActorRoom",
+ "o6_getObjectX",
+ "o6_getObjectY",
+ "o6_getObjectOldDir",
+ /* 90 */
+ "o6_getActorWalkBox",
+ "o6_getActorCostume",
+ "o6_findInventory",
+ "o6_getInventoryCount",
+ /* 94 */
+ "o6_getVerbFromXY",
+ "o6_beginOverride",
+ "o6_endOverride",
+ "o6_setObjectName",
+ /* 98 */
+ "o6_isSoundRunning",
+ "o6_setBoxFlags",
+ "o6_createBoxMatrix",
+ "o6_resourceRoutines",
+ /* 9C */
+ "o6_roomOps",
+ "o6_actorSet",
+ "o6_verbOps",
+ "o6_getActorFromXY",
+ /* A0 */
+ "o6_findObject",
+ "o6_pseudoRoom",
+ "o6_getActorElevation",
+ "o6_getVerbEntrypoint",
+ /* A4 */
+ "o6_arrayOps",
+ "o6_saveRestoreVerbs",
+ "o6_drawBox",
+ "o6_invalid",
+ /* A8 */
+ "o6_getActorWidth",
+ "o6_wait",
+ "o6_getActorScaleX",
+ "o6_getActorAnimCounter1",
+ /* AC */
+ "o6_soundKludge",
+ "o6_isAnyOf",
+ "o6_quitPauseRestart",
+ "o6_isActorInBox",
+ /* B0 */
+ "o6_delay",
+ "o6_delayLonger",
+ "o6_delayVeryLong",
+ "o6_stopSentence",
+ /* B4 */
+ "o6_print_0",
+ "o6_print_1",
+ "o6_print_2",
+ "o6_print_3",
+ /* B8 */
+ "o6_printActor",
+ "o6_printEgo",
+ "o6_talkActor",
+ "o6_talkEgo",
+ /* BC */
+ "o6_dim",
+ "o6_invalid",
+ "o6_runVerbCodeQuick",
+ "o6_runScriptQuick",
+ /* C0 */
+ "o6_dim2",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* C4 */
+ "o6_abs",
+ "o6_distObjectObject",
+ "o6_distObjectPt",
+ "o6_distPtPt",
+ /* C8 */
+ "o6_kernelFunction",
+ "o6_miscOps",
+ "o6_breakMaybe",
+ "o6_pickOneOf",
+ /* CC */
+ "o6_pickOneOfDefault",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* D0 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_getAnimateVariable",
+ "o6_invalid",
+ /* D4 */
+ "o6_invalid",
+ "o6_jumpToScript",
+ "o6_invalid",
+ "o6_invalid",
+ /* D8 */
+ "o6_isRoomScriptRunning",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* DC */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* E0 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* E4 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* E8 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* EC */
+ "o6_invalid",
+ "o6_getObjectNewDir",
+ "o6_invalid",
+ "o6_invalid",
+ /* F0 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* F4 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* F8 */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ /* FC */
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid",
+ "o6_invalid"
+ };
+
+ _opcodes = opcode_list;
+ _opcodes_lookup = opcode_lookup;
+}
+void Scumm::o6_setBlastObjectWindow()
+{ // Set BOMP processing window
+ int a, b, c, d;
+
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+
+ warning("o6_bompWindow(%d, %d, %d, %d)", a, b, c, d);
+ // sub_274EF(a, b, c, d);
+}
+
+int Scumm::popRoomAndObj(int *room)
+{
+ int obj;
+
+ if (_features & GF_HAS_ROOMTABLE) {
+ obj = pop();
+ *room = getObjectRoom(obj);
+ } else {
+ *room = pop();
+ obj = pop();
+ }
+
+ return obj;
+}
+
+
+int Scumm::readArray(int array, int idx, int base)
+{
+ ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+
+ if (ah == NULL) {
+ error("readArray: invalid array %d (%d)", array, readVar(array));
+ }
+
+ base += idx * 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 idx, int base, int value)
+{
+ ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
+ assert(ah);
+ base += idx * 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::o6_pushByte()
+{
+ push(fetchScriptByte());
+}
+
+void Scumm::o6_pushWord()
+{
+ push((int16)fetchScriptWord());
+}
+
+void Scumm::o6_pushByteVar()
+{
+ push(readVar(fetchScriptByte()));
+}
+
+void Scumm::o6_pushWordVar()
+{
+ push(readVar(fetchScriptWord()));
+}
+
+void Scumm::o6_invalid()
+{
+ error("Invalid opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer);
+}
+
+void Scumm::o6_byteArrayRead()
+{
+ int base = pop();
+ push(readArray(fetchScriptByte(), 0, base));
+}
+
+void Scumm::o6_wordArrayRead()
+{
+ int base = pop();
+ push(readArray(fetchScriptWord(), 0, base));
+}
+
+void Scumm::o6_byteArrayIndexedRead()
+{
+ int base = pop();
+ int idx = pop();
+ push(readArray(fetchScriptByte(), idx, base));
+}
+
+void Scumm::o6_wordArrayIndexedRead()
+{
+ int base = pop();
+ int idx = pop();
+ push(readArray(fetchScriptWord(), idx, base));
+}
+
+void Scumm::o6_dup()
+{
+ int a = pop();
+ push(a);
+ push(a);
+}
+
+void Scumm::o6_zero()
+{
+ push(pop() == 0);
+}
+
+void Scumm::o6_eq()
+{
+ push(pop() == pop());
+}
+
+void Scumm::o6_neq()
+{
+ push(pop() != pop());
+}
+
+void Scumm::o6_gt()
+{
+ int a = pop();
+ push(pop() > a);
+}
+
+void Scumm::o6_lt()
+{
+ int a = pop();
+ push(pop() < a);
+}
+
+void Scumm::o6_le()
+{
+ int a = pop();
+ push(pop() <= a);
+}
+
+void Scumm::o6_ge()
+{
+ int a = pop();
+ push(pop() >= a);
+}
+
+void Scumm::o6_add()
+{
+ int a = pop();
+ push(pop() + a);
+}
+
+void Scumm::o6_sub()
+{
+ int a = pop();
+ push(pop() - a);
+}
+
+void Scumm::o6_mul()
+{
+ int a = pop();
+ push(pop() * a);
+}
+
+void Scumm::o6_div()
+{
+ int a = pop();
+ if (a == 0)
+ error("division by zero");
+ push(pop() / a);
+}
+
+void Scumm::o6_land()
+{
+ int a = pop();
+ push(pop() && a);
+}
+
+void Scumm::o6_lor()
+{
+ int a = pop();
+ push(pop() || a);
+}
+
+void Scumm::o6_kill()
+{
+ pop();
+}
+
+void Scumm::o6_writeByteVar()
+{
+ writeVar(fetchScriptByte(), pop());
+}
+
+void Scumm::o6_writeWordVar()
+{
+ writeVar(fetchScriptWord(), pop());
+}
+
+void Scumm::o6_byteArrayWrite()
+{
+ int a = pop();
+ writeArray(fetchScriptByte(), 0, pop(), a);
+}
+
+void Scumm::o6_wordArrayWrite()
+{
+ int a = pop();
+ writeArray(fetchScriptWord(), 0, pop(), a);
+}
+
+void Scumm::o6_byteArrayIndexedWrite()
+{
+ int val = pop();
+ int base = pop();
+ writeArray(fetchScriptByte(), pop(), base, val);
+}
+
+void Scumm::o6_wordArrayIndexedWrite()
+{
+ int val = pop();
+ int base = pop();
+ writeArray(fetchScriptWord(), pop(), base, val);
+}
+
+void Scumm::o6_byteVarInc()
+{
+ int var = fetchScriptByte();
+ writeVar(var, readVar(var) + 1);
+}
+
+void Scumm::o6_wordVarInc()
+{
+ int var = fetchScriptWord();
+ writeVar(var, readVar(var) + 1);
+}
+
+void Scumm::o6_byteArrayInc()
+{
+ int var = fetchScriptByte();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) + 1);
+}
+
+void Scumm::o6_wordArrayInc()
+{
+ int var = fetchScriptWord();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) + 1);
+}
+
+
+void Scumm::o6_byteVarDec()
+{
+ int var = fetchScriptByte();
+ writeVar(var, readVar(var) - 1);
+}
+
+void Scumm::o6_wordVarDec()
+{
+ int var = fetchScriptWord();
+ writeVar(var, readVar(var) - 1);
+}
+
+void Scumm::o6_byteArrayDec()
+{
+ int var = fetchScriptByte();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) - 1);
+}
+
+void Scumm::o6_wordArrayDec()
+{
+ int var = fetchScriptWord();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) - 1);
+}
+
+void Scumm::o6_jumpTrue()
+{
+ if (pop())
+ o6_jump();
+ else
+ fetchScriptWord();
+}
+
+void Scumm::o6_jumpFalse()
+{
+ if (!pop())
+ o6_jump();
+ else
+ fetchScriptWord();
+}
+
+void Scumm::o6_jump()
+{
+ _scriptPointer += (int16)fetchScriptWord();
+}
+
+void Scumm::o6_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::o6_jumpToScript()
+{
+ int16 args[16];
+ int script, flags;
+
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+ script = pop();
+ flags = pop();
+ o6_stopObjectCode();
+ runScript(script, flags & 1, flags & 2, args);
+}
+
+void Scumm::o6_startScript()
+{
+ int16 args[16];
+ int script;
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+ script = pop();
+ runScript(script, 0, 0, args);
+}
+
+void Scumm::o6_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::o6_setObjectState()
+{
+ int a = pop();
+ int b = pop();
+ if (a == 0)
+ a = 1;
+// debug(1, "setObjectState(%d,%d)", a, b);
+
+ setObjectState(b, a, -1, -1);
+}
+
+void Scumm::o6_setObjectXY()
+{
+ int y = pop();
+ int x = pop();
+ int obj = pop();
+// debug(1, "setObjectXY(%d,%d,%d)", obj, x, y);
+ setObjectState(obj, 1, x, y);
+}
+
+void Scumm::o6_stopObjectCode()
+{
+ stopObjectCode();
+}
+
+void Scumm::o6_endCutscene()
+{
+ endCutscene();
+}
+
+void Scumm::o6_cutScene()
+{
+ int16 args[16];
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+ cutscene(args);
+}
+
+void Scumm::o6_stopMusic()
+{
+ _sound->stopAllSounds();
+}
+
+void Scumm::o6_freezeUnfreeze()
+{
+ int a = pop();
+ if (a)
+ freezeScripts(a);
+ else
+ unfreezeScripts();
+}
+
+void Scumm::o6_cursorCommand()
+{
+ int a, 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:{
+ int room, obj = popRoomAndObj(&room);
+ setCursorImg(obj, room, 1);
+ 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] = (unsigned char)args[i];
+ break;
+ case 0xD6:
+ makeCursorColorTransparent(pop());
+ break;
+ default:
+ error("o6_cursorCommand: default case");
+ }
+
+ _vars[VAR_CURSORSTATE] = _cursorState;
+ _vars[VAR_USERPUT] = _userPut;
+}
+
+void Scumm::o6_breakHere()
+{
+ updateScriptPtr();
+ _currentScript = 0xFF;
+}
+
+void Scumm::o6_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::o6_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::o6_getState()
+{
+ push(getState(pop()));
+}
+
+void Scumm::o6_setState()
+{
+ int state = pop();
+ int obj = pop();
+
+// debug(1, "setState(%d,%d)", obj, state);
+
+ putState(obj, state);
+ removeObjectFromRoom(obj);
+ if (_BgNeedsRedraw)
+ clearDrawObjectQueue();
+}
+
+void Scumm::o6_setOwner()
+{
+ int owner = pop();
+ int obj = pop();
+
+ setOwnerOf(obj, owner);
+}
+
+void Scumm::o6_getOwner()
+{
+ push(getOwner(pop()));
+}
+
+void Scumm::o6_startSound()
+{
+ _sound->addSoundToQueue(pop());
+}
+
+void Scumm::o6_stopSound()
+{
+ _sound->stopSound(pop());
+}
+
+void Scumm::o6_startMusic()
+{
+ _sound->addSoundToQueue(pop());
+}
+
+void Scumm::o6_stopObjectScript()
+{
+ stopObjectScript(pop());
+}
+
+void Scumm::o6_panCameraTo()
+{
+ if (_features & GF_AFTER_V7) {
+ int y = pop();
+ int x = pop();
+ panCameraTo(x, y);
+ } else {
+ panCameraTo(pop(), 0);
+ }
+}
+
+void Scumm::o6_actorFollowCamera()
+{
+ if (_features & GF_AFTER_V7)
+ setCameraFollows(derefActorSafe(pop(), "actorFollowCamera"));
+ else
+ actorFollowCamera(pop());
+
+}
+
+void Scumm::o6_setCameraAt()
+{
+ if (_features & GF_AFTER_V7) {
+ int x, y;
+
+ camera._follows = 0;
+
+ y = pop();
+ x = pop();
+
+ setCameraAt(x, y);
+ } else {
+ setCameraAtEx(pop());
+ }
+}
+
+void Scumm::o6_loadRoom()
+{
+ int room;
+ /* Begin: Autosave
+ _saveLoadSlot = 0;
+ sprintf(_saveLoadName, "Autosave", _saveLoadSlot);
+ _saveLoadFlag = 1;
+ _saveLoadCompatible = false;
+ End: Autosave */
+
+ room = pop();
+ startScene(room, 0, 0);
+ _fullRedraw = 1;
+}
+
+void Scumm::o6_stopScript()
+{
+ int script = pop();
+ if (script == 0)
+ stopObjectCode();
+ else
+ stopScriptNr(script);
+}
+
+void Scumm::o6_walkActorToObj()
+{
+ int obj, dist;
+ Actor *a, *a2;
+ int x;
+
+ dist = pop();
+ obj = pop();
+ a = derefActorSafe(pop(), "o6_walkActorToObj");
+ if (!a)
+ return;
+
+ if (obj >= NUM_ACTORS) {
+ if (whereIsObject(obj) == WIO_NOT_FOUND)
+ return;
+ int x, y, dir;
+ getObjectXYPos(obj, x, y, dir);
+ a->startWalkActor(x, y, dir);
+ } else {
+ a2 = derefActorSafe(obj, "o6_walkActorToObj(2)");
+ if (!a2)
+ return;
+ if (!a->isInCurrentRoom() || !a2->isInCurrentRoom())
+ 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;
+ a->startWalkActor(x, a2->y, -1);
+ }
+}
+
+void Scumm::o6_walkActorTo()
+{
+ int x, y;
+ y = pop();
+ x = pop();
+ derefActorSafe(pop(), "o6_walkActorTo")->startWalkActor(x, y, -1);
+}
+
+void Scumm::o6_putActorInRoom()
+{
+ int room, x, y;
+ Actor *a;
+
+ room = pop();
+ y = pop();
+ x = pop();
+ a = derefActorSafe(pop(), "o6_putActorInRoom");
+ if (!a)
+ return;
+
+ 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;
+ }
+ a->putActor(x, y, room);
+}
+
+
+void Scumm::o6_putActorAtObject()
+{
+ int room, obj, x, y;
+ Actor *a;
+
+ obj = popRoomAndObj(&room);
+
+ a = derefActorSafe(pop(), "o6_putActorAtObject");
+ if (whereIsObject(obj) != WIO_NOT_FOUND) {
+ getObjectXYPos(obj, x, y);
+ } else {
+ x = 160;
+ y = 120;
+ }
+ if (room == 0xFF)
+ room = a->room;
+ a->putActor(x, y, room);
+}
+
+void Scumm::o6_faceActor()
+{
+ int act, obj;
+ obj = pop();
+ act = pop();
+ faceActorToObj(act, obj);
+}
+
+void Scumm::o6_animateActor()
+{
+ int anim = pop();
+ int act = pop();
+
+ Actor *a = derefActorSafe(act, "o6_animateActor");
+ if (!a)
+ return;
+
+ a->animateActor(anim);
+}
+
+void Scumm::o6_doSentence()
+{
+ int a, b, c;
+
+ a = pop();
+ pop(); //dummy pop
+ b = pop();
+ c = pop();
+
+ doSentence(c, b, a);
+}
+
+void Scumm::o6_pickupObject()
+{
+ int obj, room;
+ int i;
+
+ obj = popRoomAndObj(&room);
+ if (room == 0)
+ room = _roomResource;
+
+ for (i = 1; i < _maxInventoryItems; i++) {
+ if (_inventory[i] == (uint16)obj) {
+ putOwner(obj, _vars[VAR_EGO]);
+ runHook(obj);
+ return;
+ }
+ }
+
+ addObjectToInventory(obj, room);
+ putOwner(obj, _vars[VAR_EGO]);
+ putClass(obj, 32, 1);
+ putState(obj, 1);
+ removeObjectFromRoom(obj);
+ clearDrawObjectQueue();
+ runHook(obj); /* Difference */
+}
+
+void Scumm::o6_loadRoomWithEgo()
+{
+ Actor *a;
+ int obj, room, x, y;
+
+ y = pop();
+ x = pop();
+
+ obj = popRoomAndObj(&room);
+
+ a = derefActorSafe(_vars[VAR_EGO], "o6_loadRoomWithEgo");
+
+ a->putActor(0, 0, room);
+ _egoPositioned = false;
+
+ _vars[VAR_WALKTO_OBJ] = obj;
+ startScene(a->room, a, obj);
+ _vars[VAR_WALKTO_OBJ] = 0;
+
+ /* startScene maybe modifies VAR_EGO, i hope not */
+
+ if (!(_features & GF_AFTER_V7)) {
+ setCameraAt(a->x, a->y);
+ setCameraFollows(a);
+ }
+
+ _fullRedraw = 1;
+
+ if (x != -1) {
+ a->startWalkActor(x, y, -1);
+ }
+}
+
+void Scumm::o6_getRandomNumber()
+{
+ int rnd;
+ rnd = getRandomNumber(pop());
+ _vars[VAR_V6_RANDOM_NR] = rnd;
+ push(rnd);
+}
+
+void Scumm::o6_getRandomNumberRange()
+{
+ int max = pop();
+ int min = pop();
+ int rnd = getRandomNumberRng(min, max);
+ _vars[VAR_V6_RANDOM_NR] = rnd;
+ push(rnd);
+}
+
+void Scumm::o6_getActorMoving()
+{
+ push(derefActorSafe(pop(), "o6_getActorMoving")->moving);
+}
+
+void Scumm::o6_getScriptRunning()
+{
+ push(isScriptRunning(pop()));
+}
+
+void Scumm::o6_isRoomScriptRunning()
+{
+ push(isRoomScriptRunning(pop()));
+}
+
+void Scumm::o6_getActorRoom()
+{
+ push(derefActorSafe(pop(), "o6_getActorRoom")->room);
+}
+
+void Scumm::o6_getObjectX()
+{
+ push(getObjX(pop()));
+}
+
+void Scumm::o6_getObjectY()
+{
+ push(getObjY(pop()));
+}
+
+void Scumm::o6_getObjectOldDir()
+{
+ push(getObjOldDir(pop()));
+}
+
+void Scumm::o6_getObjectNewDir()
+{
+ push(getObjNewDir(pop()));
+}
+
+void Scumm::o6_getActorWalkBox()
+{
+ Actor *a = derefActorSafe(pop(), "o6_getActorWalkBox");
+ push(a->ignoreBoxes ? 0 : a->walkbox);
+}
+
+void Scumm::o6_getActorCostume()
+{
+ push(derefActorSafe(pop(), "o6_getActorCostume")->costume);
+}
+
+void Scumm::o6_findInventory()
+{
+ int idx = pop();
+ int owner = pop();
+ push(findInventory(owner, idx));
+}
+
+void Scumm::o6_getInventoryCount()
+{
+ push(getInventoryCount(pop()));
+}
+
+void Scumm::o6_getVerbFromXY()
+{
+ int y = pop();
+ int x = pop();
+ int over = checkMouseOver(x, y);
+ if (over)
+ over = _verbs[over].verbid;
+ push(over);
+}
+
+void Scumm::o6_beginOverride()
+{
+ beginOverride();
+}
+
+void Scumm::o6_endOverride()
+{
+ endOverride();
+}
+
+void Scumm::o6_setObjectName()
+{
+ int obj = pop();
+ int i;
+
+ if (obj < NUM_ACTORS)
+ error("Can't set actor %d name with new-name-of", obj);
+
+ if (!(_features & GF_AFTER_V7) && !getOBCDFromObject(obj))
+ error("Can't set name of object %d", obj);
+
+ for (i = 1; i < 50; i++) {
+ if (_newNames[i] == obj) {
+ nukeResource(rtObjectName, i);
+ _newNames[i] = 0;
+ break;
+ }
+ }
+
+ for (i = 1; i < 50; i++) {
+ if (_newNames[i] == 0) {
+ loadPtrToResource(rtObjectName, i, NULL);
+ _newNames[i] = obj;
+ runHook(0);
+ return;
+ }
+ }
+
+ error("New name of %d overflows name table (max = %d)", obj, 50);
+}
+
+void Scumm::o6_isSoundRunning()
+{
+ int snd = pop();
+
+ // FIXME: This fixes wak-a-rat until we correctly implement
+ // sam and max iMUSE
+ if (_gameId == GID_SAMNMAX && _currentRoom == 18 && snd == 23) {
+ _sound->stopSound(snd);
+ push(0);
+ return;
+ }
+
+ if (snd)
+ snd = _sound->isSoundRunning(snd);
+
+ push(snd);
+}
+
+void Scumm::o6_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::o6_createBoxMatrix()
+{
+ createBoxMatrix();
+}
+
+void Scumm::o6_resourceRoutines()
+{
+ int resid;
+
+ switch (fetchScriptByte()) {
+ case 100: /* load script */
+ resid = pop();
+ if (_features & GF_AFTER_V7)
+ if (resid >= _numGlobalScripts)
+ break;
+ ensureResourceLoaded(rtScript, resid);
+ break;
+ case 101: /* load sound */
+ resid = pop();
+ ensureResourceLoaded(rtSound, resid);
+ break;
+ case 102: /* load costume */
+ resid = pop();
+ ensureResourceLoaded(rtCostume, resid);
+ break;
+ case 103: /* load room */
+ resid = pop();
+ ensureResourceLoaded(rtRoom, resid);
+ break;
+ case 104: /* nuke script */
+ resid = pop();
+ if (_features & GF_AFTER_V7)
+ if (resid >= _numGlobalScripts)
+ break;
+ setResourceCounter(rtScript, resid, 0x7F);
+ debug(5, "nuke script %d", resid);
+ break;
+ case 105: /* nuke sound */
+ resid = pop();
+ setResourceCounter(rtSound, resid, 0x7F);
+ break;
+ case 106: /* nuke costume */
+ resid = pop();
+ setResourceCounter(rtCostume, resid, 0x7F);
+ break;
+ case 107: /* nuke room */
+ resid = pop();
+ setResourceCounter(rtRoom, resid, 0x7F);
+ break;
+ case 108: /* lock script */
+ resid = pop();
+ if (resid >= _numGlobalScripts)
+ break;
+ lock(rtScript, resid);
+ break;
+ case 109: /* lock sound */
+ resid = pop();
+ lock(rtSound, resid);
+ break;
+ case 110: /* lock costume */
+ resid = pop();
+ lock(rtCostume, resid);
+ break;
+ case 111: /* lock room */
+ resid = pop();
+ if (resid > 0x7F)
+ resid = _resourceMapper[resid & 0x7F];
+ lock(rtRoom, resid);
+ break;
+ case 112: /* unlock script */
+ resid = pop();
+ if (resid >= _numGlobalScripts)
+ break;
+ unlock(rtScript, resid);
+ break;
+ case 113: /* unlock sound */
+ resid = pop();
+ unlock(rtSound, resid);
+ break;
+ case 114: /* unlock costume */
+ resid = pop();
+ unlock(rtCostume, resid);
+ break;
+ case 115: /* unlock room */
+ resid = pop();
+ if (resid > 0x7F)
+ resid = _resourceMapper[resid & 0x7F];
+ unlock(rtRoom, resid);
+ break;
+ case 116: /* clear heap */
+ /* this is actually a scumm message */
+ error("clear heap not working yet");
+ break;
+ case 117: /* load charset */
+ resid = pop();
+ loadCharset(resid);
+ break;
+ case 118: /* nuke charset */
+ resid = pop();
+ nukeCharset(resid);
+ break;
+ case 119:{ /* load fl object */
+ int room, obj = popRoomAndObj(&room);
+ loadFlObject(obj, room);
+ break;
+ }
+ default:
+ error("o6_resourceRoutines: default case");
+ }
+}
+
+void Scumm::o6_roomOps()
+{
+ int a, b, c, d, e;
+
+ switch (fetchScriptByte()) {
+ case 172: /* room scroll */
+ b = pop();
+ a = pop();
+ if (a < 160)
+ a = 160;
+ if (b < 160)
+ b = 160;
+ if (a > _scrWidth - 160)
+ a = _scrWidth - 160;
+ if (b > _scrWidth - 160)
+ b = _scrWidth - 160;
+ _vars[VAR_CAMERA_MIN_X] = a;
+ _vars[VAR_CAMERA_MAX_X] = 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();
+ darkenPalette(b, c, a, a, a);
+ break;
+
+ case 180:
+ _saveLoadCompatible = true;
+ _saveLoadSlot = pop();
+ _saveLoadFlag = pop();
+ warning("o6_roomops:180: partially unimplemented");
+ break;
+
+ case 181:
+ a = pop();
+ if (a) {
+ _switchRoomEffect = (byte)(a);
+ _switchRoomEffect2 = (byte)(a >> 8);
+ } else {
+ fadeIn(_newEffect);
+ }
+ break;
+
+ case 182:
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ darkenPalette(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();
+ palManipulate(a, b, c, d, 1);
+ break;
+
+ case 187: /* color cycle delay */
+ b = pop();
+ a = pop();
+ checkRange(16, 1, a, "o6_roomOps: 187: color cycle out of range (%d)");
+ _colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
+ break;
+
+ case 213: /* set palette */
+ // One case where this is used is to turn off Sam & Max film
+ // noir mode. Unfortunately it only restores color to the
+ // palette, it doesn't take palette manipulation (darkening,
+ // etc.) into account. So, for instance, if you turn on film
+ // noir mode in Sam & Max's office, turn off the light and turn
+ // off film noir mode, the room will no longer look dark.
+ //
+ // This bug is present in the original interpreter, so it may
+ // not be worth the trouble fixing it.
+ setPalette(pop());
+ break;
+
+ default:
+ error("o6_roomOps: default case");
+ }
+}
+
+void Scumm::o6_actorSet()
+{
+ Actor *a;
+ int i, j, k;
+ int16 args[8];
+ byte b;
+
+ b = fetchScriptByte();
+ if (b == 197) {
+ _curActor = pop();
+ return;
+ }
+
+ a = derefActorSafe(_curActor, "o6_actorSet");
+ if (!a)
+ return;
+
+ switch (b) {
+ case 76: /* actor-costume */
+ a->setActorCostume(pop());
+ break;
+ case 77: /* actor-speed */
+ j = pop();
+ i = pop();
+ a->setActorWalkSpeed(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:
+ a->initActor(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(rtActorName, 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->forceClip = 0;
+ break;
+ case 225:
+ case 94:
+ a->forceClip = pop();
+ break;
+ case 95:
+ a->ignoreBoxes = 1;
+ if (_features & GF_AFTER_V7) // yazoo: I don't know if it's supposed to be 100 in other games too...
+ a->forceClip = 100;
+ else
+ a->forceClip = 0;
+ FixRooms:;
+ if (a->isInCurrentRoom())
+ a->putActor(a->x, a->y, a->room);
+ break;
+ case 96:
+ a->ignoreBoxes = 0;
+ if (_features & GF_AFTER_V7) // yazoo: I don't know if it's supposed to be 100 in other games too...
+ a->forceClip = 100;
+ else
+ a->forceClip = 0;
+ goto FixRooms;
+ case 97:
+ a->animSpeed = pop();
+ a->animProgress = 0;
+ break;
+ case 98:
+ a->shadow_mode = pop();
+ break;
+ case 99:
+ a->new_1 = pop();
+ a->new_2 = pop();
+ break;
+ case 198: /* set anim variable */
+ i = pop(); /* value */
+ a->setAnimVar(pop(), i);
+ break;
+ case 215:
+ a->new_3 = 1;
+ break;
+ case 216:
+ a->new_3 = 0;
+ break;
+ case 217:
+ a->initActor(2);
+ break;
+ case 227: /* actor_layer */
+ a->layer = pop();
+ break;
+ case 228: /* walk script */
+ a->walk_script = pop();
+ break;
+ case 235: /* talk_script */
+ a->talk_script = pop();
+ break;
+ case 229: /* stand */
+ a->stopActorMoving();
+ a->startAnimActor(a->standFrame);
+ break;
+ case 230: /* set direction */
+ a->moving &= ~MF_TURN;
+ a->setDirection(pop());
+ break;
+ case 231: /* turn to direction */
+ a->turnToDirection(pop());
+ break;
+ case 233: /* freeze actor */
+ a->moving |= 0x80;
+ break;
+ case 234: /* unfreeze actor */
+ a->moving &= ~0x7f;
+ break;
+ default:
+ error("o6_actorset: default case %d", b);
+ }
+}
+
+void Scumm::o6_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(rtVerb, 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 = getStringAddress(a);
+ }
+ loadPtrToResource(rtVerb, 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("o6_verbops: default case");
+ }
+}
+
+void Scumm::o6_getActorFromXY()
+{
+ int y = pop();
+ int x = pop();
+ push(getActorFromPos(x, y));
+}
+
+void Scumm::o6_findObject()
+{
+ int y = pop();
+ int x = pop();
+ int r = findObject(x, y);
+ push(r);
+}
+
+void Scumm::o6_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::o6_getActorElevation()
+{
+ push(derefActorSafe(pop(), "o6_getActorElevation")->elevation);
+}
+
+void Scumm::o6_getVerbEntrypoint()
+{
+ int e = pop();
+ int v = pop();
+ push(getVerbEntrypoint(v, e));
+}
+
+void Scumm::o6_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("o6_arrayOps: default case");
+ }
+}
+
+void Scumm::o6_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("o6_saveRestoreVerbs: default case");
+ }
+}
+
+void Scumm::o6_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::o6_getActorWidth()
+{
+ push(derefActorSafe(pop(), "o6_getActorWidth")->width);
+}
+
+void Scumm::o6_wait()
+{
+ switch (fetchScriptByte()) {
+ case 168:{
+ int offs = (int16)fetchScriptWord();
+ if (derefActorSafe(pop(), "o6_wait")->moving) {
+ _scriptPointer += offs;
+ o6_breakHere();
+ }
+ return;
+ }
+ case 169:
+ //printf("waiting for message: %d\n", _vars[VAR_HAVE_MSG]);
+
+ if (_vars[VAR_HAVE_MSG])
+ break;
+ return;
+ case 170:
+ if (!(_features & GF_AFTER_V7)) {
+ if (camera._cur.x >> 3 != camera._dest.x >> 3)
+ break;
+ } else {
+ if (camera._dest.x != camera._cur.x || camera._dest.y != camera._cur.y)
+ break;
+ }
+
+ return;
+ case 171:
+ printf("wait for sentence");
+ if (_sentenceNum) {
+ if (sentence[_sentenceNum - 1].unk && !isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))
+ return;
+ break;
+ }
+ if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))
+ return;
+ break;
+ case 226:{ /* wait until actor drawn */
+ Actor *a = derefActorSafe(pop(), "o6_wait:226");
+ int offs = (int16)fetchScriptWord();
+ if (a && a->isInCurrentRoom() && a->needRedraw) {
+ _scriptPointer += offs;
+ o6_breakHere();
+ }
+ return;
+ }
+ case 232:{ /* wait until actor stops turning */
+ Actor *a = derefActorSafe(pop(), "o6_wait:226");
+ int offs = (int16)fetchScriptWord();
+ if (a && a->isInCurrentRoom() && a->moving & MF_TURN) {
+ _scriptPointer += offs;
+ o6_breakHere();
+ }
+ return;
+ }
+ default:
+ error("o6_wait: default case");
+ }
+
+ _scriptPointer -= 2;
+ o6_breakHere();
+}
+
+void Scumm::o6_getActorScaleX()
+{
+ push(derefActorSafe(pop(), "o6_getActorScale")->scalex);
+}
+
+void Scumm::o6_getActorAnimCounter1()
+{
+ push(derefActorSafe(pop(), "o6_getActorAnimCounter")->cost.animCounter1);
+}
+
+void Scumm::o6_getAnimateVariable()
+{
+ int var = pop();
+ push(derefActorSafe(pop(), "o6_getAnimateVariable")->getAnimVar(var));
+}
+
+void Scumm::o6_soundKludge()
+{
+ int16 list[16];
+ getStackList(list, sizeof(list) / sizeof(list[0]));
+
+ /* (yazoo): I don't know enought about the sound code to
+ * fix the looping sound bug. FIXME !*/
+
+ if (list[1] == 163 && _gameId == GID_DIG)
+ return;
+
+ _sound->soundKludge(list);
+}
+
+void Scumm::o6_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::o6_quitPauseRestart()
+{
+ switch (fetchScriptByte()) {
+ case 158:
+ pauseGame(false);
+ break;
+ case 160:
+ shutDown(0);
+ break;
+ default:
+ error("o6_quitPauseRestart: invalid case");
+ }
+}
+
+void Scumm::o6_isActorInBox()
+{
+ int box = pop();
+ Actor *a = derefActorSafe(pop(), "o6_isActorInBox");
+ push(checkXYInBoxBounds(box, a->x, a->y));
+}
+
+void Scumm::o6_delay()
+{
+ uint32 delay = (uint16)pop();
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o6_breakHere();
+}
+
+void Scumm::o6_delayLonger()
+{
+ uint32 delay = (uint16)pop() * 60;
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o6_breakHere();
+}
+
+void Scumm::o6_delayVeryLong()
+{
+ uint32 delay = (uint16)pop() * 3600;
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o6_breakHere();
+}
+
+void Scumm::o6_stopSentence()
+{
+ _sentenceNum = 0;
+ stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]);
+ clearClickedStatus();
+}
+
+void Scumm::o6_print_0()
+{
+ _actorToPrintStrFor = 0xFF;
+ decodeParseString2(0, 0);
+}
+
+void Scumm::o6_print_1()
+{
+ decodeParseString2(1, 0);
+}
+
+void Scumm::o6_print_2()
+{
+ decodeParseString2(2, 0);
+}
+
+void Scumm::o6_print_3()
+{
+ decodeParseString2(3, 0);
+}
+
+void Scumm::o6_printActor()
+{
+ decodeParseString2(0, 1);
+}
+
+void Scumm::o6_printEgo()
+{
+ push(_vars[VAR_EGO]);
+ decodeParseString2(0, 1);
+}
+
+void Scumm::o6_talkActor()
+{
+ _actorToPrintStrFor = pop();
+ _messagePtr = _scriptPointer;
+
+ if (_scriptPointer[0] == '/') {
+ char *pointer = strtok((char *)_scriptPointer, "/");
+ int bunsize = strlen(pointer) + 2;
+ _sound->playBundleSound(pointer);
+ _scriptPointer += bunsize;
+ _messagePtr = _scriptPointer;
+ }
+
+ setStringVars(0);
+ actorTalk();
+ _scriptPointer = _messagePtr;
+}
+
+void Scumm::o6_talkEgo()
+{
+ _actorToPrintStrFor = (unsigned char)_vars[VAR_EGO];
+ _messagePtr = _scriptPointer;
+
+ if (_scriptPointer[0] == '/') {
+ char *pointer = strtok((char *)_scriptPointer, "/");
+ int bunsize = strlen(pointer) + 2;
+ _sound->playBundleSound(pointer);
+ _scriptPointer += bunsize;
+ _messagePtr = _scriptPointer;
+ }
+
+ setStringVars(0);
+ actorTalk();
+ _scriptPointer = _messagePtr;
+}
+
+void Scumm::o6_dim()
+{
+ 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("o6_dim : default case");
+ }
+
+ defineArray(fetchScriptWord(), data, 0, pop());
+}
+
+void Scumm::o6_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::o6_runScriptQuick()
+{
+ int16 args[16];
+ int script;
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+ script = pop();
+ runScript(script, 0, 1, args);
+}
+
+void Scumm::o6_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("o6_dim2: default case");
+ }
+
+ b = pop();
+ a = pop();
+ defineArray(fetchScriptWord(), data, a, b);
+}
+
+void Scumm::o6_abs()
+{
+ push(abs(pop()));
+}
+
+
+void Scumm::o6_distObjectObject()
+{
+ int a, b;
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(true, a, 0, true, b, 0));
+}
+
+void Scumm::o6_distObjectPt()
+{
+ int a, b, c;
+ c = pop();
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(true, a, 0, false, b, c));
+}
+
+void Scumm::o6_distPtPt()
+{
+ int a, b, c, d;
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(false, a, b, false, c, d));
+}
+
+void Scumm::o6_dummy_stacklist()
+{
+ error("opcode o6_dummy_stacklist invalid");
+}
+
+void Scumm::o6_drawBlastObject()
+{
+ int16 args[16];
+ int a, b, c, d, e;
+
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ enqueueObject(a, b, c, d, e, 0xFF, 0xFF, 1, 0);
+}
+
+void Scumm::o6_miscOps()
+{
+ int16 args[30];
+ int i;
+ Actor *a;
+
+ IMuse *se = _imuse; //yazoo: not very nice
+ SmushPlayer * sp;
+
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+
+ if (_features & GF_AFTER_V7) {
+ switch (args[0]) {
+ case 4:
+ grabCursor(args[1], args[2], args[3], args[4]);
+ break;
+ case 6:
+ sp = new SmushPlayer(this);
+ sp->startVideo(args[1], getStringAddressVar(VAR_VIDEONAME));
+ delete sp;
+ break;
+ case 7:
+ warning("o6_miscOps: stub7()");
+ break;
+ case 10:
+ warning("o6_miscOps: stub10(%d,%d,%d,%d)", args[1], args[2], args[3], args[4]);
+ break;
+ case 11:
+ warning("o6_miscOps: stub11(%d)", args[1]);
+ break;
+ case 12:
+ setCursorImg(args[1], (uint) - 1, args[2]);
+ break;
+ case 13:
+ derefActorSafe(args[1], "o6_miscOps:14")->remapActorPalette(args[2], args[3], args[4], -1);
+ break;
+ case 14:
+ derefActorSafe(args[1], "o6_miscOps:14")->remapActorPalette(args[2], args[3], args[4], args[5]);
+ break;
+ case 15:
+ _insaneFlag = args[1];
+ break;
+ case 16:
+ if (_gameId == GID_DIG) {
+ _msgPtrToAdd = charset._buffer;
+ addMessageToStack(getStringAddressVar(VAR_STRING2DRAW));
+ i = 0;
+ while (charset._buffer[i] != 0) {
+ if (charset._buffer[i] == '/') {
+ charset._bufPos = i + 1;
+ }
+ i++;
+ }
+ description();
+ }
+ break;
+ case 17:
+ warning("o6_miscOps: stub17(%d,%d,%d,%d)", args[1], args[2], args[3], args[4]);
+ break;
+ case 18:
+ warning("o6_miscOps: stub18(%d,%d)", args[1], args[2]);
+ break;
+ case 107:
+ a = derefActorSafe(args[1], "o6_miscops: 107");
+ a->scalex = (unsigned char)args[2];
+ a->needBgReset = true;
+ a->needRedraw = true;
+ break;
+ case 108:
+ setupShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]);
+ break;
+ case 109:
+ setupShadowPalette(0, args[1], args[2], args[3], args[4], args[5]);
+ break;
+ case 114:
+ warning("o6_miscOps: stub114()");
+ break;
+ case 117:
+ freezeScripts(2);
+ break;
+ case 118:
+ enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 3);
+ break;
+ case 119:
+ enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
+ break;
+ case 120:
+ warning("o6_miscOps: stub120(%d,%d)", args[1], args[2]);
+ break;
+ case 124:
+ warning("o6_miscOps: stub124(%d)", args[1]);
+ break;
+ }
+ } else {
+ switch (args[0]) {
+ case 3:
+ warning("o6_miscOps: nothing in 3");
+ break;
+ case 4:
+ grabCursor(args[1], args[2], args[3], args[4]);
+ break;
+ case 5:
+ fadeOut(args[1]);
+ break;
+ case 6:
+ _fullRedraw = 1;
+ redrawBGAreas();
+ for (i = 0; i < NUM_ACTORS; i++)
+ derefActor(i)->needRedraw = true;
+ processActors();
+ fadeIn(args[1]);
+ break;
+ case 8:
+ startManiac();
+ break;
+ case 9:
+ unkMiscOp9();
+ break;
+
+ case 104: /* samnmax */
+ nukeFlObjects(args[2], args[3]);
+ break;
+
+ case 106:
+ error("stub o6_miscOps_106()");
+ break;
+
+ case 107: /* set actor scale */
+ a = derefActorSafe(args[1], "o6_miscops: 107");
+ a->scalex = (unsigned char)args[2];
+ a->needBgReset = true;
+ a->needRedraw = true;
+ break;
+
+ case 108: /* create proc_special_palette */
+ case 109:
+
+ createSpecialPalette(args[1], args[2], args[3], args[4], args[5], 0, 256);
+ break;
+
+ case 110:
+ gdi.clearUpperMask();
+ break;
+
+ case 111:
+ a = derefActorSafe(args[1], "o6_miscops: 111");
+ a->shadow_mode = args[2] + args[3];
+ break;
+
+ case 112: /* palette shift? */
+ createSpecialPalette(args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ break;
+
+ case 114:
+ // Sam & Max film noir mode
+ if (_gameId == GID_SAMNMAX) {
+ // At this point ScummVM will already have set
+ // variable 0x8000 to indicate that the game is
+ // in film noir mode. All we have to do here is
+ // to mark the palette as "dirty", and the next
+ // call to updatePalette() will take care of
+ // the rest.
+ //
+ // Actually, for extra bug-compatibility we
+ // should call desaturatePalette() here only,
+ // instead of in updatePalette(). To see the
+ // difference in behaviour, try turning on film
+ // noir mode in Sam & Max's office. The
+ // background will be grayscale, but Sam and
+ // Max themselves will be in color.
+ setDirtyColors(0, 255);
+ } else
+ warning("stub o6_miscOps_114()");
+ break;
+
+ case 117:
+ warning("stub o6_miscOps_117()");
+ break;
+
+ case 118:
+ error("stub o6_miscOps_118(%d,%d,%d,%d,%d,%d,%d)",
+ args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ break;
+
+ case 119:
+ enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
+ break;
+
+ case 120:
+ swapPalColors(args[1], args[2]);
+ break;
+
+ case 121:
+ error("stub o6_miscOps_121(%d)", args[1]);
+ break;
+
+ case 122:
+
+ _vars[VAR_SOUNDRESULT] =
+ (short)se->do_command(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]
+ );
+ break;
+
+ case 123:
+ swapPalColors(args[1], args[2]);
+ break;
+
+ case 124: /* samnmax */
+ warning("o6_miscOps: _saveSound=%d", args[1]);
+ _saveSound = args[1];
+ break;
+
+ default:
+ error("o6_miscOps: default case %d", args[0]);
+ }
+ }
+}
+
+void Scumm::o6_kernelFunction()
+{
+ int16 args[30];
+ int i;
+ Actor *a;
+
+ getStackList(args, sizeof(args) / sizeof(args[0]));
+
+ switch (args[0]) {
+ case 113:
+ // Do something to [1] x [2] (x/y)
+ warning("o6_kernelFunction: stub113(%d,%d)", args[1], args[2]);
+ push(0);
+ break;
+ case 115:
+ push(getSpecialBox(args[1], args[2]));
+ break;
+ case 116:
+ push(checkXYInBoxBounds(args[3], args[1], args[2]));
+ break;
+ case 206:
+ push(remapPaletteColor(args[1], args[2], args[3], (uint) - 1));
+ break;
+ case 207:
+ i = getObjectIndex(pop());
+ push(_objs[i].x_pos);
+ break;
+ case 208:
+ i = getObjectIndex(pop());
+ push(_objs[i].y_pos);
+ break;
+ case 209:
+ i = getObjectIndex(pop());
+ push(_objs[i].width);
+ break;
+ case 210:
+ i = getObjectIndex(pop());
+ push(_objs[i].height);
+ break;
+ case 211:
+ warning("o6_kernelFunction: getInput(%d)", args[1]);
+ /*
+ 13 = thrust
+ 336 = thrust
+ 328 = thrust
+ 27 = abord
+ 97 = left
+ 331 = left
+ 115 = right
+ 333 = tight
+ */
+ push(0);
+ break;
+ case 212:
+ a = derefActorSafe(args[1], "o6_kernelFunction:212");
+ push(a->frame);
+ break;
+ case 215:
+ if (_extraBoxFlags[args[1]] & 0x00FF == 0x00C0) {
+ push(_extraBoxFlags[args[1]]);
+ } else {
+ byte *temp = (byte *)getBoxBaseAddr(args[1]);
+ push((byte)(*(temp + 17)));
+ }
+ break;
+ default:
+ error("o6_kernelFunction: default case %d", args[0]);
+ }
+}
+
+void Scumm::o6_breakMaybe()
+{
+ ScriptSlot *ss = &vm.slot[_currentScript];
+ if (ss->newfield == 0) {
+ ss->newfield = pop();
+ } else {
+ ss->newfield--;
+ }
+ if (ss->newfield) {
+ _scriptPointer--;
+ o6_breakHere();
+ }
+}
+
+void Scumm::o6_pickOneOf()
+{
+ int16 args[100];
+ int i, num;
+
+ num = getStackList(args, sizeof(args) / sizeof(args[0]));
+ i = pop();
+ if (i < 0 || i >= num)
+ error("o6_pickOneOf: out of range");
+ push(args[i]);
+}
+
+void Scumm::o6_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::o6_getActorPriority()
+{
+ Actor *a;
+
+ a = derefActorSafe(pop(), "getActorPriority");
+
+ push(a->layer);
+}
+
+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 = false;
+ break;
+ case 66:
+ string[m].color = pop();
+ break;
+ case 67:
+ string[m].right = pop();
+ break;
+ case 69:
+ string[m].center = true;
+ string[m].overhead = false;
+ break;
+ case 71:
+ string[m].center = false;
+ string[m].overhead = false;
+ break;
+ case 72:
+ string[m].overhead = true;
+ string[m].no_talk_anim = false;
+ break;
+ case 73:
+ error("decodeParseString2: case 73");
+ break;
+ case 74:
+ string[m].no_talk_anim = true;
+ break;
+ case 75:{
+ _messagePtr = _scriptPointer;
+
+ if (_scriptPointer[0] == '/') {
+ char *pointer = strtok((char *)_scriptPointer, "/");
+ int bunsize = strlen(pointer) + 2;
+ _sound->playBundleSound(pointer);
+ _scriptPointer += bunsize;
+ _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_no_talk_anim = string[m].no_talk_anim;
+ 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");
+ }
+}
+
+void Scumm::setupShadowPalette(int slot, int rfact, int gfact, int bfact, int from, int to)
+{
+ byte *table;
+ int i, num;
+ byte *curpal;
+
+ if (slot < 0 || slot > 7)
+ error("setupShadowPalette: invalid slot %d", slot);
+
+ if (from < 0 || from > 255 || to < 0 || from > 255 || to < from)
+ error("setupShadowPalette: invalid range from %d to %d", from, to);
+
+ table = _shadowPalette + slot * 256;
+ for (i = 0; i < 256; i++)
+ table[i] = i;
+
+ table += from;
+ curpal = _currentPalette + from * 3;
+ num = to - from + 1;
+ do {
+ *table++ = remapPaletteColor((curpal[0] * rfact) >> 8,
+ curpal[1] * gfact >> 8, curpal[2] * bfact >> 8, (uint) - 1);
+ curpal += 3;
+ } while (--num);
+}