aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/script_v100he.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/script_v100he.cpp')
-rw-r--r--engines/scumm/script_v100he.cpp2958
1 files changed, 2958 insertions, 0 deletions
diff --git a/engines/scumm/script_v100he.cpp b/engines/scumm/script_v100he.cpp
new file mode 100644
index 0000000000..790f65e021
--- /dev/null
+++ b/engines/scumm/script_v100he.cpp
@@ -0,0 +1,2958 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "scumm/actor.h"
+#include "scumm/charset.h"
+#include "scumm/intern_he.h"
+#include "scumm/object.h"
+#include "scumm/resource.h"
+#include "scumm/resource_v7he.h"
+#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/sprite_he.h"
+#include "scumm/util.h"
+
+namespace Scumm {
+
+#define OPCODE(x) _OPCODE(ScummEngine_v100he, x)
+
+void ScummEngine_v100he::setupOpcodes() {
+ static const OpcodeEntryV100he opcodes[256] = {
+ /* 00 */
+ OPCODE(o100_actorOps),
+ OPCODE(o6_add),
+ OPCODE(o6_faceActor),
+ OPCODE(o90_sortArray),
+ /* 04 */
+ OPCODE(o100_arrayOps),
+ OPCODE(o6_band),
+ OPCODE(o6_bor),
+ OPCODE(o6_breakHere),
+ /* 08 */
+ OPCODE(o6_delayFrames),
+ OPCODE(o90_shl),
+ OPCODE(o90_shr),
+ OPCODE(o90_xor),
+ /* 0C */
+ OPCODE(o6_setCameraAt),
+ OPCODE(o6_actorFollowCamera),
+ OPCODE(o6_loadRoom),
+ OPCODE(o6_panCameraTo),
+ /* 10 */
+ OPCODE(o72_captureWizImage),
+ OPCODE(o100_jumpToScript),
+ OPCODE(o6_setClass),
+ OPCODE(o60_closeFile),
+ /* 14 */
+ OPCODE(o6_loadRoomWithEgo),
+ OPCODE(o6_invalid),
+ OPCODE(o72_setFilePath),
+ OPCODE(o100_createSound),
+ /* 18 */
+ OPCODE(o6_cutscene),
+ OPCODE(o6_pop),
+ OPCODE(o72_traceStatus),
+ OPCODE(o6_wordVarDec),
+ /* 1C */
+ OPCODE(o6_wordArrayDec),
+ OPCODE(o72_deleteFile),
+ OPCODE(o100_dim2dimArray),
+ OPCODE(o100_dimArray),
+ /* 20 */
+ OPCODE(o6_div),
+ OPCODE(o6_animateActor),
+ OPCODE(o6_doSentence),
+ OPCODE(o6_drawBox),
+ /* 24 */
+ OPCODE(o72_drawWizImage),
+ OPCODE(o80_drawWizPolygon),
+ OPCODE(o100_drawLine),
+ OPCODE(o100_drawObject),
+ /* 28 */
+ OPCODE(o6_dup),
+ OPCODE(o90_dup_n),
+ OPCODE(o6_endCutscene),
+ OPCODE(o6_stopObjectCode),
+ /* 2C */
+ OPCODE(o6_stopObjectCode),
+ OPCODE(o6_eq),
+ OPCODE(o100_floodFill),
+ OPCODE(o6_freezeUnfreeze),
+ /* 30 */
+ OPCODE(o6_ge),
+ OPCODE(o6_getDateTime),
+ OPCODE(o100_setSpriteGroupInfo),
+ OPCODE(o6_gt),
+ /* 34 */
+ OPCODE(o100_resourceRoutines),
+ OPCODE(o6_if),
+ OPCODE(o6_ifNot),
+ OPCODE(o100_wizImageOps),
+ /* 38 */
+ OPCODE(o72_isAnyOf),
+ OPCODE(o6_wordVarInc),
+ OPCODE(o6_wordArrayInc),
+ OPCODE(o6_jump),
+ /* 3C */
+ OPCODE(o90_kernelSetFunctions),
+ OPCODE(o6_land),
+ OPCODE(o6_le),
+ OPCODE(o60_localizeArrayToScript),
+ /* 40 */
+ OPCODE(o6_wordArrayRead),
+ OPCODE(o6_wordArrayIndexedRead),
+ OPCODE(o6_lor),
+ OPCODE(o6_lt),
+ /* 44 */
+ OPCODE(o90_mod),
+ OPCODE(o6_mul),
+ OPCODE(o6_neq),
+ OPCODE(o100_dim2dim2Array),
+ /* 48 */
+ OPCODE(o6_setObjectName),
+ OPCODE(o100_redim2dimArray),
+ OPCODE(o6_not),
+ OPCODE(o6_invalid),
+ /* 4C */
+ OPCODE(o6_beginOverride),
+ OPCODE(o6_endOverride),
+ OPCODE(o72_resetCutscene),
+ OPCODE(o6_setOwner),
+ /* 50 */
+ OPCODE(o100_paletteOps),
+ OPCODE(o70_pickupObject),
+ OPCODE(o70_polygonOps),
+ OPCODE(o6_pop),
+ /* 54 */
+ OPCODE(o6_printDebug),
+ OPCODE(o72_printWizImage),
+ OPCODE(o6_printLine),
+ OPCODE(o6_printSystem),
+ /* 58 */
+ OPCODE(o6_printText),
+ OPCODE(o100_jumpToScriptUnk),
+ OPCODE(o100_startScriptUnk),
+ OPCODE(o6_pseudoRoom),
+ /* 5C */
+ OPCODE(o6_pushByte),
+ OPCODE(o72_pushDWord),
+ OPCODE(o72_getScriptString),
+ OPCODE(o6_pushWord),
+ /* 60 */
+ OPCODE(o6_pushWordVar),
+ OPCODE(o6_putActorAtObject),
+ OPCODE(o6_putActorAtXY),
+ OPCODE(o6_invalid),
+ /* 64 */
+ OPCODE(o100_redimArray),
+ OPCODE(o72_rename),
+ OPCODE(o6_stopObjectCode),
+ OPCODE(o80_localizeArrayToRoom),
+ /* 68 */
+ OPCODE(o100_roomOps),
+ OPCODE(o6_printActor),
+ OPCODE(o6_printEgo),
+ OPCODE(o72_talkActor),
+ /* 6C */
+ OPCODE(o72_talkEgo),
+ OPCODE(o6_invalid),
+ OPCODE(o70_seekFilePos),
+ OPCODE(o6_setBoxFlags),
+ /* 70 */
+ OPCODE(o6_invalid),
+ OPCODE(o6_setBoxSet),
+ OPCODE(o72_setWindowCaption),
+ OPCODE(o6_shuffle),
+ /* 74 */
+ OPCODE(o6_delay),
+ OPCODE(o6_delayMinutes),
+ OPCODE(o6_delaySeconds),
+ OPCODE(o100_startSound),
+ /* 78 */
+ OPCODE(o80_sourceDebug),
+ OPCODE(o100_setSpriteInfo),
+ OPCODE(o6_stampObject),
+ OPCODE(o72_startObject),
+ /* 7C */
+ OPCODE(o100_startScript),
+ OPCODE(o6_startScriptQuick),
+ OPCODE(o80_setState),
+ OPCODE(o6_stopObjectScript),
+ /* 80 */
+ OPCODE(o6_stopScript),
+ OPCODE(o6_stopSentence),
+ OPCODE(o6_stopSound),
+ OPCODE(o6_stopTalking),
+ /* 84 */
+ OPCODE(o6_writeWordVar),
+ OPCODE(o6_wordArrayWrite),
+ OPCODE(o6_wordArrayIndexedWrite),
+ OPCODE(o6_sub),
+ /* 88 */
+ OPCODE(o100_systemOps),
+ OPCODE(o6_invalid),
+ OPCODE(o72_setTimer),
+ OPCODE(o100_cursorCommand),
+ /* 8C */
+ OPCODE(o100_videoOps),
+ OPCODE(o100_wait),
+ OPCODE(o6_walkActorToObj),
+ OPCODE(o6_walkActorTo),
+ /* 90 */
+ OPCODE(o100_writeFile),
+ OPCODE(o72_writeINI),
+ OPCODE(o80_writeConfigFile),
+ OPCODE(o6_abs),
+ /* 94 */
+ OPCODE(o6_getActorWalkBox),
+ OPCODE(o6_getActorCostume),
+ OPCODE(o6_getActorElevation),
+ OPCODE(o6_getObjectOldDir),
+ /* 98 */
+ OPCODE(o6_getActorMoving),
+ OPCODE(o90_getActorData),
+ OPCODE(o6_getActorRoom),
+ OPCODE(o6_getActorScaleX),
+ /* 9C */
+ OPCODE(o6_getAnimateVariable),
+ OPCODE(o6_getActorWidth),
+ OPCODE(o6_getObjectX),
+ OPCODE(o6_getObjectY),
+ /* A0 */
+ OPCODE(o90_atan2),
+ OPCODE(o90_getSegmentAngle),
+ OPCODE(o90_getActorAnimProgress),
+ OPCODE(o90_getDistanceBetweenPoints),
+ /* A4 */
+ OPCODE(o6_ifClassOfIs),
+ OPCODE(o6_invalid),
+ OPCODE(o90_cond),
+ OPCODE(o90_cos),
+ /* A8 */
+ OPCODE(o6_invalid),
+ OPCODE(o80_getFileSize),
+ OPCODE(o6_getActorFromXY),
+ OPCODE(o72_findAllObjects),
+ /* AC */
+ OPCODE(o90_findAllObjectsWithClassOf),
+ OPCODE(o6_invalid),
+ OPCODE(o6_findInventory),
+ OPCODE(o72_findObject),
+ /* B0 */
+ OPCODE(o72_findObjectWithClassOf),
+ OPCODE(o70_polygonHit),
+ OPCODE(o90_getLinesIntersectionPoint),
+ OPCODE(o90_fontUnk),
+ /* B4 */
+ OPCODE(o72_getNumFreeArrays),
+ OPCODE(o72_getArrayDimSize),
+ OPCODE(o100_isResourceLoaded),
+ OPCODE(o100_getResourceSize),
+ /* B8 */
+ OPCODE(o100_getSpriteGroupInfo),
+ OPCODE(o6_invalid),
+ OPCODE(o100_getWizData),
+ OPCODE(o6_isActorInBox),
+ /* BC */
+ OPCODE(o6_isAnyOf),
+ OPCODE(o6_getInventoryCount),
+ OPCODE(o90_kernelGetFunctions),
+ OPCODE(o90_max),
+ /* C0 */
+ OPCODE(o90_min),
+ OPCODE(o72_getObjectImageX),
+ OPCODE(o72_getObjectImageY),
+ OPCODE(o6_isRoomScriptRunning),
+ /* C4 */
+ OPCODE(o90_getObjectData),
+ OPCODE(o72_openFile),
+ OPCODE(o90_getPolygonOverlap),
+ OPCODE(o6_getOwner),
+ /* C8 */
+ OPCODE(o100_getPaletteData),
+ OPCODE(o6_pickOneOf),
+ OPCODE(o6_pickOneOfDefault),
+ OPCODE(o80_pickVarRandom),
+ /* CC */
+ OPCODE(o72_getPixel),
+ OPCODE(o6_distObjectObject),
+ OPCODE(o6_distObjectPt),
+ OPCODE(o6_distPtPt),
+ /* D0 */
+ OPCODE(o6_getRandomNumber),
+ OPCODE(o6_getRandomNumberRange),
+ OPCODE(o6_invalid),
+ OPCODE(o100_readFile),
+ /* D4 */
+ OPCODE(o72_readINI),
+ OPCODE(o80_readConfigFile),
+ OPCODE(o6_isScriptRunning),
+ OPCODE(o90_sin),
+ /* D8 */
+ OPCODE(o72_getSoundPosition),
+ OPCODE(o6_isSoundRunning),
+ OPCODE(o80_getSoundVar),
+ OPCODE(o100_getSpriteInfo),
+ /* DC */
+ OPCODE(o90_sqrt),
+ OPCODE(o6_startObjectQuick),
+ OPCODE(o6_startScriptQuick2),
+ OPCODE(o6_getState),
+ /* E0 */
+ OPCODE(o70_compareString),
+ OPCODE(o70_copyString),
+ OPCODE(o70_appendString),
+ OPCODE(o70_concatString),
+ /* E4 */
+ OPCODE(o70_getStringLen),
+ OPCODE(o70_getStringLenForWidth),
+ OPCODE(o80_stringToInt),
+ OPCODE(o70_getCharIndexInString),
+ /* E8 */
+ OPCODE(o70_getStringWidth),
+ OPCODE(o60_readFilePos),
+ OPCODE(o72_getTimer),
+ OPCODE(o6_getVerbEntrypoint),
+ /* EC */
+ OPCODE(o100_getVideoData),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ /* F0 */
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ /* F4 */
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ /* F8 */
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ /* FC */
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ OPCODE(o6_invalid),
+ };
+
+ _opcodesV100he = opcodes;
+}
+
+void ScummEngine_v100he::executeOpcode(byte i) {
+ OpcodeProcV100he op = _opcodesV100he[i].proc;
+ (this->*op) ();
+}
+
+const char *ScummEngine_v100he::getOpcodeDesc(byte i) {
+ return _opcodesV100he[i].desc;
+}
+
+void ScummEngine_v100he::o100_actorOps() {
+ Actor *a;
+ int i, j, k;
+ int args[32];
+ byte string[256];
+
+ byte subOp = fetchScriptByte();
+ if (subOp == 129) {
+ _curActor = pop();
+ return;
+ }
+
+ a = derefActorSafe(_curActor, "o100_actorOps");
+ if (!a)
+ return;
+
+ switch (subOp) {
+ case 0:
+ // freddicove Ru Updated
+ // FIXME: check stack parameters
+ debug(0,"o100_actorOps: case 0 UNHANDLED");
+ break;
+ case 3:
+ pop();
+ pop();
+ pop();
+ break;
+ case 4: // SO_ANIMATION_SPEED
+ a->setAnimSpeed(pop());
+ break;
+ case 6:
+ j = pop();
+ i = pop();
+ a->putActor(i, j, a->_room);
+ break;
+ case 8:
+ a->_drawToBackBuf = false;
+ a->_needRedraw = true;
+ a->_needBgReset = true;
+ break;
+ case 9:
+ a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
+ break;
+ case 14:
+ a->_charset = pop();
+ break;
+ case 18:
+ a->_clipOverride.bottom = pop();
+ a->_clipOverride.right = pop();
+ a->_clipOverride.top = pop();
+ a->_clipOverride.left = pop();
+ break;
+ case 22:
+ k = getStackList(args, ARRAYSIZE(args));
+ for (i = 0; i < k; ++i) {
+ a->setUserCondition(args[i] & 0x7F, args[i] & 0x80);
+ }
+ break;
+ case 25: // SO_COSTUME
+ a->setActorCostume(pop());
+ break;
+ case 27: // SO_DEFAULT
+ a->initActor(0);
+ break;
+ case 32:
+ i = pop();
+ debug(0,"o100_actorOps: case 32 (%d)", i);
+ break;
+ case 52: // SO_ACTOR_NAME
+ copyScriptString(string, sizeof(string));
+ loadPtrToResource(rtActorName, a->_number, string);
+ break;
+ case 53: // SO_ACTOR_NEW
+ a->initActor(2);
+ break;
+ case 57: // SO_PALETTE
+ j = pop();
+ i = pop();
+ checkRange(255, 0, i, "o100_actorOps: Illegal palette slot %d");
+ a->remapActorPaletteColor(i, j);
+ a->_needRedraw = true;
+ break;
+ case 59:
+ // HE games use reverse order of layering, so we adjust
+ a->_layer = -pop();
+ a->_needRedraw = true;
+ break;
+ case 63:
+ a->_hePaletteNum = pop();
+ a->_needRedraw = true;
+ break;
+ case 65: // SO_SCALE
+ i = pop();
+ a->setScale(i, i);
+ break;
+ case 70: // SO_SHADOW
+ a->_heXmapNum = pop();
+ a->_needRedraw = true;
+ break;
+ case 74: // SO_STEP_DIST
+ j = pop();
+ i = pop();
+ a->setActorWalkSpeed(i, j);
+ break;
+ case 78:
+ {
+ copyScriptString(string, sizeof(string));
+ int slot = pop();
+
+ int len = resStrLen(string) + 1;
+ memcpy(a->_heTalkQueue[slot].sentence, string, len);
+
+ a->_heTalkQueue[slot].posX = a->_talkPosX;
+ a->_heTalkQueue[slot].posY = a->_talkPosY;
+ a->_heTalkQueue[slot].color = a->_talkColor;
+ }
+ break;
+ case 83: // SO_ACTOR_VARIABLE
+ i = pop();
+ a->setAnimVar(pop(), i);
+ break;
+ case 87: // SO_ALWAYS_ZCLIP
+ a->_forceClip = pop();
+ break;
+ case 89: // SO_NEVER_ZCLIP
+ a->_forceClip = 0;
+ break;
+ case 128:
+ _actorClipOverride.bottom = pop();
+ _actorClipOverride.right = pop();
+ _actorClipOverride.top = pop();
+ _actorClipOverride.left = pop();
+ break;
+ case 130: // SO_SOUND
+ k = getStackList(args, ARRAYSIZE(args));
+ for (i = 0; i < k; i++)
+ a->_sound[i] = args[i];
+ break;
+ case 131: // SO_ACTOR_WIDTH
+ a->_width = pop();
+ break;
+ case 132: // SO_ANIMATION_DEFAULT
+ a->_initFrame = 1;
+ a->_walkFrame = 2;
+ a->_standFrame = 3;
+ a->_talkStartFrame = 4;
+ a->_talkStopFrame = 5;
+ break;
+ case 133: // SO_ELEVATION
+ a->setElevation(pop());
+ break;
+ case 134: // SO_FOLLOW_BOXES
+ a->_ignoreBoxes = 0;
+ a->_forceClip = 0;
+ if (a->isInCurrentRoom())
+ a->putActor(a->_pos.x, a->_pos.y, a->_room);
+ break;
+ case 135: // SO_IGNORE_BOXES
+ a->_ignoreBoxes = 1;
+ a->_forceClip = 0;
+ if (a->isInCurrentRoom())
+ a->putActor(a->_pos.x, a->_pos.y, a->_room);
+ break;
+ case 136: // SO_ACTOR_IGNORE_TURNS_OFF
+ a->_ignoreTurns = false;
+ break;
+ case 137: // SO_ACTOR_IGNORE_TURNS_ON
+ a->_ignoreTurns = true;
+ break;
+ case 138: // SO_INIT_ANIMATION
+ a->_initFrame = pop();
+ break;
+ case 139: // SO_STAND_ANIMATION
+ a->_standFrame = pop();
+ break;
+ case 140: // SO_TALK_ANIMATION
+ a->_talkStopFrame = pop();
+ a->_talkStartFrame = pop();
+ break;
+ case 141: // SO_TALK_COLOR
+ a->_talkColor = pop();
+ break;
+ case 142:
+ k = pop();
+ if (k == 0)
+ k = _rnd.getRandomNumberRng(1, 10);
+ a->_heNoTalkAnimation = 1;
+ a->setTalkCondition(k);
+ break;
+ case 143: // SO_TEXT_OFFSET
+ a->_talkPosY = pop();
+ a->_talkPosX = pop();
+ break;
+ case 144: // SO_WALK_ANIMATION
+ a->_walkFrame = pop();
+ break;
+ default:
+ error("o100_actorOps: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_arrayOps() {
+ ArrayHeader *ah;
+ byte string[1024];
+ int dim1end, dim1start, dim2end, dim2start;
+ int id, len, b, c, list[128];
+ int offs, tmp, tmp2;
+ uint tmp3;
+
+ byte subOp = fetchScriptByte();
+ int array = fetchScriptWord();
+ debug(9,"o100_arrayOps: array %d case %d", array, subOp);
+
+ switch (subOp) {
+ case 35:
+ decodeScriptString(string);
+ len = resStrLen(string);
+ ah = defineArray(array, kStringArray, 0, 0, 0, len);
+ memcpy(ah->data, string, len);
+ break;
+ case 77: // SO_ASSIGN_STRING
+ copyScriptString(string, sizeof(string));
+ len = resStrLen(string);
+ ah = defineArray(array, kStringArray, 0, 0, 0, len);
+ memcpy(ah->data, string, len);
+ break;
+
+ case 128: // SO_ASSIGN_2DIM_LIST
+ len = getStackList(list, ARRAYSIZE(list));
+ id = readVar(array);
+ if (id == 0)
+ error("Must DIM a two dimensional array before assigning");
+ c = pop();
+ while (--len >= 0) {
+ writeArray(array, c, len, list[len]);
+ }
+ break;
+ case 129: // SO_ASSIGN_INT_LIST
+ b = pop();
+ c = pop();
+ id = readVar(array);
+ if (id == 0) {
+ defineArray(array, kDwordArray, 0, 0, 0, b + c - 1);
+ }
+ while (c--) {
+ writeArray(array, 0, b + c, pop());
+ }
+ break;
+ case 130:
+ len = getStackList(list, ARRAYSIZE(list));
+ dim1end = pop();
+ dim1start = pop();
+ dim2end = pop();
+ dim2start = pop();
+ id = readVar(array);
+ if (id == 0) {
+ defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
+ }
+ tmp2 = 0;
+ while (dim2start <= dim2end) {
+ tmp = dim1start;
+ while (tmp <= dim1end) {
+ writeArray(array, dim2start, tmp, list[tmp2++]);
+ if (tmp2 == len)
+ tmp2 = 0;
+ tmp++;
+ }
+ dim2start++;
+ }
+ break;
+ case 131:
+ {
+ int a2_dim1end = pop();
+ int a2_dim1start = pop();
+ int a2_dim2end = pop();
+ int a2_dim2start = pop();
+ int array2 = fetchScriptWord();
+ int a1_dim1end = pop();
+ int a1_dim1start = pop();
+ int a1_dim2end = pop();
+ int a1_dim2start = pop();
+ if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
+ error("Source and dest ranges size are mismatched");
+ }
+ copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
+ }
+ break;
+ case 133:
+ b = pop();
+ c = pop();
+ dim1end = pop();
+ dim1start = pop();
+ dim2end = pop();
+ dim2start = pop();
+ id = readVar(array);
+ if (id == 0) {
+ defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
+ }
+
+ offs = (b >= c) ? 1 : -1;
+ tmp2 = c;
+ tmp3 = c - b + 1;
+ while (dim2start <= dim2end) {
+ tmp = dim1start;
+ while (tmp <= dim1end) {
+ writeArray(array, dim2start, tmp, tmp2);
+ if (--tmp3 == 0) {
+ tmp2 = c;
+ tmp3 = c - b + 1;
+ } else {
+ tmp2 += offs;
+ }
+ tmp++;
+ }
+ dim2start++;
+ }
+ break;
+ default:
+ error("o100_arrayOps: default case %d (array %d)", subOp, array);
+ }
+}
+
+void ScummEngine_v100he::o100_jumpToScript() {
+ int args[25];
+ int script;
+ byte flags;
+
+ getStackList(args, ARRAYSIZE(args));
+ script = pop();
+ flags = fetchScriptByte();
+ stopObjectCode();
+ runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args);
+}
+
+void ScummEngine_v100he::o100_createSound() {
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ _heSndResId = pop();
+ break;
+ case 53:
+ createSound(_heSndResId, -1);
+ break;
+ case 92:
+ // dummy case
+ break;
+ case 128:
+ createSound(_heSndResId, pop());
+ break;
+ default:
+ error("o100_createSound: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_dim2dimArray() {
+ int data, dim1end, dim2end;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 41: // SO_BIT_ARRAY
+ data = kBitArray;
+ break;
+ case 42: // SO_INT_ARRAY
+ data = kIntArray;
+ break;
+ case 43:
+ data = kDwordArray;
+ break;
+ case 44: // SO_NIBBLE_ARRAY
+ data = kNibbleArray;
+ break;
+ case 45: // SO_BYTE_ARRAY
+ data = kByteArray;
+ break;
+ case 77: // SO_STRING_ARRAY
+ data = kStringArray;
+ break;
+ default:
+ error("o100_dim2dimArray: default case %d", subOp);
+ }
+
+ dim1end = pop();
+ dim2end = pop();
+ defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
+}
+
+void ScummEngine_v100he::o100_dimArray() {
+ int data;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 41: // SO_BIT_ARRAY
+ data = kBitArray;
+ break;
+ case 42: // SO_INT_ARRAY
+ data = kIntArray;
+ break;
+ case 43:
+ data = kDwordArray;
+ break;
+ case 44: // SO_NIBBLE_ARRAY
+ data = kNibbleArray;
+ break;
+ case 45: // SO_BYTE_ARRAY
+ data = kByteArray;
+ break;
+ case 77: // SO_STRING_ARRAY
+ data = kStringArray;
+ break;
+ case 135: // SO_UNDIM_ARRAY
+ nukeArray(fetchScriptWord());
+ return;
+ default:
+ error("o100_dimArray: default case %d", subOp);
+ }
+
+ defineArray(fetchScriptWord(), data, 0, 0, 0, pop());
+}
+
+void ScummEngine_v100he::o100_drawLine() {
+ int id, unk1, unk2, x, x1, y1;
+
+ unk2 = pop();
+ id = pop();
+ unk1 = pop();
+ x = pop();
+ y1 = pop();
+ x1 = pop();
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 1:
+ drawLine(x1, y1, x, unk1, unk2, 2, id);
+ break;
+ case 20:
+ drawLine(x1, y1, x, unk1, unk2, 1, id);
+ break;
+ case 40:
+ drawLine(x1, y1, x, unk1, unk2, 3, id);
+ break;
+ default:
+ error("o100_drawLine: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_drawObject() {
+ int state, y, x;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 6:
+ state = 1;
+ y = pop();
+ x = pop();
+ break;
+ case 7:
+ state = pop();
+ y = pop();
+ x = pop();
+ break;
+ case 40:
+ state = pop();
+ if (state == 0)
+ state = 1;
+ y = x = -100;
+ break;
+ default:
+ error("o100_drawObject: default case %d", subOp);
+ }
+
+ int object = pop();
+ int objnum = getObjectIndex(object);
+ if (objnum == -1)
+ return;
+
+ if (y != -100 && x != -100) {
+ _objs[objnum].x_pos = x * 8;
+ _objs[objnum].y_pos = y * 8;
+ }
+
+ if (state != -1) {
+ addObjectToDrawQue(objnum);
+ putState(object, state);
+ }
+}
+
+void ScummEngine_v100he::o100_floodFill() {
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ memset(&_floodFillParams, 0, sizeof(_floodFillParams));
+ _floodFillParams.box.left = 0;
+ _floodFillParams.box.top = 0;
+ _floodFillParams.box.right = 639;
+ _floodFillParams.box.bottom = 479;
+ break;
+ case 6:
+ _floodFillParams.y = pop();
+ _floodFillParams.x = pop();
+ break;
+ case 18:
+ _floodFillParams.box.bottom = pop();
+ _floodFillParams.box.right = pop();
+ _floodFillParams.box.top = pop();
+ _floodFillParams.box.left = pop();
+ break;
+ case 20:
+ _floodFillParams.flags = pop();
+ break;
+ case 67:
+ pop();
+ break;
+ case 92:
+ floodFill(&_floodFillParams, this);
+ break;
+ default:
+ error("o100_floodFill: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_setSpriteGroupInfo() {
+ byte string[260];
+ int type, value1, value2, value3, value4;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ _curSpriteGroupId = pop();
+ break;
+ case 6:
+ value2 = pop();
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupPosition(_curSpriteGroupId, value1, value2);
+ break;
+ case 18:
+ value4 = pop();
+ value3 = pop();
+ value2 = pop();
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupBounds(_curSpriteGroupId, value1, value2, value3, value4);
+ break;
+ case 38:
+ type = pop() - 1;
+ switch (type) {
+ case 0:
+ value2 = pop();
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->moveGroupMembers(_curSpriteGroupId, value1, value2);
+ break;
+ case 1:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersPriority(_curSpriteGroupId, value1);
+ break;
+ case 2:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersGroup(_curSpriteGroupId, value1);
+ break;
+ case 3:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersUpdateType(_curSpriteGroupId, value1);
+ break;
+ case 4:
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersResetSprite(_curSpriteGroupId);
+ break;
+ case 5:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersAnimationSpeed(_curSpriteGroupId, value1);
+ break;
+ case 6:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersAutoAnimFlag(_curSpriteGroupId, value1);
+ break;
+ case 7:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupMembersShadow(_curSpriteGroupId, value1);
+ break;
+ default:
+ error("o100_setSpriteGroupInfo subOp 38: Unknown case %d", subOp);
+ }
+ break;
+ case 40:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupImage(_curSpriteGroupId, value1);
+ break;
+ case 49:
+ value2 = pop();
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->moveGroup(_curSpriteGroupId, value1, value2);
+ break;
+ case 52:
+ copyScriptString(string, sizeof(string));
+ break;
+ case 53:
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->resetGroup(_curSpriteGroupId);
+ break;
+ case 54:
+ // dummy case
+ pop();
+ pop();
+ break;
+ case 59:
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->setGroupPriority(_curSpriteGroupId, value1);
+ break;
+ case 60:
+ type = pop();
+ value1 = pop();
+ if (!_curSpriteGroupId)
+ break;
+
+ switch (type) {
+ case 0:
+ _sprite->setGroupXMul(_curSpriteGroupId, value1);
+ break;
+ case 1:
+ _sprite->setGroupXDiv(_curSpriteGroupId, value1);
+ break;
+ case 2:
+ _sprite->setGroupYMul(_curSpriteGroupId, value1);
+ break;
+ case 3:
+ _sprite->setGroupYDiv(_curSpriteGroupId, value1);
+ break;
+ default:
+ error("o100_setSpriteGroupInfo subOp 60: Unknown case %d", subOp);
+ }
+ break;
+ case 89:
+ if (!_curSpriteGroupId)
+ break;
+
+ _sprite->resetGroupBounds(_curSpriteGroupId);
+ break;
+ default:
+ error("o100_setSpriteGroupInfo: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_resourceRoutines() {
+ int objidx, room;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 14:
+ _heResType = rtCharset;
+ _heResId = pop();
+ break;
+ case 25:
+ _heResType = rtCostume;
+ _heResId = pop();
+ break;
+ case 34:
+ _heResType = rtFlObject;
+ _heResId = pop();
+ break;
+ case 40:
+ _heResType = rtImage;
+ _heResId = pop();
+ break;
+ case 47:
+ if (_heResType == rtFlObject) {
+ room = getObjectRoom(_heResId);
+ loadFlObject(_heResId, room);
+ } else if (_heResType == rtCharset) {
+ loadCharset(_heResId);
+ } else {
+ ensureResourceLoaded(_heResType, _heResId);
+ }
+ break;
+ case 62:
+ _heResType = rtRoom;
+ _heResId = pop();
+ break;
+ case 66:
+ _heResType = rtScript;
+ _heResId = pop();
+ break;
+ case 72:
+ _heResType = rtSound;
+ _heResId = pop();
+ break;
+ case 128:
+ break;
+ case 132:
+ if (_heResType == rtScript && _heResId >= _numGlobalScripts)
+ break;
+
+ if (_heResType == rtFlObject) {
+ objidx = getObjectIndex(_heResId);
+ if (objidx == -1)
+ break;
+ res.lock(rtFlObject, _objs[objidx].fl_object_index);
+ } else {
+ res.lock(_heResType, _heResId);
+ }
+ break;
+ case 133:
+ if (_heResType == rtCharset)
+ nukeCharset(_heResId);
+ else
+ res.nukeResource(_heResType, _heResId);
+ break;
+ case 134:
+ case 135:
+ // Heap related
+ break;
+ case 136:
+ if (_heResType == rtScript && _heResId >= _numGlobalScripts)
+ break;
+
+ //queueLoadResource(_heResType, _heResId);
+ break;
+ case 137:
+ if (_heResType == rtScript && _heResId >= _numGlobalScripts)
+ break;
+
+ if (_heResType == rtFlObject) {
+ objidx = getObjectIndex(_heResId);
+ if (objidx == -1)
+ break;
+ res.unlock(rtFlObject, _objs[objidx].fl_object_index);
+ } else {
+ res.unlock(_heResType, _heResId);
+ }
+ break;
+ default:
+ error("o100_resourceRoutines: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_wizImageOps() {
+ int a, b;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ _wizParams.img.resNum = pop();
+ _wizParams.processMode = 0;
+ _wizParams.processFlags = 0;
+ _wizParams.remapNum = 0;
+ _wizParams.img.flags = 0;
+ _wizParams.field_184 = 0;
+ _wizParams.field_180 = 0;
+ _wizParams.spriteId = 0;
+ _wizParams.spriteGroup = 0;
+ break;
+ case 2:
+ _wizParams.processFlags |= kWPFRotate;
+ _wizParams.angle = pop();
+ break;
+ case 6:
+ case 132:
+ _wizParams.processFlags |= kWPFSetPos;
+ _wizParams.img.y1 = pop();
+ _wizParams.img.x1 = pop();
+ break;
+ case 7:
+ _wizParams.processFlags |= kWPFMaskImg;
+ _wizParams.sourceImage = pop();
+ break;
+ case 11:
+ _wizParams.processFlags |= kWPFClipBox | 0x100;
+ _wizParams.processMode = 2;
+ _wizParams.box.bottom = pop();
+ _wizParams.box.right = pop();
+ _wizParams.box.top = pop();
+ _wizParams.box.left = pop();
+ _wizParams.compType = pop();
+ break;
+ case 18:
+ _wizParams.processFlags |= kWPFClipBox;
+ _wizParams.box.bottom = pop();
+ _wizParams.box.right = pop();
+ _wizParams.box.top = pop();
+ _wizParams.box.left = pop();
+ break;
+ case 21:
+ b = pop();
+ a = pop();
+ _wizParams.processFlags |= kWPFRemapPalette;
+ _wizParams.processMode = 6;
+ if (_wizParams.remapNum == 0) {
+ memset(_wizParams.remapIndex, 0, sizeof(_wizParams.remapIndex));
+ } else {
+ assert(_wizParams.remapNum < ARRAYSIZE(_wizParams.remapIndex));
+ _wizParams.remapIndex[_wizParams.remapNum] = a;
+ _wizParams.remapColor[a] = b;
+ ++_wizParams.remapNum;
+ }
+ break;
+ case 29:
+ _wizParams.processMode = 1;
+ break;
+ case 36:
+ _wizParams.box.bottom = pop();
+ _wizParams.box.right = pop();
+ _wizParams.box.top = pop();
+ _wizParams.box.left = pop();
+ break;
+ case 37:
+ // Dummy case
+ pop();
+ break;
+ case 39:
+ _wizParams.processFlags |= kWPFUseDefImgHeight;
+ _wizParams.resDefImgH = pop();
+ break;
+ case 47:
+ _wizParams.processFlags |= kWPFUseFile;
+ _wizParams.processMode = 3;
+ copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
+ break;
+ case 53:
+ _wizParams.processMode = 8;
+ break;
+ case 54:
+ _wizParams.processFlags |= 0x100000;
+ _wizParams.field_180 = pop();
+ _wizParams.field_184 = pop();
+ break;
+ case 55:
+ _wizParams.img.flags = pop();
+ _wizParams.img.state = pop();
+ _wizParams.img.y1 = pop();
+ _wizParams.img.x1 = pop();
+ _wizParams.spriteId = 0;
+ _wizParams.spriteGroup = 0;
+ _wizParams.img.resNum = pop();
+ _wiz->displayWizImage(&_wizParams.img);
+ break;
+ case 57:
+ _wizParams.processFlags |= kWPFPaletteNum;
+ _wizParams.img.palette = pop();
+ break;
+ case 58:
+ _wizParams.processFlags |= 0x1000 | 0x100 | 0x2;
+ _wizParams.processMode = 7;
+ _wizParams.field_168 = pop();
+ _wizParams.field_164 = pop();
+ _wizParams.compType = pop();
+ break;
+ case 64:
+ _wizParams.processFlags |= kWPFUseFile;
+ _wizParams.processMode = 4;
+ copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
+ _wizParams.fileWriteMode = pop();
+ break;
+ case 65:
+ _wizParams.processFlags |= kWPFScaled;
+ _wizParams.scale = pop();
+ break;
+ case 67:
+ _wizParams.processFlags |= kWPFNewFlags;
+ _wizParams.img.flags |= pop();
+ break;
+ case 68:
+ _wizParams.processFlags |= kWPFNewFlags | kWPFSetPos | 2;
+ _wizParams.img.flags |= kWIFIsPolygon;
+ _wizParams.field_164 = _wizParams.img.y1 = _wizParams.img.x1 = pop();
+ break;
+ case 70:
+ _wizParams.processFlags |= kWPFShadow;
+ _wizParams.img.shadow = pop();
+ break;
+ case 73:
+ _wizParams.processFlags |= kWPFNewState;
+ _wizParams.img.state = pop();
+ break;
+ case 84:
+ _wizParams.processFlags |= kWPFUseDefImgWidth;
+ _wizParams.resDefImgW = pop();
+ break;
+ case 92:
+ if (_wizParams.img.resNum)
+ _wiz->processWizImage(&_wizParams);
+ break;
+ case 128:
+ _wizParams.field_239D = pop();
+ _wizParams.field_2399 = pop();
+ _wizParams.field_23A5 = pop();
+ _wizParams.field_23A1 = pop();
+ copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
+ _wizParams.processMode = 15;
+ break;
+ case 129:
+ _wizParams.processMode = 14;
+ break;
+ case 130:
+ _wizParams.processMode = 16;
+ _wizParams.field_23AD = pop();
+ _wizParams.field_23A9 = pop();
+ copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
+ break;
+ case 131:
+ _wizParams.processMode = 13;
+ break;
+ case 133:
+ _wizParams.processMode = 17;
+ _wizParams.field_23CD = pop();
+ _wizParams.field_23C9 = pop();
+ _wizParams.field_23C5 = pop();
+ _wizParams.field_23C1 = pop();
+ _wizParams.field_23BD = pop();
+ _wizParams.field_23B9 = pop();
+ _wizParams.field_23B5 = pop();
+ _wizParams.field_23B1 = pop();
+ break;
+ case 134:
+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
+ _wizParams.processMode = 12;
+ _wizParams.fillColor = pop();
+ _wizParams.box2.top = _wizParams.box2.bottom = pop();
+ _wizParams.box2.left = _wizParams.box2.right = pop();
+ break;
+ case 135:
+ _wizParams.processFlags |= kWPFDstResNum;
+ _wizParams.dstResNum = pop();
+ break;
+ case 136:
+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
+ _wizParams.processMode = 10;
+ _wizParams.fillColor = pop();
+ _wizParams.box2.bottom = pop();
+ _wizParams.box2.right = pop();
+ _wizParams.box2.top = pop();
+ _wizParams.box2.left = pop();
+ break;
+ case 137:
+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
+ _wizParams.processMode = 11;
+ _wizParams.fillColor = pop();
+ _wizParams.box2.top = _wizParams.box2.bottom = pop();
+ _wizParams.box2.left = _wizParams.box2.right = pop();
+ break;
+ case 138:
+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
+ _wizParams.processMode = 9;
+ _wizParams.fillColor = pop();
+ _wizParams.box2.bottom = pop();
+ _wizParams.box2.right = pop();
+ _wizParams.box2.top = pop();
+ _wizParams.box2.left = pop();
+ break;
+ default:
+ error("o100_wizImageOps: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_dim2dim2Array() {
+ int data, dim1start, dim1end, dim2start, dim2end;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 41: // SO_BIT_ARRAY
+ data = kBitArray;
+ break;
+ case 42: // SO_INT_ARRAY
+ data = kIntArray;
+ break;
+ case 43:
+ data = kDwordArray;
+ break;
+ case 44: // SO_NIBBLE_ARRAY
+ data = kNibbleArray;
+ break;
+ case 45: // SO_BYTE_ARRAY
+ data = kByteArray;
+ break;
+ case 77: // SO_STRING_ARRAY
+ data = kStringArray;
+ break;
+ default:
+ error("o100_dim2dim2Array: default case %d", subOp);
+ }
+
+ if (pop() == 2) {
+ dim1end = pop();
+ dim1start = pop();
+ dim2end = pop();
+ dim2start = pop();
+ } else {
+ dim2end = pop();
+ dim2start = pop();
+ dim1end = pop();
+ dim1start = pop();
+ }
+
+ defineArray(fetchScriptWord(), data, dim2start, dim2end, dim1start, dim1end);
+}
+
+void ScummEngine_v100he::o100_redim2dimArray() {
+ int a, b, c, d;
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 42:
+ redimArray(fetchScriptWord(), a, b, c, d, kIntArray);
+ break;
+ case 43:
+ redimArray(fetchScriptWord(), a, b, c, d, kDwordArray);
+ break;
+ case 45:
+ redimArray(fetchScriptWord(), a, b, c, d, kByteArray);
+ break;
+ default:
+ error("o100_redim2dimArray: default type %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_paletteOps() {
+ int a, b, c, d, e;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ _hePaletteNum = pop();
+ break;
+ case 20:
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ if (_hePaletteNum != 0) {
+ for (; a <= b; ++a) {
+ setHEPaletteColor(_hePaletteNum, a, c, d, e);
+ }
+ }
+ break;
+ case 25:
+ a = pop();
+ if (_hePaletteNum != 0) {
+ setHEPaletteFromCostume(_hePaletteNum, a);
+ }
+ break;
+ case 40:
+ b = pop();
+ a = pop();
+ if (_hePaletteNum != 0) {
+ setHEPaletteFromImage(_hePaletteNum, a, b);
+ }
+ break;
+ case 53:
+ if (_hePaletteNum != 0) {
+ restoreHEPalette(_hePaletteNum);
+ }
+ break;
+ case 57:
+ a = pop();
+ if (_hePaletteNum != 0) {
+ copyHEPalette(_hePaletteNum, a);
+ }
+ break;
+ case 63:
+ b = pop();
+ a = pop();
+ if (_hePaletteNum != 0) {
+ setHEPaletteFromRoom(_hePaletteNum, a, b);
+ }
+ break;
+ case 81:
+ c = pop();
+ b = pop();
+ a = pop();
+ if (_hePaletteNum) {
+ for (; a <= b; ++a) {
+ copyHEPaletteColor(_hePaletteNum, a, c);
+ }
+ }
+ break;
+ case 92:
+ _hePaletteNum = 0;
+ break;
+ default:
+ error("o100_paletteOps: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_jumpToScriptUnk() {
+ int args[25];
+ int script, cycle;
+ byte flags;
+
+ getStackList(args, ARRAYSIZE(args));
+ cycle = pop();
+ script = pop();
+ flags = fetchScriptByte();
+ stopObjectCode();
+ runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args, cycle);
+}
+
+void ScummEngine_v100he::o100_startScriptUnk() {
+ int args[25];
+ int script, cycle;
+ byte flags;
+
+ getStackList(args, ARRAYSIZE(args));
+ cycle = pop();
+ script = pop();
+ flags = fetchScriptByte();
+ runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args, cycle);
+}
+
+void ScummEngine_v100he::o100_redimArray() {
+ int newX, newY;
+ newY = pop();
+ newX = pop();
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 42:
+ redimArray(fetchScriptWord(), 0, newX, 0, newY, kIntArray);
+ break;
+ case 43:
+ redimArray(fetchScriptWord(), 0, newX, 0, newY, kDwordArray);
+ break;
+ case 45:
+ redimArray(fetchScriptWord(), 0, newX, 0, newY, kByteArray);
+ break;
+ default:
+ error("o100_redimArray: default type %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_roomOps() {
+ int a, b, c, d, e;
+ byte filename[100];
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 63: // SO_ROOM_PALETTE
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ setPalColor(d, a, b, c);
+ break;
+
+ case 129:
+ b = pop();
+ a = pop();
+ swapObjects(a, b);
+ break;
+
+ case 130:
+ a = pop();
+ b = pop();
+ copyPalColor(a, b);
+ break;
+
+ case 131: // SO_ROOM_FADE
+ // Defaults to 1 but doesn't use fade effects
+ a = pop();
+ break;
+
+ case 132: // SO_ROOM_INTENSITY
+ c = pop();
+ b = pop();
+ a = pop();
+ darkenPalette(a, a, a, b, c);
+ break;
+
+ case 133: // SO_RGB_ROOM_INTENSITY
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ darkenPalette(a, b, c, d, e);
+ break;
+
+ case 134: // SO_ROOM_NEW_PALETTE
+ a = pop();
+ setPalette(a);
+ break;
+
+ case 135:
+ b = pop();
+ a = pop();
+ setRoomPalette(a, b);
+ break;
+
+ case 136: // SO_ROOM_SAVEGAME
+ _saveTemporaryState = true;
+ _saveLoadSlot = pop();
+ _saveLoadFlag = pop();
+ break;
+
+ case 137:
+ copyScriptString(filename, sizeof(filename));
+ _saveLoadFlag = pop();
+ _saveLoadSlot = 1;
+ _saveTemporaryState = true;
+ break;
+
+ case 138: // SO_ROOM_SCREEN
+ b = pop();
+ a = pop();
+ initScreens(a, _screenHeight);
+ break;
+
+ case 139: // SO_ROOM_SCROLL
+ b = pop();
+ a = pop();
+ if (a < (_screenWidth / 2))
+ a = (_screenWidth / 2);
+ if (b < (_screenWidth / 2))
+ b = (_screenWidth / 2);
+ if (a > _roomWidth - (_screenWidth / 2))
+ a = _roomWidth - (_screenWidth / 2);
+ if (b > _roomWidth - (_screenWidth / 2))
+ b = _roomWidth - (_screenWidth / 2);
+ VAR(VAR_CAMERA_MIN_X) = a;
+ VAR(VAR_CAMERA_MAX_X) = b;
+ break;
+
+ default:
+ error("o100_roomOps: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_startSound() {
+ byte filename[260];
+ int var, value;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 6:
+ _heSndFlags |= 16;
+ _heSndOffset = pop();
+ break;
+ case 47:
+ copyScriptString(filename, sizeof(filename));
+ _heSndSoundId = pop();
+ if (_heSndSoundId)
+ debug(0, "Load sound %d from file %s\n", _heSndSoundId, filename);
+ break;
+ case 55:
+ _heSndFlags |= 8;
+ break;
+ case 83:
+ value = pop();
+ var = pop();
+ _heSndSoundId = pop();
+ _sound->setSoundVar(_heSndSoundId, var, value);
+ break;
+ case 92:
+ _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags);
+ break;
+ case 128:
+ _heSndFlags |= 2;
+ break;
+ case 129:
+ _heSndChannel = pop();
+ break;
+ case 130:
+ _heSndFlags |= 64;
+ pop();
+ break;
+ case 131:
+ _heSndFlags |= 1;
+ break;
+ case 132: // Music
+ case 134: // Sound
+ _heSndSoundId = pop();
+ _heSndOffset = 0;
+ _heSndSoundFreq = 11025;
+ _heSndChannel = VAR(VAR_SOUND_CHANNEL);
+ _heSndFlags = 0;
+ break;
+ case 133:
+ _heSndFlags |= 128;
+ pop();
+ break;
+ case 135:
+ _heSndFlags |= 4;
+ break;
+ case 136:
+ _heSndFlags |= 32;
+ pop();
+ break;
+ default:
+ error("o100_startSound invalid case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_setSpriteInfo() {
+ int args[16];
+ int spriteId, n;
+ int32 tmp[2];
+ byte string[80];
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ _curMaxSpriteId = pop();
+ _curSpriteId = pop();
+
+ if (_curSpriteId > _curMaxSpriteId)
+ SWAP(_curSpriteId, _curMaxSpriteId);
+ break;
+ case 2:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteAngle(spriteId, args[0]);
+ break;
+ case 3:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteFlagAutoAnim(spriteId, args[0]);
+ break;
+ case 4:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteAnimSpeed(spriteId, args[0]);
+ break;
+ case 6:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpritePosition(spriteId, args[0], args[1]);
+ break;
+ case 7:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteSourceImage(spriteId, args[0]);
+ break;
+ case 16:
+ n = getStackList(args, ARRAYSIZE(args));
+ if (_curSpriteId != 0 && _curMaxSpriteId != 0 && n != 0) {
+ int *p = &args[n - 1];
+ do {
+ int code = *p;
+ if (code == 0) {
+ for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
+ _sprite->setSpriteResetClass(i);
+ }
+ } else if (code & 0x80) {
+ for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
+ _sprite->setSpriteSetClass(i, code & 0x7F, 1);
+ }
+ } else {
+ for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
+ _sprite->setSpriteSetClass(i, code & 0x7F, 0);
+ }
+ }
+ --p;
+ } while (--n);
+ }
+ break;
+ case 32:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteFlagEraseType(spriteId, args[0]);
+ break;
+ case 38:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteGroup(spriteId, args[0]);
+ break;
+ case 40:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteImage(spriteId, args[0]);
+ break;
+ case 48:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteMaskImage(spriteId, args[0]);
+ break;
+ case 49:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->moveSprite(spriteId, args[0], args[1]);
+ break;
+ case 52:
+ copyScriptString(string, sizeof(string));
+ break;
+ case 53:
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->resetSprite(spriteId);
+ break;
+ case 54:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteGeneralProperty(spriteId, args[0], args[1]);
+ break;
+ case 57:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpritePalette(spriteId, args[0]);
+ break;
+ case 59:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpritePriority(spriteId, args[0]);
+ break;
+ case 60:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ switch(args[1]) {
+ case 0:
+ _sprite->setSpriteFlagXFlipped(spriteId, args[0]);
+ break;
+ case 1:
+ _sprite->setSpriteFlagYFlipped(spriteId, args[0]);
+ break;
+ case 2:
+ _sprite->setSpriteFlagActive(spriteId, args[0]);
+ break;
+ case 3:
+ _sprite->setSpriteFlagDoubleBuffered(spriteId, args[0]);
+ break;
+ case 4:
+ _sprite->setSpriteFlagRemapPalette(spriteId, args[0]);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 61:
+ _sprite->resetTables(true);
+ break;
+ case 65:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteScale(spriteId, args[0]);
+ break;
+ case 70:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteShadow(spriteId, args[0]);
+ break;
+ case 73:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteImageState(spriteId, args[0]);
+ break;
+ case 74:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteDist(spriteId, args[0], args[1]);
+ break;
+ case 75:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++) {
+ _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
+ _sprite->setSpriteDist(spriteId, args[0], tmp[1]);
+ }
+ break;
+ case 76:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++) {
+ _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
+ _sprite->setSpriteDist(spriteId, tmp[0], args[0]);
+ }
+ break;
+ case 82:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteFlagUpdateType(spriteId, args[0]);
+ break;
+ case 83:
+ args[1] = pop();
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteUserValue(spriteId, args[0], args[1]);
+ break;
+ case 88:
+ args[0] = pop();
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteField84(spriteId, args[0]);
+ break;
+ case 89:
+ if (_curSpriteId > _curMaxSpriteId)
+ break;
+ spriteId = _curSpriteId;
+ if (!spriteId)
+ spriteId++;
+
+ for (; spriteId <= _curMaxSpriteId; spriteId++)
+ _sprite->setSpriteField84(spriteId, 0);
+ break;
+ default:
+ error("o100_setSpriteInfo: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_startScript() {
+ int args[25];
+ int script;
+ byte flags;
+
+ getStackList(args, ARRAYSIZE(args));
+ script = pop();
+ flags = fetchScriptByte();
+ runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args);
+}
+
+void ScummEngine_v100he::o100_systemOps() {
+ byte string[1024];
+
+ byte subOp = fetchScriptByte();
+ subOp -= 61;
+
+ switch (subOp) {
+ case 0:
+ restart();
+ break;
+ case 67:
+ clearDrawObjectQueue();
+ break;
+ case 71:
+ // Confirm shutdown
+ shutDown();
+ break;
+ case 72:
+ shutDown();
+ break;
+ case 73:
+ copyScriptString(string, sizeof(string));
+ debug(0, "Start game (%s)", string);
+ break;
+ case 74:
+ copyScriptString(string, sizeof(string));
+ debug(0, "Start executable (%s)", string);
+ break;
+ case 75:
+ gdi.copyVirtScreenBuffers(Common::Rect(_screenWidth, _screenHeight));
+ updatePalette();
+ break;
+ default:
+ error("o100_systemOps invalid case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_cursorCommand() {
+ int a, i;
+ int args[16];
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0xE: // SO_CHARSET_SET
+ initCharset(pop());
+ break;
+ case 0xF: // SO_CHARSET_COLOR
+ getStackList(args, ARRAYSIZE(args));
+ for (i = 0; i < 16; i++)
+ _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
+ break;
+ case 0x80:
+ case 0x81:
+ a = pop();
+ _wiz->loadWizCursor(a);
+ break;
+ case 0x82:
+ pop();
+ a = pop();
+ _wiz->loadWizCursor(a);
+ break;
+ case 0x86: // SO_CURSOR_ON Turn cursor on
+ _cursor.state = 1;
+ break;
+ case 0x87: // SO_CURSOR_OFF Turn cursor off
+ _cursor.state = 0;
+ break;
+ case 0x88: // SO_CURSOR_SOFT_ON Turn soft cursor on
+ _cursor.state++;
+ if (_cursor.state > 1)
+ error("o100_cursorCommand: Cursor state greater than 1 in script");
+ break;
+
+ case 0x89: // SO_CURSOR_SOFT_OFF Turn soft cursor off
+ _cursor.state--;
+ break;
+ case 0x8B: // SO_USERPUT_ON
+ _userPut = 1;
+ break;
+ case 0x8C: // SO_USERPUT_OFF
+ _userPut = 0;
+ break;
+ case 0x8D: // SO_USERPUT_SOFT_ON
+ _userPut++;
+ break;
+ case 0x8E: // SO_USERPUT_SOFT_OFF
+ _userPut--;
+ break;
+ default:
+ error("o100_cursorCommand: default case %x", subOp);
+ }
+
+ VAR(VAR_CURSORSTATE) = _cursor.state;
+ VAR(VAR_USERPUT) = _userPut;
+}
+
+void ScummEngine_v100he::o100_videoOps() {
+ // Uses Bink video
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ memset(_videoParams.filename, 0, sizeof(_videoParams.filename));
+ _videoParams.unk2 = pop();
+ break;
+ case 19:
+ _videoParams.status = 19;
+ break;
+ case 40:
+ _videoParams.wizResNum = pop();
+ if (_videoParams.wizResNum)
+ _videoParams.flags |= 2;
+ break;
+ case 47:
+ copyScriptString(_videoParams.filename, sizeof(_videoParams.filename));
+ _videoParams.status = 47;
+ break;
+ case 67:
+ _videoParams.flags |= pop();
+ break;
+ case 92:
+ if (_videoParams.status == 47) {
+ // Start video
+ if (_videoParams.flags == 0)
+ _videoParams.flags = 4;
+
+ if (_videoParams.flags == 2) {
+ // result = startVideo(_videoParams.filename, _videoParams.flags, _videoParams.wizResNum);
+ // VAR(119) = result;
+ } else {
+ // result = startVideo(_videoParams.filename, _videoParams.flags);
+ // VAR(119) = result;
+ }
+ } else if (_videoParams.status == 19) {
+ // Stop video
+ }
+ break;
+ default:
+ error("o100_videoOps: unhandled case %d", subOp);
+ }
+
+ debug(1,"o100_videoOps stub (%d)", subOp);
+}
+
+void ScummEngine_v100he::o100_wait() {
+ int actnum;
+ int offs = -2;
+ Actor *a;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 128: // SO_WAIT_FOR_ACTOR Wait for actor
+ offs = fetchScriptWordSigned();
+ actnum = pop();
+ a = derefActor(actnum, "o100_wait:168");
+ if (a->_moving)
+ break;
+ return;
+ case 129: // SO_WAIT_FOR_CAMERA Wait for camera
+ if (camera._cur.x / 8 != camera._dest.x / 8)
+ break;
+ return;
+ case 130: // SO_WAIT_FOR_MESSAGE Wait for message
+ if (VAR(VAR_HAVE_MSG))
+ break;
+ return;
+ case 131: // SO_WAIT_FOR_SENTENCE
+ if (_sentenceNum) {
+ if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
+ return;
+ break;
+ }
+ if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
+ return;
+ break;
+ default:
+ error("o100_wait: default case 0x%x", subOp);
+ }
+
+ _scriptPointer += offs;
+ o6_breakHere();
+}
+
+void ScummEngine_v100he::o100_writeFile() {
+ int32 resID = pop();
+ int slot = pop();
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 5:
+ fetchScriptByte();
+ writeFileFromArray(slot, resID);
+ break;
+ case 42:
+ _hFileTable[slot].writeUint16LE(resID);
+ break;
+ case 43:
+ _hFileTable[slot].writeUint32LE(resID);
+ break;
+ case 45:
+ _hFileTable[slot].writeByte(resID);
+ break;
+ default:
+ error("o100_writeFile: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_isResourceLoaded() {
+ // Reports percentage of resource loaded by queue
+ int type;
+
+ byte subOp = fetchScriptByte();
+ /* int idx = */ pop();
+
+ switch (subOp) {
+ case 25:
+ type = rtCostume;
+ break;
+ case 40:
+ type = rtImage;
+ break;
+ case 62:
+ type = rtRoom;
+ break;
+ case 66:
+ type = rtScript;
+ break;
+ case 72:
+ type = rtSound;
+ break;
+ default:
+ error("o100_isResourceLoaded: default case %d", subOp);
+ }
+
+ push(100);
+}
+
+void ScummEngine_v100he::o100_getResourceSize() {
+ const byte *ptr;
+ int size, type;
+
+ int resid = pop();
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 25:
+ type = rtCostume;
+ break;
+ case 40:
+ type = rtImage;
+ break;
+ case 62:
+ type = rtRoomImage;
+ break;
+ case 66:
+ type = rtScript;
+ break;
+ case 72:
+ push (getSoundResourceSize(resid));
+ return;
+ default:
+ error("o100_getResourceSize: default type %d", subOp);
+ }
+
+ ptr = getResourceAddress(type, resid);
+ assert(ptr);
+ size = READ_BE_UINT32(ptr + 4) - 8;
+ push(size);
+}
+
+void ScummEngine_v100he::o100_getSpriteGroupInfo() {
+ int32 tx, ty;
+ int spriteGroupId, type;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 5:
+ spriteGroupId = pop();
+ if (spriteGroupId)
+ push(getGroupSpriteArray(spriteGroupId));
+ else
+ push(0);
+ break;
+ case 40:
+ spriteGroupId = pop();
+ if (spriteGroupId)
+ push(_sprite->getGroupDstResNum(spriteGroupId));
+ else
+ push(0);
+ break;
+ case 54:
+ // TODO: U32 related
+ pop();
+ pop();
+ push(0);
+ break;
+ case 59:
+ spriteGroupId = pop();
+ if (spriteGroupId)
+ push(_sprite->getGroupPriority(spriteGroupId));
+ else
+ push(0);
+ break;
+ case 60:
+ type = pop();
+ spriteGroupId = pop();
+ if (spriteGroupId) {
+ switch(type) {
+ case 0:
+ push(_sprite->getGroupXMul(spriteGroupId));
+ break;
+ case 1:
+ push(_sprite->getGroupXDiv(spriteGroupId));
+ break;
+ case 2:
+ push(_sprite->getGroupYMul(spriteGroupId));
+ break;
+ case 3:
+ push(_sprite->getGroupYDiv(spriteGroupId));
+ break;
+ default:
+ push(0);
+ }
+ } else {
+ push(0);
+ }
+ break;
+ case 85:
+ spriteGroupId = pop();
+ if (spriteGroupId) {
+ _sprite->getGroupPosition(spriteGroupId, tx, ty);
+ push(tx);
+ } else {
+ push(0);
+ }
+ break;
+ case 86:
+ spriteGroupId = pop();
+ if (spriteGroupId) {
+ _sprite->getGroupPosition(spriteGroupId, tx, ty);
+ push(ty);
+ } else {
+ push(0);
+ }
+ break;
+ default:
+ error("o100_getSpriteGroupInfo: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_getWizData() {
+ byte filename[4096];
+ int resId, state, type;
+ int32 w, h;
+ int32 x, y;
+
+ byte subOp = fetchScriptByte();
+ subOp -= 20;
+
+ switch (subOp) {
+ case 0:
+ y = pop();
+ x = pop();
+ state = pop();
+ resId = pop();
+ push(_wiz->getWizPixelColor(resId, state, x, y, 0));
+ break;
+ case 6:
+ resId = pop();
+ push(_wiz->getWizImageStates(resId));
+ break;
+ case 13:
+ y = pop();
+ x = pop();
+ state = pop();
+ resId = pop();
+ push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0));
+ break;
+ case 19:
+ state = pop();
+ resId = pop();
+ _wiz->getWizImageDim(resId, state, w, h);
+ push(h);
+ break;
+ case 34:
+ type = pop();
+ state = pop();
+ resId = pop();
+ push(_wiz->getWizImageData(resId, state, type));
+ break;
+ case 64:
+ state = pop();
+ resId = pop();
+ _wiz->getWizImageDim(resId, state, w, h);
+ push(w);
+ break;
+ case 65:
+ state = pop();
+ resId = pop();
+ _wiz->getWizImageSpot(resId, state, x, y);
+ push(x);
+ break;
+ case 66:
+ state = pop();
+ resId = pop();
+ _wiz->getWizImageSpot(resId, state, x, y);
+ push(y);
+ break;
+ case 111:
+ pop();
+ copyScriptString(filename, sizeof(filename));
+ pop();
+ push(0);
+ debug(0, "o100_getWizData() case 111 unhandled");
+ break;
+ case 112:
+ h = pop();
+ w = pop();
+ y = pop();
+ x = pop();
+ state = pop();
+ resId = pop();
+ if (x == -1 && y == -1 && w == -1 && h == -1) {
+ _wiz->getWizImageDim(resId, state, w, h);
+ x = 0;
+ y = 0;
+ }
+ push(computeWizHistogram(resId, state, x, y, w, h));
+ break;
+ default:
+ error("o100_getWizData: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_getPaletteData() {
+ int b, c, d, e;
+ int palSlot, color;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 13:
+ c = pop();
+ b = pop();
+ push(getHEPaletteColorComponent(1, b, c));
+ break;
+ case 20:
+ color = pop();
+ palSlot = pop();
+ push(getHEPaletteColor(palSlot, color));
+ break;
+ case 33:
+ e = pop();
+ d = pop();
+ palSlot = pop();
+ pop();
+ c = pop();
+ b = pop();
+ push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
+ break;
+ case 53:
+ pop();
+ c = pop();
+ c = MAX(0, c);
+ c = MIN(c, 255);
+ b = pop();
+ b = MAX(0, b);
+ b = MIN(b, 255);
+ push(getHEPaletteSimilarColor(1, b, c, 10, 245));
+ break;
+ case 73:
+ c = pop();
+ b = pop();
+ palSlot = pop();
+ push(getHEPaletteColorComponent(palSlot, b, c));
+ break;
+ default:
+ error("o100_getPaletteData: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_readFile() {
+ int slot, val;
+ int32 size;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 5:
+ fetchScriptByte();
+ size = pop();
+ slot = pop();
+ val = readFileToArray(slot, size);
+ push(val);
+ break;
+ case 42:
+ slot = pop();
+ val = _hFileTable[slot].readUint16LE();
+ push(val);
+ break;
+ case 43:
+ slot = pop();
+ val = _hFileTable[slot].readUint32LE();
+ push(val);
+ break;
+ case 45:
+ slot = pop();
+ val = _hFileTable[slot].readByte();
+ push(val);
+ break;
+ default:
+ error("o100_readFile: default case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_getSpriteInfo() {
+ int args[16];
+ int spriteId, flags, groupId, type;
+ int32 x, y;
+
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 3:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteFlagAutoAnim(spriteId));
+ else
+ push(0);
+ break;
+ case 4:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteAnimSpeed(spriteId));
+ else
+ push(1);
+ break;
+ case 7:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteSourceImage(spriteId));
+ else
+ push(0);
+ break;
+ case 16:
+ flags = getStackList(args, ARRAYSIZE(args));
+ spriteId = pop();
+ if (spriteId) {
+ push(_sprite->getSpriteClass(spriteId, flags, args));
+ } else {
+ push(0);
+ }
+ break;
+ case 26:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteImageStateCount(spriteId));
+ else
+ push(0);
+ break;
+ case 30:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteDisplayX(spriteId));
+ else
+ push(0);
+ break;
+ case 31:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteDisplayY(spriteId));
+ else
+ push(0);
+ break;
+ case 32:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteFlagEraseType(spriteId));
+ else
+ push(1);
+ break;
+ case 33:
+ flags = getStackList(args, ARRAYSIZE(args));
+ type = pop();
+ groupId = pop();
+ y = pop();
+ x = pop();
+ push(_sprite->findSpriteWithClassOf(x, y, groupId, type, flags, args));
+ break;
+ case 38:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteGroup(spriteId));
+ else
+ push(0);
+ break;
+ case 39:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpriteImageDim(spriteId, x, y);
+ push(y);
+ } else {
+ push(0);
+ }
+ break;
+ case 40:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteImage(spriteId));
+ else
+ push(0);
+ break;
+ case 48:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteMaskImage(spriteId));
+ else
+ push(0);
+ break;
+ case 54:
+ flags = pop();
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteGeneralProperty(spriteId, flags));
+ else
+ push(0);
+ break;
+ case 57:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpritePalette(spriteId));
+ else
+ push(0);
+ break;
+ case 59:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpritePriority(spriteId));
+ else
+ push(0);
+ break;
+ case 60:
+ flags = pop();
+ spriteId = pop();
+ if (spriteId) {
+ switch(flags) {
+ case 0:
+ push(_sprite->getSpriteFlagXFlipped(spriteId));
+ break;
+ case 1:
+ push(_sprite->getSpriteFlagYFlipped(spriteId));
+ break;
+ case 2:
+ push(_sprite->getSpriteFlagActive(spriteId));
+ break;
+ case 3:
+ push(_sprite->getSpriteFlagDoubleBuffered(spriteId));
+ break;
+ case 4:
+ push(_sprite->getSpriteFlagRemapPalette(spriteId));
+ break;
+ default:
+ push(0);
+ }
+ } else {
+ push(0);
+ }
+ break;
+ case 65:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteScale(spriteId));
+ else
+ push(0);
+ break;
+ case 70:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteShadow(spriteId));
+ else
+ push(0);
+ break;
+ case 73:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteImageState(spriteId));
+ else
+ push(0);
+ break;
+ case 75:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpriteDist(spriteId, x, y);
+ push(x);
+ } else {
+ push(0);
+ }
+ break;
+ case 76:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpriteDist(spriteId, x, y);
+ push(y);
+ } else {
+ push(0);
+ }
+ break;
+ case 82:
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteFlagUpdateType(spriteId));
+ else
+ push(0);
+ break;
+ case 83:
+ pop();
+ spriteId = pop();
+ if (spriteId)
+ push(_sprite->getSpriteUserValue(spriteId));
+ else
+ push(0);
+ break;
+ case 84:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpriteImageDim(spriteId, x, y);
+ push(x);
+ } else {
+ push(0);
+ }
+ break;
+ case 85:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpritePosition(spriteId, x, y);
+ push(x);
+ } else {
+ push(0);
+ }
+ break;
+ case 86:
+ spriteId = pop();
+ if (spriteId) {
+ _sprite->getSpritePosition(spriteId, x, y);
+ push(y);
+ } else {
+ push(0);
+ }
+ break;
+ default:
+ error("o100_getSpriteInfo: Unknown case %d", subOp);
+ }
+}
+
+void ScummEngine_v100he::o100_getVideoData() {
+ // Uses Bink video
+ byte subOp = fetchScriptByte();
+ subOp -= 26;
+
+ switch (subOp) {
+ case 0:
+ pop();
+ break;
+ case 13:
+ pop();
+ break;
+ case 14:
+ pop();
+ break;
+ case 28:
+ pop();
+ pop();
+ break;
+ case 47:
+ pop();
+ break;
+ case 58:
+ pop();
+ break;
+ default:
+ error("o100_getVideoData: unhandled case %d", subOp);
+ }
+
+ push(-1);
+ debug(1,"o100_getVideoData stub (%d)", subOp);
+}
+
+void ScummEngine_v100he::decodeParseString(int m, int n) {
+ Actor *a;
+ int i, colors, size;
+ int args[31];
+ byte name[1024];
+
+ byte b = fetchScriptByte();
+
+ switch (b) {
+ case 6: // SO_AT
+ _string[m].ypos = pop();
+ _string[m].xpos = pop();
+ _string[m].overhead = false;
+ break;
+ case 12: // SO_CENTER
+ _string[m].center = true;
+ _string[m].overhead = false;
+ break;
+ case 18: // SO_CLIPPED
+ _string[m].right = pop();
+ break;
+ case 20: // SO_COLOR
+ _string[m].color = pop();
+ break;
+ case 21:
+ colors = pop();
+ if (colors == 1) {
+ _string[m].color = pop();
+ } else {
+ push(colors);
+ getStackList(args, ARRAYSIZE(args));
+ for (i = 0; i < 16; i++)
+ _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
+ _string[m].color = _charsetColorMap[0];
+ }
+ break;
+ case 35:
+ decodeScriptString(name, true);
+ printString(m, name);
+ break;
+ case 46: // SO_LEFT
+ _string[m].center = false;
+ _string[m].overhead = false;
+ break;
+ case 51: // SO_MUMBLE
+ _string[m].no_talk_anim = true;
+ break;
+ case 56: // SO_OVERHEAD
+ _string[m].overhead = true;
+ _string[m].no_talk_anim = false;
+ break;
+ case 78:
+ {
+ byte *dataPtr = getResourceAddress(rtTalkie, pop());
+ byte *text = findWrappedBlock(MKID('TEXT'), dataPtr, 0, 0);
+ size = getResourceDataSize(text);
+ memcpy(name, text, size);
+ printString(m, name);
+ }
+ break;
+ case 79: // SO_TEXTSTRING
+ printString(m, _scriptPointer);
+ _scriptPointer += resStrLen(_scriptPointer) + 1;
+ break;
+ case 91:
+ _string[m].loadDefault();
+ if (n) {
+ _actorToPrintStrFor = pop();
+ if (_actorToPrintStrFor != 0xFF) {
+ a = derefActor(_actorToPrintStrFor, "decodeParseString");
+ _string[0].color = a->_talkColor;
+ }
+ }
+ break;
+ case 92:
+ _string[m].saveDefault();
+ break;
+ default:
+ error("decodeParseString: default case %d", b);
+ }
+}
+
+} // End of namespace Scumm