[Scummvm-cvs-logs] SF.net SVN: scummvm: [21644] scummvm/trunk/engines/simon

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Thu Apr 6 10:57:03 CEST 2006


Revision: 21644
Author:   eriktorbjorn
Date:     2006-04-06 10:56:41 -0700 (Thu, 06 Apr 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=21644&view=rev

Log Message:
-----------
Split the opcodes into separate functions, and use an array of function
pointers for decoding them, like we do in most other engines. And I just want
to say that this is the second biggest opcode table I've ever seen!

Modified Paths:
--------------
    scummvm/trunk/engines/simon/items.cpp
    scummvm/trunk/engines/simon/simon.cpp
    scummvm/trunk/engines/simon/simon.h
Modified: scummvm/trunk/engines/simon/items.cpp
===================================================================
--- scummvm/trunk/engines/simon/items.cpp	2006-04-06 17:24:26 UTC (rev 21643)
+++ scummvm/trunk/engines/simon/items.cpp	2006-04-06 17:56:41 UTC (rev 21644)
@@ -34,1215 +34,1545 @@
 
 namespace Simon {
 
-int SimonEngine::runScript() {
-	byte opcode;
-	bool flag, condition;
+// Opcode table
+void SimonEngine::setupOpcodes() {
+	// This opcode table is for Simon 1. Changes for Simon 2 and FF are
+	// made below.
 
-	do {
-		if (_continousMainScript)
-			dumpOpcode(_codePtr);
+	static OpcodeProc opcode_table[200] = {
+		// 0 - 4
+		NULL,
+		&SimonEngine::o1_at,
+		&SimonEngine::o1_notAt,
+		NULL,
+		NULL,
+		// 5 - 9
+		&SimonEngine::o1_carried,
+		&SimonEngine::o1_notCarried,
+		&SimonEngine::o1_isAt,
+		NULL,
+		NULL,
+		// 10 - 14
+		NULL,
+		&SimonEngine::o1_zero,
+		&SimonEngine::o1_notZero,
+		&SimonEngine::o1_eq,
+		&SimonEngine::o1_notEq,
+		// 15 - 19
+		&SimonEngine::o1_gt,
+		&SimonEngine::o1_lt,
+		&SimonEngine::o1_eqf,
+		&SimonEngine::o1_notEqf,
+		&SimonEngine::o1_ltf,
+		// 20 - 24
+		&SimonEngine::o1_gtf,
+		NULL,
+		NULL,
+		&SimonEngine::o1_chance,
+		NULL,
+		// 25 - 29
+		&SimonEngine::o1_isRoom,
+		&SimonEngine::o1_isObject,
+		&SimonEngine::o1_state,
+		&SimonEngine::o1_oflag,
+		NULL,
+		// 30 - 34
+		NULL,
+		&SimonEngine::o1_destroy,
+		NULL,
+		&SimonEngine::o1_place,
+		NULL,
+		// 35 - 39
+		NULL,
+		&SimonEngine::o1_copyff,
+		NULL,
+		NULL,
+		NULL,
+		// 40 - 44
+		NULL,
+		&SimonEngine::o1_clear,
+		&SimonEngine::o1_let,
+		&SimonEngine::o1_add,
+		&SimonEngine::o1_sub,
+		// 45 - 49
+		&SimonEngine::o1_addf,
+		&SimonEngine::o1_subf,
+		&SimonEngine::o1_mul,
+		&SimonEngine::o1_div,
+		&SimonEngine::o1_mulf,
+		// 50 - 54
+		&SimonEngine::o1_divf,
+		&SimonEngine::o1_mod,
+		&SimonEngine::o1_modf,
+		&SimonEngine::o1_random,
+		NULL,
+		// 55 - 59
+		&SimonEngine::o1_goto,
+		&SimonEngine::o1_oset,
+		&SimonEngine::o1_oclear,
+		&SimonEngine::o1_putBy,
+		&SimonEngine::o1_inc,
+		// 60 - 64
+		&SimonEngine::o1_dec,
+		&SimonEngine::o1_setState,
+		&SimonEngine::o1_print,
+		&SimonEngine::o1_message,
+		&SimonEngine::o1_msg,
+		// 65 - 69
+		&SimonEngine::o1_addTextBox,
+		&SimonEngine::o1_setShortText,
+		&SimonEngine::o1_setLongText,
+		&SimonEngine::o1_end,
+		&SimonEngine::o1_done,
+		// 70 - 74
+		&SimonEngine::o1_printLongText,
+		&SimonEngine::o1_process,
+		NULL,
+		NULL,
+		NULL,
+		// 75 - 79
+		NULL,
+		&SimonEngine::o1_when,
+		&SimonEngine::o1_if1,
+		&SimonEngine::o1_if2,
+		&SimonEngine::o1_isCalled,
+		// 80 - 84
+		&SimonEngine::o1_is,
+		NULL,
+		&SimonEngine::o1_debug,
+		&SimonEngine::o1_rescan,
+		NULL,
+		// 85 - 89
+		NULL,
+		NULL,
+		&SimonEngine::o1_comment,
+		&SimonEngine::o1_haltAnimation,
+		&SimonEngine::o1_restartAnimation,
+		// 90 - 94
+		&SimonEngine::o1_getParent,
+		&SimonEngine::o1_getNext,
+		&SimonEngine::o1_getChildren,
+		NULL,
+		NULL,
+		// 95 - 99
+		NULL,
+		&SimonEngine::o1_picture,
+		&SimonEngine::o1_loadZone,
+		&SimonEngine::o1_animate,
+		&SimonEngine::o1_stopAnimate,
+		// 100 - 104
+		&SimonEngine::o1_killAnimate,
+		&SimonEngine::o1_defWindow,
+		&SimonEngine::o1_window,
+		&SimonEngine::o1_cls,
+		&SimonEngine::o1_closeWindow,
+		// 105 - 109
+		NULL,
+		NULL,
+		&SimonEngine::o1_addBox,
+		&SimonEngine::o1_delBox,
+		&SimonEngine::o1_enableBox,
+		// 110 - 114
+		&SimonEngine::o1_disableBox,
+		&SimonEngine::o1_moveBox,
+		NULL,
+		NULL,
+		&SimonEngine::o1_doIcons,
+		// 115 - 119
+		&SimonEngine::o1_isClass,
+		&SimonEngine::o1_setClass,
+		&SimonEngine::o1_unsetClass,
+		NULL,
+		&SimonEngine::o1_waitSync,
+		// 120 - 124
+		&SimonEngine::o1_sync,
+		&SimonEngine::o1_defObj,
+		NULL,
+		NULL,
+		NULL,
+		// 125 - 129
+		&SimonEngine::o1_here,
+		&SimonEngine::o1_doClassIcons,
+		&SimonEngine::o1_playTune,
+		&SimonEngine::o1_waitEndTune,
+		&SimonEngine::o1_ifEndTune,
+		// 130 - 134
+		&SimonEngine::o1_setAdjNoun,
+		NULL,
+		&SimonEngine::o1_saveUserGame,
+		&SimonEngine::o1_loadUserGame,
+		&SimonEngine::o1_stopTune,
+		// 135 - 139
+		&SimonEngine::o1_pauseGame,
+		&SimonEngine::o1_copysf,
+		&SimonEngine::o1_restoreIcons,
+		&SimonEngine::o1_freezeZones,
+		&SimonEngine::o1_placeNoIcons,
+		// 140 - 144
+		&SimonEngine::o1_clearTimers,
+		&SimonEngine::o1_setDollar,
+		&SimonEngine::o1_isBox,
+		&SimonEngine::o1_doTable,
+		NULL,
+		// 145 - 149
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		// 150 - 154
+		NULL,
+		&SimonEngine::o1_storeItem,
+		&SimonEngine::o1_getItem,
+		&SimonEngine::o1_bSet,
+		&SimonEngine::o1_bClear,
+		// 155 - 159
+		&SimonEngine::o1_bZero,
+		&SimonEngine::o1_bNotZero,
+		&SimonEngine::o1_getOValue,
+		&SimonEngine::o1_setOValue,
+		NULL,
+		// 160 - 164
+		&SimonEngine::o1_ink,
+		&SimonEngine::o1_screenTextBox,
+		&SimonEngine::o1_screenTextMsg,
+		&SimonEngine::o1_playEffect,
+		&SimonEngine::o1_getDollar2,
+		// 165 - 169
+		&SimonEngine::o1_isAdjNoun,
+		&SimonEngine::o1_b2Set,
+		&SimonEngine::o1_b2Clear,
+		&SimonEngine::o1_b2Zero,
+		&SimonEngine::o1_b2NotZero,
+		// 170 - 174
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		// 175 - 179
+		&SimonEngine::o1_lockZones,
+		&SimonEngine::o1_unlockZones,
+		&SimonEngine::o1_screenTextPObj,
+		&SimonEngine::o1_getPathPosn,
+		&SimonEngine::o1_scnTxtLongText,
+		// 180 - 184
+		&SimonEngine::o1_mouseOn,
+		&SimonEngine::o1_mouseOff,
+		&SimonEngine::o1_loadBeard,
+		&SimonEngine::o1_unloadBeard,
+		&SimonEngine::o1_unloadZone,
+		// 185 - 189
+		&SimonEngine::o1_loadStrings,
+		&SimonEngine::o1_unfreezeZones,
+		&SimonEngine::o1_specialFade,
+		NULL,
+		NULL,
+		// 190 - 194
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		// 195 - 199
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL
+	};
 
-		opcode = getByte();
-		if (opcode == 0xFF)
-			return 0;
+	_opcode_table = opcode_table;
+	_numOpcodes = ARRAYSIZE(opcode_table);
 
-		if (_runScriptReturn1)
-			return 1;
+	switch (getGameType()) {
+	case GType_SIMON1:
+		break;
+	case GType_SIMON2:
+		opcode_table[70] = &SimonEngine::o2_printLongText;
+		opcode_table[83] = &SimonEngine::o2_rescan;
+		opcode_table[98] = &SimonEngine::o2_animate;
+		opcode_table[99] = &SimonEngine::o2_stopAnimate;
+		opcode_table[181] = &SimonEngine::o2_mouseOff;
+		opcode_table[185] = NULL;
+		opcode_table[187] = NULL;
+		opcode_table[188] = &SimonEngine::o2_isShortText;
+		opcode_table[189] = &SimonEngine::o2_clearMarks;
+		opcode_table[190] = &SimonEngine::o2_waitMark;
+		break;
+	case GType_FF:
+		opcode_table[37] = &SimonEngine::o3_jumpOut;
+		opcode_table[70] = &SimonEngine::o3_printLongText;
+		opcode_table[83] = &SimonEngine::o2_rescan;
+		opcode_table[98] = &SimonEngine::o2_animate;
+		opcode_table[99] = &SimonEngine::o2_stopAnimate;
+		opcode_table[122] = &SimonEngine::o3_oracleTextDown;
+		opcode_table[123] = &SimonEngine::o3_oracleTextUp;
+		opcode_table[124] = &SimonEngine::o3_ifTime;
+		opcode_table[131] = &SimonEngine::o3_setTime;
+		opcode_table[133] = &SimonEngine::o3_loadUserGame;
+		opcode_table[134] = &SimonEngine::o3_listSaveGames;
+		opcode_table[135] = &SimonEngine::o3_checkCD;
+		opcode_table[161] = &SimonEngine::o3_screenTextBox;
+		opcode_table[171] = &SimonEngine::o3_hyperLinkOn;
+		opcode_table[172] = &SimonEngine::o3_hyperLinkOff;
+		opcode_table[173] = &SimonEngine::o3_checkPaths;
+		opcode_table[181] = &SimonEngine::o2_mouseOff;
+		opcode_table[182] = &SimonEngine::o3_loadSmack;
+		opcode_table[183] = &SimonEngine::o3_playSmack;
+		opcode_table[185] = NULL;
+		opcode_table[187] = &SimonEngine::o3_centreScroll;
+		opcode_table[188] = &SimonEngine::o2_isShortText;
+		opcode_table[189] = &SimonEngine::o2_clearMarks;
+		opcode_table[190] = &SimonEngine::o2_waitMark;
+		opcode_table[191] = &SimonEngine::o3_resetPVCount;
+		opcode_table[192] = &SimonEngine::o3_setPathValues;
+		opcode_table[193] = &SimonEngine::o3_stopClock;
+		opcode_table[194] = &SimonEngine::o3_restartClock;
+		opcode_table[195] = &SimonEngine::o3_setColour;
+		opcode_table[196] = &SimonEngine::o3_b3Set;
+		opcode_table[197] = &SimonEngine::o3_b3Clear;
+		opcode_table[198] = &SimonEngine::o3_b3Zero;
+		opcode_table[199] = &SimonEngine::o3_b3NotZero;
+		break;
+	default:
+		error("setupOpcodes: Unknown game");
+	}
+}
 
-		/* Invert condition? */
-		flag = false;
-		if (opcode == 0) {
-			flag = true;
-			opcode = getByte();
-			if (opcode == 0xFF)
-				return 0;
-		}
+// -----------------------------------------------------------------------
+// Simon 1 Opcodes
+// -----------------------------------------------------------------------
 
-		condition = true;
+void SimonEngine::o1_at(bool &cond, int &ret) {
+	// 1: ptrA parent is
+	cond = (getItem1Ptr()->parent == getNextItemID());
+}
 
-		switch (opcode) {
-		case 1:{										/* ptrA parent is */
-				condition = (getItem1Ptr()->parent == getNextItemID());
-			}
-			break;
+void SimonEngine::o1_notAt(bool &cond, int &ret) {
+	// 2: ptrA parent is not
+	cond = (getItem1Ptr()->parent != getNextItemID());
+}
 
-		case 2:{										/* ptrA parent is not */
-				condition = (getItem1Ptr()->parent != getNextItemID());
-			}
-			break;
+void SimonEngine::o1_carried(bool &cond, int &ret) {
+	// 5: parent is 1
+	cond = (getNextItemPtr()->parent == getItem1ID());
+}
 
-		case 5:{										/* parent is 1 */
-				condition = (getNextItemPtr()->parent == getItem1ID());
-			}
-			break;
+void SimonEngine::o1_notCarried(bool &cond, int &ret) {
+	// 6: parent isnot 1
+	cond = (getNextItemPtr()->parent != getItem1ID());
+}
 
-		case 6:{										/* parent isnot 1 */
-				condition = (getNextItemPtr()->parent != getItem1ID());
-			}
-			break;
+void SimonEngine::o1_isAt(bool &cond, int &ret) {
+	// 7: parent is
+	Item *item = getNextItemPtr();
+	cond = (item->parent == getNextItemID());
+}
 
-		case 7:{										/* parent is */
-				Item *item = getNextItemPtr();
-				condition = (item->parent == getNextItemID());
-			}
-			break;
+void SimonEngine::o1_zero(bool &cond, int &ret) {
+	// 11: is zero
+	cond = (getNextVarContents() == 0);
+}
 
-		case 11:{									/* is zero */
-				condition = (getNextVarContents() == 0);
-			}
-			break;
+void SimonEngine::o1_notZero(bool &cond, int &ret) {
+	// 12: isnot zero
+	cond = (getNextVarContents() != 0);
+}
 
-		case 12:{									/* isnot zero */
-				condition = (getNextVarContents() != 0);
-			}
-			break;
+void SimonEngine::o1_eq(bool &cond, int &ret) {
+	// 13: equal
+	uint tmp = getNextVarContents();
+	cond = (tmp == getVarOrWord());
+}
 
-		case 13:{									/* equal */
-				uint tmp = getNextVarContents();
-				condition = (tmp == getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_notEq(bool &cond, int &ret) {
+	// 14: not equal
+	uint tmp = getNextVarContents();
+	cond = (tmp != getVarOrWord());
+}
 
-		case 14:{									/* not equal */
-				uint tmp = getNextVarContents();
-				condition = (tmp != getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_gt(bool &cond, int &ret) {
+	// 15: is greater
+	uint tmp = getNextVarContents();
+	cond = (tmp > getVarOrWord());
+}
 
-		case 15:{									/* is greater */
-				uint tmp = getNextVarContents();
-				condition = (tmp > getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_lt(bool &cond, int &ret) {
+	// 16: is less
+	uint tmp = getNextVarContents();
+	cond = (tmp < getVarOrWord());
+}
 
-		case 16:{									/* is less */
-				uint tmp = getNextVarContents();
-				condition = (tmp < getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_eqf(bool &cond, int &ret) {
+	// 17: is eq f
+	uint tmp = getNextVarContents();
+	cond = (tmp == getNextVarContents());
+}
 
-		case 17:{									/* is eq f */
-				uint tmp = getNextVarContents();
-				condition = (tmp == getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_notEqf(bool &cond, int &ret) {
+	// 18: is not equal f
+	uint tmp = getNextVarContents();
+	cond = (tmp != getNextVarContents());
+}
 
-		case 18:{									/* is not equal f */
-				uint tmp = getNextVarContents();
-				condition = (tmp != getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_ltf(bool &cond, int &ret) {
+	// 19: is greater f
+	uint tmp = getNextVarContents();
+	cond = (tmp < getNextVarContents());
+}
 
-		case 19:{									/* is greater f */
-				uint tmp = getNextVarContents();
-				condition = (tmp < getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_gtf(bool &cond, int &ret) {
+	// 20: is less f
+	uint tmp = getNextVarContents();
+	cond = (tmp > getNextVarContents());
+}
 
-		case 20:{									/* is less f */
-				uint tmp = getNextVarContents();
-				condition = (tmp > getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_chance(bool &cond, int &ret) {
+	// 23
+	cond = o_chance(getVarOrWord());
+}
 
-		case 23:{
-				condition = o_chance(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_isRoom(bool &cond, int &ret) {
+	// 25: is room
+	cond = isRoom(getNextItemPtr());
+}
 
-		case 25:{									/* is room */
-				condition = isRoom(getNextItemPtr());
-			}
-			break;
+void SimonEngine::o1_isObject(bool &cond, int &ret) {
+	// 26: is object
+	cond = isObject(getNextItemPtr());
+}
 
-		case 26:{									/* is object */
-				condition = isObject(getNextItemPtr());
-			}
-			break;
+void SimonEngine::o1_state(bool &cond, int &ret) {
+	// 27: item state is
+	Item *item = getNextItemPtr();
+	cond = ((uint) item->state == getVarOrWord());
+}
 
-		case 27:{									/* item state is */
-				Item *item = getNextItemPtr();
-				condition = ((uint) item->state == getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_oflag(bool &cond, int &ret) {
+	// 28: item has prop
+	SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
+	byte num = getVarOrByte();
+	cond = subObject != NULL && (subObject->objectFlags & (1 << num)) != 0;
+}
 
-		case 28:{									/* item has prop */
-				SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
-				byte num = getVarOrByte();
-				condition = subObject != NULL && (subObject->objectFlags & (1 << num)) != 0;
-			} break;
+void SimonEngine::o1_destroy(bool &cond, int &ret) {
+	// 31: set no parent
+	setItemParent(getNextItemPtr(), NULL);
+}
 
-		case 31:{									/* set no parent */
-				setItemParent(getNextItemPtr(), NULL);
-			}
-			break;
+void SimonEngine::o1_place(bool &cond, int &ret) {
+	// 33: set item parent
+	Item *item = getNextItemPtr();
+	setItemParent(item, getNextItemPtr());
+}
 
-		case 33:{									/* set item parent */
-				Item *item = getNextItemPtr();
-				setItemParent(item, getNextItemPtr());
-			}
-			break;
+void SimonEngine::o1_copyff(bool &cond, int &ret) {
+	// 36: copy var
+	uint value = getNextVarContents();
+	writeNextVarContents(value);
+}
 
-		case 36:{									/* copy var */
-				uint value = getNextVarContents();
-				writeNextVarContents(value);
-			}
-			break;
+void SimonEngine::o1_clear(bool &cond, int &ret) {
+	// 41: zero var
+	writeNextVarContents(0);
+}
 
-		case 37:{
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_let(bool &cond, int &ret) {
+	// 42: set var
+	uint var = getVarOrByte();
+	writeVariable(var, getVarOrWord());
+}
 
-				getVarOrByte();
-				_runScriptReturn1 = 1;
-			}
-			break;
+void SimonEngine::o1_add(bool &cond, int &ret) {
+	// 43: add
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) + getVarOrWord());
+}
 
-		case 41:{									/* zero var */
-				writeNextVarContents(0);
-			}
-			break;
+void SimonEngine::o1_sub(bool &cond, int &ret) {
+	// 44: sub
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) - getVarOrWord());
+}
 
-		case 42:{									/* set var */
-				uint var = getVarOrByte();
-				writeVariable(var, getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_addf(bool &cond, int &ret) {
+	// 45: add f
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) + getNextVarContents());
+}
 
-		case 43:{									/* add */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) + getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_subf(bool &cond, int &ret) {
+	// 46: sub f
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) - getNextVarContents());
+}
 
-		case 44:{									/* sub */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) - getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_mul(bool &cond, int &ret) {
+	// 47: mul
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) * getVarOrWord());
+}
 
-		case 45:{									/* add f */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) + getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_div(bool &cond, int &ret) {
+	// 48: div
+	uint var = getVarOrByte();
+	int value = getVarOrWord();
+	if (value == 0)
+		error("o1_div: Division by zero");
+	writeVariable(var, readVariable(var) / value);
+}
 
-		case 46:{									/* sub f */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) - getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_mulf(bool &cond, int &ret) {
+	// 49: mul f
+	uint var = getVarOrByte();
+	writeVariable(var, readVariable(var) * getNextVarContents());
+}
 
-		case 47:{									/* mul */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) * getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_divf(bool &cond, int &ret) {
+	// 50: div f
+	uint var = getVarOrByte();
+	int value = getNextVarContents();
+	if (value == 0)
+		error("o1_divf: Division by zero");
+	writeVariable(var, readVariable(var) / value);
+}
 
-		case 48:{									/* div */
-				uint var = getVarOrByte();
-				int value = getVarOrWord();
-				if (value == 0)
-					error("Division by zero in div");
-				writeVariable(var, readVariable(var) / value);
-			}
-			break;
+void SimonEngine::o1_mod(bool &cond, int &ret) {
+	// 51: mod
+	uint var = getVarOrByte();
+	int value = getVarOrWord();
+	if (value == 0)
+		error("o1_mod: Division by zero");
+	writeVariable(var, readVariable(var) % value);
+}
 
-		case 49:{									/* mul f */
-				uint var = getVarOrByte();
-				writeVariable(var, readVariable(var) * getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_modf(bool &cond, int &ret) {
+	// 52: mod f
+	uint var = getVarOrByte();
+	int value = getNextVarContents();
+	if (value == 0)
+		error("o1_modf: Division by zero");
+	writeVariable(var, readVariable(var) % value);
+}
 
-		case 50:{									/* div f */
-				uint var = getVarOrByte();
-				int value = getNextVarContents();
-				if (value == 0)
-					error("Division by zero in div f");
-				writeVariable(var, readVariable(var) / value);
-			}
-			break;
+void SimonEngine::o1_random(bool &cond, int &ret) {
+	// 53: random
+	uint var = getVarOrByte();
+	uint value = (uint16)getVarOrWord();
 
-		case 51:{									/* mod */
-				uint var = getVarOrByte();
-				int value = getVarOrWord();
-				if (value == 0)
-					error("Division by zero in mod");
-				writeVariable(var, readVariable(var) % value);
-			}
-			break;
+	// Disable random in simon1amiga for now
+	// Since copy protection screen is currently unreadable
+	if (getPlatform() == Common::kPlatformAmiga)
+		writeVariable(var, 4);
+	else
+		writeVariable(var, _rnd.getRandomNumber(value - 1));
+}
 
-		case 52:{									/* mod f */
-				uint var = getVarOrByte();
-				int value = getNextVarContents();
-				if (value == 0)
-					error("Division by zero in mod f");
-				writeVariable(var, readVariable(var) % value);
-			}
-			break;
+void SimonEngine::o1_goto(bool &cond, int &ret) {
+	// 55: set itemA parent
+	setItemParent(getItem1Ptr(), getNextItemPtr());
+}
 
-		case 53:{									/* random */
-				uint var = getVarOrByte();
-				uint value = (uint16)getVarOrWord();
+void SimonEngine::o1_oset(bool &cond, int &ret) {
+	// 56: set child2 fr bit
+	SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
+	int value = getVarOrByte();
+	if (subObject != NULL && value >= 0x10)
+		subObject->objectFlags |= 1 << value;
+}
 
-				// Disable random in simon1amiga for now
-				// Since copy protection screen is currently unreadable
-				if (getPlatform() == Common::kPlatformAmiga)
-					writeVariable(var, 4);
-				else
-					writeVariable(var, _rnd.getRandomNumber(value - 1));
-			}
-			break;
+void SimonEngine::o1_oclear(bool &cond, int &ret) {
+	// 57: clear child2 fr bit
+	SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
+	int value = getVarOrByte();
+	if (subObject != NULL && value >= 0x10)
+		subObject->objectFlags &= ~(1 << value);
+}
 
-		case 55:{									/* set itemA parent */
-				setItemParent(getItem1Ptr(), getNextItemPtr());
-			}
-			break;
+void SimonEngine::o1_putBy(bool &cond, int &ret) {
+	// 58: make siblings
+	Item *item = getNextItemPtr();
+	setItemParent(item, derefItem(getNextItemPtr()->parent));
+}
 
-		case 56:{									/* set child2 fr bit */
-				SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
-				int value = getVarOrByte();
-				if (subObject != NULL && value >= 0x10)
-					subObject->objectFlags |= 1 << value;
-			}
-			break;
+void SimonEngine::o1_inc(bool &cond, int &ret) {
+	// 59: item inc state
+	Item *item = getNextItemPtr();
+	if (item->state <= 30000)
+		setItemState(item, item->state + 1);
+}
 
-		case 57:{									/* clear child2 fr bit */
-				SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
-				int value = getVarOrByte();
-				if (subObject != NULL && value >= 0x10)
-					subObject->objectFlags &= ~(1 << value);
-			}
-			break;
+void SimonEngine::o1_dec(bool &cond, int &ret) {
+	// 60: item dec state
+	Item *item = getNextItemPtr();
+	if (item->state >= 0)
+		setItemState(item, item->state - 1);
+}
 
-		case 58:{									/* make siblings */
-				Item *item = getNextItemPtr();
-				setItemParent(item, derefItem(getNextItemPtr()->parent));
-			}
-			break;
+void SimonEngine::o1_setState(bool &cond, int &ret) {
+	// 61: item set state
+	Item *item = getNextItemPtr();
+	int value = getVarOrWord();
+	if (value < 0)
+		value = 0;
+	if (value > 30000)
+		value = 30000;
+	setItemState(item, value);
+}
 
-		case 59:{									/* item inc state */
-				Item *item = getNextItemPtr();
-				if (item->state <= 30000)
-					setItemState(item, item->state + 1);
-			}
-			break;
+void SimonEngine::o1_print(bool &cond, int &ret) {
+	// 62: show int
+	showMessageFormat("%d", getNextVarContents());
+}
 
-		case 60:{									/* item dec state */
-				Item *item = getNextItemPtr();
-				if (item->state >= 0)
-					setItemState(item, item->state - 1);
-			}
-			break;
+void SimonEngine::o1_message(bool &cond, int &ret) {
+	// 63: show string nl
+	showMessageFormat("%s\n", getStringPtrByID(getNextStringID()));
+}
 
-		case 61:{									/* item set state */
-				Item *item = getNextItemPtr();
-				int value = getVarOrWord();
-				if (value < 0)
-					value = 0;
-				if (value > 30000)
-					value = 30000;
-				setItemState(item, value);
-			}
-			break;
+void SimonEngine::o1_msg(bool &cond, int &ret) {
+	// 64: show string
+	showMessageFormat("%s", getStringPtrByID(getNextStringID()));
+}
 
-		case 62:{									/* show int */
-				showMessageFormat("%d", getNextVarContents());
-			}
-			break;
+void SimonEngine::o1_addTextBox(bool &cond, int &ret) {
+	// 65: add hit area
+	int id = getVarOrWord();
+	int x = getVarOrWord();
+	int y = getVarOrWord();
+	int w = getVarOrWord();
+	int h = getVarOrWord();
+	int number = getVarOrByte();
+	if (number < 20)
+		addNewHitArea(id, x, y, w, h, (number << 8) + 129, 0xD0, _dummyItem2);
+}
 
-		case 63:{									/* show string nl */
-				showMessageFormat("%s\n", getStringPtrByID(getNextStringID()));
-			}
-			break;
+void SimonEngine::o1_setShortText(bool &cond, int &ret) {
+	// 66: set item name
+	uint var = getVarOrByte();
+	uint stringId = getNextStringID();
+	if (var < 20)
+		_stringIdArray2[var] = stringId;
+}
 
-		case 64:{									/* show string */
-				showMessageFormat("%s", getStringPtrByID(getNextStringID()));
-			}
-			break;
+void SimonEngine::o1_setLongText(bool &cond, int &ret) {
+	// 67: set item description
+	uint var = getVarOrByte();
+	uint stringId = getNextStringID();
+	if (getFeatures() & GF_TALKIE) {
+		uint speechId = getNextWord();
+		if (var < 20) {
+			_stringIdArray3[var] = stringId;
+			_speechIdArray4[var] = speechId;
+		}
+	} else {
+		if (var < 20) {
+			_stringIdArray3[var] = stringId;
+		}
+	}
+}
 
-		case 65:{									/* add hit area */
-				int id = getVarOrWord();
-				int x = getVarOrWord();
-				int y = getVarOrWord();
-				int w = getVarOrWord();
-				int h = getVarOrWord();
-				int number = getVarOrByte();
-				if (number < 20)
-					addNewHitArea(id, x, y, w, h, (number << 8) + 129, 0xD0, _dummyItem2);
-			}
-			break;
+void SimonEngine::o1_end(bool &cond, int &ret) {
+	// 68: exit interpreter
+	shutdown();
+}
 
-		case 66:{									/* set item name */
-				uint var = getVarOrByte();
-				uint stringId = getNextStringID();
-				if (var < 20)
-					_stringIdArray2[var] = stringId;
-			}
-			break;
+void SimonEngine::o1_done(bool &cond, int &ret) {
+	// 69: return 1
+	ret = 1;
+}
 
-		case 67:{									/* set item description */
-				uint var = getVarOrByte();
-				uint stringId = getNextStringID();
-				if (getFeatures() & GF_TALKIE) {
-					uint speechId = getNextWord();
-					if (var < 20) {
-						_stringIdArray3[var] = stringId;
-						_speechIdArray4[var] = speechId;
-					}
-				} else {
-					if (var < 20) {
-						_stringIdArray3[var] = stringId;
-					}
-				}
-			}
-			break;
+void SimonEngine::o1_printLongText(bool &cond, int &ret) {
+	// 70: show string from array
+	const char *str = (const char *)getStringPtrByID(_stringIdArray3[getVarOrByte()]);
+	showMessageFormat("%s\n", str);
+}
 
-		case 68:{									/* exit interpreter */
-				shutdown();
-			}
-			break;
+void SimonEngine::o1_process(bool &cond, int &ret) {
+	// 71: start subroutine
+	Subroutine *sub = getSubroutineByID(getVarOrWord());
+	if (sub != NULL)
+		startSubroutine(sub);
+}
 
-		case 69:{									/* return 1 */
-				return 1;
-			}
+void SimonEngine::o1_when(bool &cond, int &ret) {
+	// 76: add timeout
+	uint timeout = getVarOrWord();
+	addTimeEvent(timeout, getVarOrWord());
+}
 
-		case 70:{									/* show string from array */
-				const char *str = (const char *)getStringPtrByID(_stringIdArray3[getVarOrByte()]);
+void SimonEngine::o1_if1(bool &cond, int &ret) {
+	// 77: has item minus 1
+	cond = _subjectItem != NULL;
+}
 
-				if (getGameType() == GType_SIMON2) {
-					writeVariable(51, strlen(str) / 53 * 8 + 8);
-				}
+void SimonEngine::o1_if2(bool &cond, int &ret) {
+	// 78: has item minus 3
+	cond = _objectItem != NULL;
+}
 
-				showMessageFormat("%s\n", str);
-			}
-			break;
+void SimonEngine::o1_isCalled(bool &cond, int &ret) {
+	// 79: childstruct fr2 is
+	SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
+	uint stringId = getNextStringID();
+	cond = (subObject != NULL) && subObject->objectName == stringId;
+}
 
-		case 71:{									/* start subroutine */
-				Subroutine *sub = getSubroutineByID(getVarOrWord());
-				if (sub != NULL)
-					startSubroutine(sub);
-			}
-			break;
+void SimonEngine::o1_is(bool &cond, int &ret) {
+	// 80: item equal
+	cond = getNextItemPtr() == getNextItemPtr();
+}
 
-		case 76:{									/* add timeout */
-				uint timeout = getVarOrWord();
-				addTimeEvent(timeout, getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_debug(bool &cond, int &ret) {
+	// 82: debug opcode
+	getVarOrByte();
+}
 
-		case 77:{									/* has item minus 1 */
-				condition = _subjectItem != NULL;
-			}
-			break;
+void SimonEngine::o1_rescan(bool &cond, int &ret) {
+	// 83: restart subroutine
+	ret = -10;
+}
 
-		case 78:{									/* has item minus 3 */
-				condition = _objectItem != NULL;
-			}
-			break;
+void SimonEngine::o1_comment(bool &cond, int &ret) {
+	// 87: comment
+	getNextStringID();
+}
 
-		case 79:{									/* childstruct fr2 is */
-				SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
-				uint stringId = getNextStringID();
-				condition = (subObject != NULL) && subObject->objectName == stringId;
-			}
-			break;
+void SimonEngine::o1_haltAnimation(bool &cond, int &ret) {
+	// 88: stop animation
+	_lockWord |= 0x10;
+}
 
-		case 80:{									/* item equal */
-				condition = getNextItemPtr() == getNextItemPtr();
-			}
-			break;
+void SimonEngine::o1_restartAnimation(bool &cond, int &ret) {
+	// 89: restart animation
+	_lockWord &= ~0x10;
+}
 
-		case 82:{									/* debug opcode */
-				getVarOrByte();
-			}
-			break;
+void SimonEngine::o1_getParent(bool &cond, int &ret) {
+	// 90: set minusitem to parent
+	Item *item = derefItem(getNextItemPtr()->parent);
+	switch (getVarOrByte()) {
+	case 0:
+		_objectItem = item;
+		break;
+	case 1:
+		_subjectItem = item;
+		break;
+	default:
+		error("o1_getParent: invalid subcode");
+	}
+}
 
-		case 83:{									/* restart subroutine */
-				if (getGameType() == GType_SIMON2 || getGameType() == GType_FF)
-					o_83_helper();
-				return -10;
-			}
+void SimonEngine::o1_getNext(bool &cond, int &ret) {
+	// 91: set minusitem to sibling
+	Item *item = derefItem(getNextItemPtr()->sibling);
+	switch (getVarOrByte()) {
+	case 0:
+		_objectItem = item;
+		break;
+	case 1:
+		_subjectItem = item;
+		break;
+	default:
+		error("o1_getNext: invalid subcode");
+	}
+}
 
-		case 87:{									/* comment */
-				getNextStringID();
-			}
-			break;
+void SimonEngine::o1_getChildren(bool &cond, int &ret) {
+	// 92: set minusitem to child
+	Item *item = derefItem(getNextItemPtr()->child);
+	switch (getVarOrByte()) {
+	case 0:
+		_objectItem = item;
+		break;
+	case 1:
+		_subjectItem = item;
+		break;
+	default:
+		error("o1_getChildren: invalid subcode");
+	}
+}
 
-		case 88:{									/* stop animation */
-				_lockWord |= 0x10;
-			}
-			break;
+void SimonEngine::o1_picture(bool &cond, int &ret) {
+	// 96
+	uint val = getVarOrWord();
+	o_set_video_mode(getVarOrByte(), val);
+}
 
-		case 89:{									/* restart animation */
-				_lockWord &= ~0x10;
-			}
-			break;
+void SimonEngine::o1_loadZone(bool &cond, int &ret) {
+	// 97: load vga
+	o_loadZone(getVarOrWord());
+}
 
-		case 90:{									/* set minusitem to parent */
-				Item *item = derefItem(getNextItemPtr()->parent);
-				switch (getVarOrByte()) {
-				case 0:
-					_objectItem = item;
-					break;
-				case 1:
-					_subjectItem = item;
-					break;
-				default:
-					error("set minusitem to parent, invalid subcode");
-				}
-			}
-			break;
+void SimonEngine::o1_animate(bool &cond, int &ret) {
+	// 98: start vga
+	uint vga_res, vgaSpriteId, windowNum, x, y, palette;
+	vgaSpriteId = getVarOrWord();
+	vga_res = vgaSpriteId / 100;
+	windowNum = getVarOrByte();
+	x = getVarOrWord();
+	y = getVarOrWord();
+	palette = getVarOrWord();
+	loadSprite(windowNum, vga_res, vgaSpriteId, x, y, palette);
+}
 
-		case 91:{									/* set minusitem to sibling */
-				Item *item = derefItem(getNextItemPtr()->sibling);
-				switch (getVarOrByte()) {
-				case 0:
-					_objectItem = item;
-					break;
-				case 1:
-					_subjectItem = item;
-					break;
-				default:
-					error("set minusitem to sibling, invalid subcode");
-				}
-			}
-			break;
+void SimonEngine::o1_stopAnimate(bool &cond, int &ret) {
+	// 99: kill sprite
+	o_kill_sprite_simon1(getVarOrWord());
+}
 
-		case 92:{									/* set minusitem to child */
-				Item *item = derefItem(getNextItemPtr()->child);
-				switch (getVarOrByte()) {
-				case 0:
-					_objectItem = item;
-					break;
-				case 1:
-					_subjectItem = item;
-					break;
-				default:
-					error("set minusitem to child, invalid subcode");
-				}
-			}
-			break;
+void SimonEngine::o1_killAnimate(bool &cond, int &ret) {
+	// 100: vga reset
+	o_vga_reset();
+}
 
-		case 96:{
-				uint val = getVarOrWord();
-				o_set_video_mode(getVarOrByte(), val);
-			}
-			break;
+void SimonEngine::o1_defWindow(bool &cond, int &ret) {
+	// 101
+	uint num = getVarOrByte();
+	uint x = getVarOrWord();
+	uint y = getVarOrWord();
+	uint w = getVarOrWord();
+	uint h = getVarOrWord();
+	uint flags = getVarOrWord();
+	uint fill_color = getVarOrWord();
+	o_defineWindow(num, x, y, w, h, flags, fill_color, 0);
+}
 
-		case 97:{									/* load vga */
-				o_loadZone(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_window(bool &cond, int &ret) {
+	// 102
+	changeWindow(getVarOrByte() & 7);
+}
 
-		case 98:{									/* start vga */
-				uint vga_res, vgaSpriteId, windowNum, x, y, palette;
-				if (getGameType() == GType_SIMON1) {
-					vgaSpriteId = getVarOrWord();
-					vga_res = vgaSpriteId / 100;
-				} else {
-					vga_res = getVarOrWord();
-					vgaSpriteId = getVarOrWord();
-				}
-				windowNum = getVarOrByte();
-				x = getVarOrWord();
-				y = getVarOrWord();
-				palette = getVarOrWord();
-				loadSprite(windowNum, vga_res, vgaSpriteId, x, y, palette);
-			}
-			break;
+void SimonEngine::o1_cls(bool &cond, int &ret) {
+	// 103
+	o_unk_103();
+}
 
-		case 99:{									/* kill sprite */
-				if (getGameType() == GType_SIMON1) {
-					o_kill_sprite_simon1(getVarOrWord());
-				} else {
-					uint a = getVarOrWord();
-					uint b = getVarOrWord();
-					o_kill_sprite_simon2(a, b);
-				}
-			}
-			break;
+void SimonEngine::o1_closeWindow(bool &cond, int &ret) {
+	// 104
+	closeWindow(getVarOrByte() & 7);
+}
 
-		case 100:{									/* vga reset */
-				o_vga_reset();
-			}
-			break;
+void SimonEngine::o1_addBox(bool &cond, int &ret) {
+	// 107: add item hitarea
+	uint flags = 0;
+	uint id = getVarOrWord();
+	uint params = id / 1000;
+	uint x, y, w, h, verb;
+	Item *item;
 
-		case 101:{
-				uint num = getVarOrByte();
-				uint x = getVarOrWord();
-				uint y = getVarOrWord();
-				uint w = getVarOrWord();
-				uint h = getVarOrWord();
-				uint flags = getVarOrWord();
-				uint fill_color = getVarOrWord();
-				o_defineWindow(num, x, y, w, h, flags, fill_color, 0);
-			}
-			break;
+	id = id % 1000;
 
-		case 102:{
-				changeWindow(getVarOrByte() & 7);
-			}
-			break;
+	if (params & 1)
+		flags |= 8;
+	if (params & 2)
+		flags |= 4;
+	if (params & 4)
+		flags |= 0x80;
+	if (params & 8)
+		flags |= 1;
+	if (params & 16)
+		flags |= 0x10;
 
-		case 103:{
-				o_unk_103();
-			}
-			break;
+	x = getVarOrWord();
+	y = getVarOrWord();
+	w = getVarOrWord();
+	h = getVarOrWord();
+	item = getNextItemPtrStrange();
+	verb = getVarOrWord();
+	if (x >= 1000) {
+		verb += 0x4000;
+		x -= 1000;
+	}
+	addNewHitArea(id, x, y, w, h, flags, verb, item);
+}
 
-		case 104:{
-				closeWindow(getVarOrByte() & 7);
-			}
-			break;
+void SimonEngine::o1_delBox(bool &cond, int &ret) {
+	// 108: delete hitarea
+	delete_hitarea(getVarOrWord());
+}
 
-		case 107:{									/* add item hitarea */
-				uint flags = 0;
-				uint id = getVarOrWord();
-				uint params = id / 1000;
-				uint x, y, w, h, verb;
-				Item *item;
+void SimonEngine::o1_enableBox(bool &cond, int &ret) {
+	// 109: clear hitarea bit 0x40
+	clear_hitarea_bit_0x40(getVarOrWord());
+}
 
-				id = id % 1000;
+void SimonEngine::o1_disableBox(bool &cond, int &ret) {
+	// 110: set hitarea bit 0x40
+	set_hitarea_bit_0x40(getVarOrWord());
+}
 
-				if (params & 1)
-					flags |= 8;
-				if (params & 2)
-					flags |= 4;
-				if (params & 4)
-					flags |= 0x80;
-				if (params & 8)
-					flags |= 1;
-				if (params & 16)
-					flags |= 0x10;
+void SimonEngine::o1_moveBox(bool &cond, int &ret) {
+	// 111: set hitarea xy
+	uint hitarea_id = getVarOrWord();
+	uint x = getVarOrWord();
+	uint y = getVarOrWord();
+	moveBox(hitarea_id, x, y);
+}
 
-				x = getVarOrWord();
-				y = getVarOrWord();
-				w = getVarOrWord();
-				h = getVarOrWord();
-				item = getNextItemPtrStrange();
-				verb = getVarOrWord();
-				if (x >= 1000) {
-					verb += 0x4000;
-					x -= 1000;
-				}
-				addNewHitArea(id, x, y, w, h, flags, verb, item);
-			}
-			break;
+void SimonEngine::o1_doIcons(bool &cond, int &ret) {
+	// 114
+	Item *item = getNextItemPtr();
+	uint num = getVarOrByte();
+	mouseOff();
+	drawIconArray(num, item, 0, 0);
+	mouseOn();
+}
 
-		case 108:{									/* delete hitarea */
-				delete_hitarea(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_isClass(bool &cond, int &ret) {
+	// 115: item has flag
+	Item *item = getNextItemPtr();
+	cond = (item->classFlags & (1 << getVarOrByte())) != 0;
+}
 
-		case 109:{									/* clear hitarea bit 0x40 */
-				clear_hitarea_bit_0x40(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_setClass(bool &cond, int &ret) {
+	// 116: item set flag
+	Item *item = getNextItemPtr();
+	item->classFlags |= (1 << getVarOrByte());
+}
 
-		case 110:{									/* set hitarea bit 0x40 */
-				set_hitarea_bit_0x40(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_unsetClass(bool &cond, int &ret) {
+	// 117: item clear flag
+	Item *item = getNextItemPtr();
+	item->classFlags &= ~(1 << getVarOrByte());
+}
 
-		case 111:{									/* set hitarea xy */
-				uint hitarea_id = getVarOrWord();
-				uint x = getVarOrWord();
-				uint y = getVarOrWord();
-				moveBox(hitarea_id, x, y);
-			}
-			break;
+void SimonEngine::o1_waitSync(bool &cond, int &ret) {
+	// 119: wait vga
+	uint var = getVarOrWord();
+	_scriptVar2 = (var == 200);
 
-		case 114:{
-				Item *item = getNextItemPtr();
-				uint num = getVarOrByte();
-				mouseOff();
-				drawIconArray(num, item, 0, 0);
-				mouseOn();
-			}
-			break;
+	if (var != 200 || !_skipVgaWait)
+		o_waitForSync(var);
+	_skipVgaWait = false;
+}
 
-		case 115:{									/* item has flag */
-				Item *item = getNextItemPtr();
-				condition = (item->classFlags & (1 << getVarOrByte())) != 0;
-			}
-			break;
+void SimonEngine::o1_sync(bool &cond, int &ret) {
+	// 120: sync
+	o_sync(getVarOrWord());
+}
 
-		case 116:{									/* item set flag */
-				Item *item = getNextItemPtr();
-				item->classFlags |= (1 << getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_defObj(bool &cond, int &ret) {
+	// 121: set vga item
+	uint slot = getVarOrByte();
+	_vcItemArray[slot] = getNextItemPtr();
+}
 
-		case 117:{									/* item clear flag */
-				Item *item = getNextItemPtr();
-				item->classFlags &= ~(1 << getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_here(bool &cond, int &ret) {
+	// 125: item is sibling with item 1
+	Item *item = getNextItemPtr();
+	cond = (getItem1Ptr()->parent == item->parent);
+}
 
-		case 119:{									/* wait vga */
-				uint var = getVarOrWord();
-				_scriptVar2 = (var == 200);
+void SimonEngine::o1_doClassIcons(bool &cond, int &ret) {
+	// 126
+	Item *item = getNextItemPtr();
+	uint num = getVarOrByte();
+	uint a = 1 << getVarOrByte();
+	mouseOff();
+	drawIconArray(num, item, 1, a);
+	mouseOn();
+}
 
-				if (var != 200 || !_skipVgaWait)
-					o_waitForSync(var);
-				_skipVgaWait = false;
-			}
-			break;
+void SimonEngine::o1_playTune(bool &cond, int &ret) {
+	// 127: deals with music
+	o_playMusic();
+}
 
-		case 120:{
-				o_sync(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_waitEndTune(bool &cond, int &ret) {
+	// 128: dummy instruction
+	getVarOrWord();
+}
 
-		case 121:{									/* set vga item */
-				uint slot = getVarOrByte();
-				_vcItemArray[slot] = getNextItemPtr();
-			}
-			break;
+void SimonEngine::o1_ifEndTune(bool &cond, int &ret) {
+	// 129: dummy instruction
+	getVarOrWord();
+	cond = true;
+}
 
-		case 122:{									/* oracle text down */
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_setAdjNoun(bool &cond, int &ret) {
+	// 130: set adj noun
+	uint var = getVarOrByte();
+	if (var == 1) {
+		_scriptAdj1 = getNextWord();
+		_scriptNoun1 = getNextWord();
+	} else {
+		_scriptAdj2 = getNextWord();
+		_scriptNoun2 = getNextWord();
+	}
+}
 
-				oracleTextDown();
-			}
-			break;
+void SimonEngine::o1_saveUserGame(bool &cond, int &ret) {
+	// 132: save game
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+	o_saveGame();
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+}
 
-		case 123:{									/* oracle text down */
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_loadUserGame(bool &cond, int &ret) {
+	// 133: load game
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+	o_loadGame();
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+}
 
-				oracleTextUp();
-			}
-			break;
+void SimonEngine::o1_stopTune(bool &cond, int &ret) {
+	// 134: dummy opcode?
+	midi.stop();
+	_lastMusicPlayed = -1;
+}
 
-		case 124:{									/* if time */
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_pauseGame(bool &cond, int &ret) {
+	// 135: quit if user presses y
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+	o_confirmQuit();
+	_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+}
 
-				uint time = getVarOrWord();
-				condition = 1;
-				warning("STUB: script opcode 124 (%d)", time);
-			}
-			break;
+void SimonEngine::o1_copysf(bool &cond, int &ret) {
+	// 136: set var to item unk3
+	Item *item = getNextItemPtr();
+	writeNextVarContents(item->state);
+}
 
-		case 125:{									/* item is sibling with item 1 */
-				Item *item = getNextItemPtr();
-				condition = (getItem1Ptr()->parent == item->parent);
-			}
-			break;
+void SimonEngine::o1_restoreIcons(bool &cond, int &ret) {
+	// 137
+	o_restoreIconArray(getVarOrByte());
+}
 
-		case 126:{
-				Item *item = getNextItemPtr();
-				uint num = getVarOrByte();
-				uint a = 1 << getVarOrByte();
-				mouseOff();
-				drawIconArray(num, item, 1, a);
-				mouseOn();
-			}
-			break;
+void SimonEngine::o1_freezeZones(bool &cond, int &ret) {
+	// 138: vga pointer op 4
+	o_freezeBottom();
+}
 
-		case 127:{									/* deals with music */
-				o_playMusic();
-			}
-			break;
+void SimonEngine::o1_placeNoIcons(bool &cond, int &ret) {
+	// 139: set parent special
+	Item *item = getNextItemPtr();
+	_noParentNotify = true;
+	setItemParent(item, getNextItemPtr());
+	_noParentNotify = false;
+}
 
-		case 128:{									/* dummy instruction */
-				getVarOrWord();
-			}
-			break;
+void SimonEngine::o1_clearTimers(bool &cond, int &ret) {
+	// 140: del te and add one
+	killAllTimers();
+	addTimeEvent(3, 0xA0);
+}
 
-		case 129:{									/* dummy instruction */
-				getVarOrWord();
-				condition = true;
-			}
-			break;
+void SimonEngine::o1_setDollar(bool &cond, int &ret) {
+	// 141: set m1 to m3
+	uint which = getVarOrByte();
+	Item *item = getNextItemPtr();
+	if (which == 1) {
+		_subjectItem = item;
+	} else {
+		_objectItem = item;
+	}
+}
 
-		case 130:{									/* set adj noun */
-				uint var = getVarOrByte();
-				if (var == 1) {
-					_scriptAdj1 = getNextWord();
-					_scriptNoun1 = getNextWord();
-				} else {
-					_scriptAdj2 = getNextWord();
-					_scriptNoun2 = getNextWord();
-				}
-			}
-			break;
+void SimonEngine::o1_isBox(bool &cond, int &ret) {
+	// 142: is hitarea 0x40 clear
+	cond = is_hitarea_0x40_clear(getVarOrWord());
+}
 
-		case 131:{
-				warning("STUB: script opcode 131");
-			}
-			break;
+void SimonEngine::o1_doTable(bool &cond, int &ret) {
+	// 143: start item sub
+	SubRoom *subRoom = (SubRoom *)findChildOfType(getNextItemPtr(), 1);
+	if (subRoom != NULL) {
+		Subroutine *sub = getSubroutineByID(subRoom->subroutine_id);
+		if (sub)
+			startSubroutine(sub);
+	}
+}
 
-		case 132:{									/* save game */
-				_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-				o_saveGame();
-				_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-			}
-			break;
+void SimonEngine::o1_storeItem(bool &cond, int &ret) {
+	// 151: set array6 to item
+	uint var = getVarOrByte();
+	Item *item = getNextItemPtr();
+	_itemArray6[var] = item;
+}
 
-		case 133:{									/* load game */
-				if (getGameType() == GType_FF) {
-					loadGame(readVariable(55));
-				} else {
-					_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-					o_loadGame();
-					_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-				}
-			}
-			break;
+void SimonEngine::o1_getItem(bool &cond, int &ret) {
+	// 152: set m1 to m3 to array 6
+	Item *item = _itemArray6[getVarOrByte()];
+	uint var = getVarOrByte();
+	if (var == 1) {
+		_subjectItem = item;
+	} else {
+		_objectItem = item;
+	}
+}
 
-		case 134:{									/* dummy opcode? */
-				if (getGameType() == GType_FF) {
-					listSaveGames(1);
-				} else {
-					midi.stop();
-					_lastMusicPlayed = -1;
-				}
-			}
-			break;
+void SimonEngine::o1_bSet(bool &cond, int &ret) {
+	// 153: set bit
+	setBitFlag(getVarOrByte(), true);
+}
 
-		case 135:{									/* quit if user presses y */
-				if (getGameType() == GType_FF) {
-					// Switch CD
-					debug(1, "Switch to CD number %d", readVariable(97));
-				} else {
-					_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-					o_confirmQuit();
-					_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-				}
-			}
-			break;
+void SimonEngine::o1_bClear(bool &cond, int &ret) {
+	// 154: clear bit
+	setBitFlag(getVarOrByte(), false);
+}
 
-		case 136:{									/* set var to item unk3 */
-				Item *item = getNextItemPtr();
-				writeNextVarContents(item->state);
-			}
-			break;
+void SimonEngine::o1_bZero(bool &cond, int &ret) {
+	// 155: is bit clear
+	cond = !getBitFlag(getVarOrByte());
+}
 
-		case 137:{
-				o_restoreIconArray(getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_bNotZero(bool &cond, int &ret) {
+	// 156: is bit set
+	uint bit = getVarOrByte();
 
-		case 138:{									/* vga pointer op 4 */
-				o_freezeBottom();
-			}
-			break;
+	// WORKAROUND: Fix for glitch in some versions
+	if (getGameType() == GType_SIMON1 && _subroutine == 2962 && bit == 63) {
+		bit = 50;
+	}
 
-		case 139:{									/* set parent special */
-				Item *item = getNextItemPtr();
-				_noParentNotify = true;
-				setItemParent(item, getNextItemPtr());
-				_noParentNotify = false;
-			}
-			break;
+	cond = getBitFlag(bit);
+}
 
-		case 140:{									/* del te and add one */
-				killAllTimers();
-				addTimeEvent(3, 0xA0);
-			}
-			break;
+void SimonEngine::o1_getOValue(bool &cond, int &ret) {
+	// 157: get item int prop
+	Item *item = getNextItemPtr();
+	SubObject *subObject = (SubObject *)findChildOfType(item, 2);
+	uint prop = getVarOrByte();
 
-		case 141:{									/* set m1 or m3 */
-				uint which = getVarOrByte();
-				Item *item = getNextItemPtr();
-				if (which == 1) {
-					_subjectItem = item;
-				} else {
-					_objectItem = item;
-				}
-			}
-			break;
+	if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
+		uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
+		writeNextVarContents(subObject->objectFlagValue[offs]);
+	} else {
+		writeNextVarContents(0);
+	}
+}
 
-		case 142:{									/* is hitarea 0x40 clear */
-				condition = is_hitarea_0x40_clear(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_setOValue(bool &cond, int &ret) {
+	// 158: set item prop
+	Item *item = getNextItemPtr();
+	SubObject *subObject = (SubObject *)findChildOfType(item, 2);
+	uint prop = getVarOrByte();
+	int value = getVarOrWord();
 
-		case 143:{									/* start item sub */
-				SubRoom *subRoom = (SubRoom *)findChildOfType(getNextItemPtr(), 1);
-				if (subRoom != NULL) {
-					Subroutine *sub = getSubroutineByID(subRoom->subroutine_id);
-					if (sub)
-						startSubroutine(sub);
-				}
-			}
-			break;
+	if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
+		uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
+		subObject->objectFlagValue[offs] = value;
+	}
+}
 
-		case 151:{									/* set array6 to item */
-				uint var = getVarOrByte();
-				Item *item = getNextItemPtr();
-				_itemArray6[var] = item;
-			}
-			break;
+void SimonEngine::o1_ink(bool &cond, int &ret) {
+	// 160
+	o_setTextColor(getVarOrByte());
+}
 
-		case 152:{									/* set m1 or m3 to array6 */
-				Item *item = _itemArray6[getVarOrByte()];
-				uint var = getVarOrByte();
-				if (var == 1) {
-					_subjectItem = item;
-				} else {
-					_objectItem = item;
-				}
-			}
-			break;
+void SimonEngine::o1_screenTextBox(bool &cond, int &ret) {
+	// 161: setup text
+	TextLocation *tl = getTextLocation(getVarOrByte());
 
-		case 153:{									/* set bit */
-				setBitFlag(getVarOrByte(), true);
-				break;
-			}
+	tl->x = getVarOrWord();
+	tl->y = getVarOrByte();
+	tl->width = getVarOrWord();
+}
+	
+void SimonEngine::o1_screenTextMsg(bool &cond, int &ret) {
+	// 162: print string
+	o_printStr();
+}
 
-		case 154:{									/* clear bit */
-				setBitFlag(getVarOrByte(), false);
-				break;
-			}
+void SimonEngine::o1_playEffect(bool &cond, int &ret) {
+	// 163: play sound
+	o_playSFX(getVarOrWord());
+}
 
-		case 155:{									/* is bit clear */
-				condition = !getBitFlag(getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_getDollar2(bool &cond, int &ret) {
+	// 164
+	_showPreposition = true;
+	o_setup_cond_c();
+	_showPreposition = false;
+}
 
-		case 156:{									/* is bit set */
-				uint bit = getVarOrByte();
-				if (getGameType() == GType_SIMON1 && _subroutine == 2962 && bit == 63) {
-					bit = 50;
-				}
-				condition = getBitFlag(bit);
-			}
-			break;
+void SimonEngine::o1_isAdjNoun(bool &cond, int &ret) {
+	// 165: item unk1 unk2 is
+	Item *item = getNextItemPtr();
+	int16 a = getNextWord(), b = getNextWord();
+	cond = (item->adjective == a && item->noun == b);
+}
 
-		case 157:{									/* get item int prop */
-				Item *item = getNextItemPtr();
-				SubObject *subObject = (SubObject *)findChildOfType(item, 2);
-				uint prop = getVarOrByte();
+void SimonEngine::o1_b2Set(bool &cond, int &ret) {
+	// 166: set bit2
+	setBitFlag(256 + getVarOrByte(), true);
+}
 
-				if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
-					uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
-					writeNextVarContents(subObject->objectFlagValue[offs]);
-				} else {
-					writeNextVarContents(0);
-				}
-			}
-			break;
+void SimonEngine::o1_b2Clear(bool &cond, int &ret) {
+	// 167: clear bit2
+	setBitFlag(256 + getVarOrByte(), false);
+}
 
-		case 158:{									/* set item prop */
-				Item *item = getNextItemPtr();
-				SubObject *subObject = (SubObject *)findChildOfType(item, 2);
-				uint prop = getVarOrByte();
-				int value = getVarOrWord();
+void SimonEngine::o1_b2Zero(bool &cond, int &ret) {
+	// 168: is bit2 clear
+	cond = !getBitFlag(256 + getVarOrByte());
+}
 
-				if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
-					uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
-					subObject->objectFlagValue[offs] = value;
-				}
-			}
-			break;
+void SimonEngine::o1_b2NotZero(bool &cond, int &ret) {
+	// 169: is bit2 set
+	cond = getBitFlag(256 + getVarOrByte());
+}
 
-		case 160:{
-				o_setTextColor(getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_lockZones(bool &cond, int &ret) {
+	// 175: vga pointer op 1
+	o_lockZone();
+}
 
-		case 161:{									/* setup text */
-				TextLocation *tl = getTextLocation(getVarOrByte());
+void SimonEngine::o1_unlockZones(bool &cond, int &ret) {
+	// 176: vga pointer op 2
+	o_unlockZone();
+}
 
-				tl->x = getVarOrWord();
-				if (getGameType() == GType_FF)
-					tl->y = getVarOrWord();
-				else
-					tl->y = getVarOrByte();
-				tl->width = getVarOrWord();
-			}
-			break;
+void SimonEngine::o1_screenTextPObj(bool &cond, int &ret) {
+	// 177: inventory descriptions
+	o_inventory_descriptions();
+}
 
-		case 162:{									/* print string */
-				o_printStr();
-			}
-			break;
+void SimonEngine::o1_getPathPosn(bool &cond, int &ret) {
+	// 178: path find
+	uint a = getVarOrWord();
+	uint b = getVarOrWord();
+	uint c = getVarOrByte();
+	uint d = getVarOrByte();
+	o_pathfind(a, b, c, d);
+}
 
-		case 163:{									/* play sound */
-				o_playSFX(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_scnTxtLongText(bool &cond, int &ret) {
+	// 179: conversation responses and room descriptions
+	uint vgaSpriteId = getVarOrByte();
+	uint color = getVarOrByte();
+	uint stringId = getVarOrByte();
+	uint speechId = 0;
 
-		case 164:{
-				_showPreposition = true;
-				o_setup_cond_c();
-				_showPreposition = false;
-			}
-			break;
+	const char *string_ptr = (const char *)getStringPtrByID(_stringIdArray3[stringId]);
+	TextLocation *tl = getTextLocation(vgaSpriteId);
+	if (getFeatures() & GF_TALKIE)
+		speechId = _speechIdArray4[stringId];
 
-		case 165:{									/* item unk1 unk2 is */
-				Item *item = getNextItemPtr();
-				int16 a = getNextWord(), b = getNextWord();
-				condition = (item->adjective == a && item->noun == b);
-			} break;
+	if (_speech && speechId != 0)
+		playSpeech(speechId, vgaSpriteId);
+	if (string_ptr != NULL && _subtitles)
+		printText(vgaSpriteId, color, string_ptr, tl->x, tl->y, tl->width);
+}
 
-		case 166:{									/* set bit2 */
-				setBitFlag(256 + getVarOrByte(), true);
-			}
-			break;
+void SimonEngine::o1_mouseOn(bool &cond, int &ret) {
+	// 180: force mouseOn
+	o_mouseOn();
+}
 
-		case 167:{									/* clear bit2 */
-				setBitFlag(256 + getVarOrByte(), false);
-			}
-			break;
+void SimonEngine::o1_mouseOff(bool &cond, int &ret) {
+	// 181: force mouseOff
+	o_mouseOff();
+}
 
-		case 168:{									/* is bit2 clear */
-				condition = !getBitFlag(256 + getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_loadBeard(bool &cond, int &ret) {
+	// 182: load beard
+	o_loadBeard();
+}
 
-		case 169:{									/* is bit2 set */
-				condition = getBitFlag(256 + getVarOrByte());
-			}
-			break;
+void SimonEngine::o1_unloadBeard(bool &cond, int &ret) {
+	// 183: unload beard
+	o_unloadBeard();
+}
 
-		case 171:{									/* oracle hyperlink on */
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_unloadZone(bool &cond, int &ret) {
+	// 184: clear vgapointer entry
+	o_unloadZone(getVarOrWord());
+}
 
-				hyperLinkOn(getVarOrWord());
-			}
-			break;
+void SimonEngine::o1_loadStrings(bool &cond, int &ret) {
+	// 185: load sound files
+	_soundFileId = getVarOrWord();
+	if (getPlatform() == Common::kPlatformAmiga && getFeatures() & GF_TALKIE) {
+		char buf[10];
+		sprintf(buf, "%d%s", _soundFileId, "Effects");
+		_sound->readSfxFile(buf);
+		sprintf(buf, "%d%s", _soundFileId, "simon");
+		_sound->readVoiceFile(buf);
+	}
+}
 
-		case 172:{									/* oracle hyperlink off */
-				if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o1_unfreezeZones(bool &cond, int &ret) {
+	// 186: vga pointer op 3
+	o_unfreezeBottom();
+}
 
-				hyperLinkOff();
-			}
-			break;
+void SimonEngine::o1_specialFade(bool &cond, int &ret) {
+	// 187: fade to black
+	o_fadeToBlack();
+}
 
-		case 173:{
-				warning("STUB: script opcode 173");
-			}
-			break;
+// -----------------------------------------------------------------------
+// Simon 2 Opcodes
+// -----------------------------------------------------------------------
 
-		case 175:{									/* vga pointer op 1 */
-				o_lockZone();
-			}
-			break;
+void SimonEngine::o2_printLongText(bool &cond, int &ret) {
+	// 70: show string from array
+	const char *str = (const char *)getStringPtrByID(_stringIdArray3[getVarOrByte()]);
+	writeVariable(51, strlen(str) / 53 * 8 + 8);
+	showMessageFormat("%s\n", str);
+}
 
-		case 176:{									/* vga pointer op 2 */
-				o_unlockZone();
-			}
-			break;
+void SimonEngine::o2_rescan(bool &cond, int &ret) {
+	// 83: restart subroutine
+	o_83_helper();
+	ret = -10;
+}
 
-		case 177:{									/* inventory descriptions */
-				o_inventory_descriptions();
-			}
-			break;
+void SimonEngine::o2_animate(bool &cond, int &ret) {
+	// 98: start vga
+	uint vga_res, vgaSpriteId, windowNum, x, y, palette;
+	vga_res = getVarOrWord();
+	vgaSpriteId = getVarOrWord();
+	windowNum = getVarOrByte();
+	x = getVarOrWord();
+	y = getVarOrWord();
+	palette = getVarOrWord();
+	loadSprite(windowNum, vga_res, vgaSpriteId, x, y, palette);
+}
 
-		case 178:{									/* path find */
-				uint a = getVarOrWord();
-				uint b = getVarOrWord();
-				uint c = getVarOrByte();
-				uint d = getVarOrByte();
-				o_pathfind(a, b, c, d);
-			}
-			break;
+void SimonEngine::o2_stopAnimate(bool &cond, int &ret) {
+	// 99: kill sprite
+	uint a = getVarOrWord();
+	uint b = getVarOrWord();
+	o_kill_sprite_simon2(a, b);
+}
 
-		case 179:{									/* conversation responses */
-				uint vgaSpriteId = getVarOrByte();				/* and room descriptions */
-				uint color = getVarOrByte();
-				uint stringId = getVarOrByte();
-				uint speechId = 0;
+void SimonEngine::o2_mouseOff(bool &cond, int &ret) {
+	// 181: force mouseOff
+	o_mouseOff();
+	changeWindow(1);
+	showMessageFormat("\xC");
+}
 
-				const char *string_ptr = (const char *)getStringPtrByID(_stringIdArray3[stringId]);
-				TextLocation *tl = getTextLocation(vgaSpriteId);
-				if (getFeatures() & GF_TALKIE)
-					speechId = _speechIdArray4[stringId];
+void SimonEngine::o2_isShortText(bool &cond, int &ret) {
+	// 188: string2 is
+	uint i = getVarOrByte();
+	uint str = getNextStringID();
+	cond = (str < 20 && _stringIdArray2[i] == str);
+}
 
-				if (_speech && speechId != 0)
-					playSpeech(speechId, vgaSpriteId);
-				if (string_ptr != NULL && _subtitles)
-					printText(vgaSpriteId, color, string_ptr, tl->x, tl->y, tl->width);
-			}
-			break;
+void SimonEngine::o2_clearMarks(bool &cond, int &ret) {
+	// 189: clear_op189_flag
+	_marks = 0;
+}
 
-		case 180:{									/* force mouseOn */
-				o_mouseOn();
-			}
-			break;
+void SimonEngine::o2_waitMark(bool &cond, int &ret) {
+	// 190
+	uint i = getVarOrByte();
+	if (!(_marks & (1 << i)))
+		o_waitForMark(i);
+}
 
-		case 181:{									/* force mouseOff */
-				o_mouseOff();
-				if (getGameType() == GType_SIMON2) {
-					changeWindow(1);
-					showMessageFormat("\xC");
-				}
-			}
-			break;
+// -----------------------------------------------------------------------
+// Feeble Files Opcodes
+// -----------------------------------------------------------------------
 
-		case 182:{									/* load beard */
-				if (getGameType() == GType_FF) {
-					// Load video file
-					debug(1,"Load video file: %s", getStringPtrByID(getNextStringID()));
-				} else if (getGameType() == GType_SIMON2) {
-					goto invalid_opcode;
-				} else {
-					o_loadBeard();
-				}
-			}
-			break;
+void SimonEngine::o3_jumpOut(bool &cond, int &ret) {
+	// 37
+	getVarOrByte();
+	ret = 1;
+}
 
-		case 183:{									/* unload beard */
-				if (getGameType() == GType_FF) {
-					// Play video
-					debug(1, "Play video");
-				} else if (getGameType() == GType_SIMON2) {
-					goto invalid_opcode;
-				} else {
-					o_unloadBeard();
-				}
-			}
-			break;
+void SimonEngine::o3_printLongText(bool &cond, int &ret) {
+	// 70: show string from array
+	int tmp = getVarOrByte();
+	const char *str = (const char *)getStringPtrByID(_stringIdArray3[tmp]);
+	showMessageFormat("%d. %s\n", tmp, str);
+}
 
-		case 184:{									/* clear vgapointer entry */
-				o_unloadZone(getVarOrWord());
-			}
-			break;
+void SimonEngine::o3_oracleTextDown(bool &cond, int &ret) {
+	// 122: oracle text down
+	oracleTextDown();
+}
 
-		case 185:{									/* load sound files */
-				if (getGameType() == GType_SIMON2)
-					goto invalid_opcode;
+void SimonEngine::o3_oracleTextUp(bool &cond, int &ret) {
+	// 123: oracle text up
+	oracleTextUp();
+}
 
-				_soundFileId = getVarOrWord();
-				if (getPlatform() == Common::kPlatformAmiga && getFeatures() & GF_TALKIE) {
-					char buf[10];
-					sprintf(buf, "%d%s", _soundFileId, "Effects");
-					_sound->readSfxFile(buf);
-					sprintf(buf, "%d%s", _soundFileId, "simon");
-					_sound->readVoiceFile(buf);
-				}
+void SimonEngine::o3_ifTime(bool &cond, int &ret) {
+	// 124: if time
+	uint time = getVarOrWord();
+	cond = true;
+	warning("STUB: script opcode 124 (%d)", time);
+}
 
-			}
-			break;
+void SimonEngine::o3_setTime(bool &cond, int &ret) {
+	// 131
+	warning("STUB: script opcode 131");
+}
 
-		case 186:{									/* vga pointer op 3 */
-				o_unfreezeBottom();
-			}
-			break;
+void SimonEngine::o3_loadUserGame(bool &cond, int &ret) {
+	// 133: load game
+	loadGame(readVariable(55));
+}
 
-		case 187:{									/* fade to black */
-				if (getGameType() == GType_FF) {
-					warning("STUB: script opcode 187");
-				} else if (getGameType() == GType_SIMON2) {
-					goto invalid_opcode;
-				} else {
-					o_fadeToBlack();
-				}
-			}
-			break;
+void SimonEngine::o3_listSaveGames(bool &cond, int &ret) {
+	// 134: dummy opcode?
+	listSaveGames(1);
+}
 
-		case 188:									/* string2 is */
-			if (getGameType() == GType_SIMON1)
-				goto invalid_opcode;
-			{
-				uint i = getVarOrByte();
-				uint str = getNextStringID();
-				condition = (str < 20 && _stringIdArray2[i] == str);
-			}
-			break;
+void SimonEngine::o3_checkCD(bool &cond, int &ret) {
+	// 135: switch CD
+	debug(1, "Switch to CD number %d", readVariable(97));
+}
 
-		case 189:{									/* clear_op189_flag */
-				if (getGameType() == GType_SIMON1)
-					goto invalid_opcode;
-				_marks = 0;
-			}
-			break;
+void SimonEngine::o3_screenTextBox(bool &cond, int &ret) {
+	// 161: setup text
+	TextLocation *tl = getTextLocation(getVarOrByte());
 
-		case 190:{
-				uint i;
-				if (getGameType() == GType_SIMON1)
-					goto invalid_opcode;
-				i = getVarOrByte();
-				if (!(_marks & (1 << i)))
-					o_waitForMark(i);
-			}
-			break;
+	tl->x = getVarOrWord();
+	tl->y = getVarOrWord();
+	tl->width = getVarOrWord();
+}
 
-		// Feeble opcodes
-		case 191:
-			if (getBitFlag(83)) {
-				_PVCount1 = 0;
-				_GPVCount1 = 0;
-			} else {
-				_PVCount = 0;
-				_GPVCount = 0;
-			}
-			break;
+void SimonEngine::o3_hyperLinkOn(bool &cond, int &ret) {
+	// 171: oracle hyperlink on
+	hyperLinkOn(getVarOrWord());
+}
 
-		case 192:{
-				uint8 a = getVarOrByte();
-				uint8 b = getVarOrByte();
-				uint8 c = getVarOrByte();
-				uint8 d = getVarOrByte();
-				if (getBitFlag(83)) {
-					_pathValues1[_PVCount1++] = a;
-					_pathValues1[_PVCount1++] = b;
-					_pathValues1[_PVCount1++] = c;
-					_pathValues1[_PVCount1++] = d;
-				} else {
-					_pathValues[_PVCount++] = a;
-					_pathValues[_PVCount++] = b;
-					_pathValues[_PVCount++] = c;
-					_pathValues[_PVCount++] = d;
-				}
-			}
-			break;
+void SimonEngine::o3_hyperLinkOff(bool &cond, int &ret) {
+	// 172: oracle hyperlink off
+	hyperLinkOff();
+}
 
-		case 193:
-			// pause clock
-			warning("STUB: script opcode 193");
-			break;
+void SimonEngine::o3_checkPaths(bool &cond, int &ret) {
+	// 173
+	warning("STUB: script opcode 173");
+}
 
-		case 194:
-			// resume clock
-			warning("STUB: script opcode 194");
-			break;
+void SimonEngine::o3_loadSmack(bool &cond, int &ret) {
+	// 182: load video file
+	debug(1,"Load video file: %s", getStringPtrByID(getNextStringID()));
+}
 
-		case 195:{
-				// Set palette colour?
-				uint blue = getVarOrByte();
-				uint green = getVarOrByte();
-				uint red = getVarOrByte();
-				uint color = getVarOrByte();
-				warning("STUB: script opcode 195 (%d, %d, %d, %d)", blue, green, red, color);
-			}
-			break;
+void SimonEngine::o3_playSmack(bool &cond, int &ret) {
+	// 183: play video
+	debug(1, "Play video");
+}
 
-		case 196:{									/* set bit3 */
-				setBitFlag(512 + getVarOrByte(), true);
-			}
-			break;
+void SimonEngine::o3_centreScroll(bool &cond, int &ret) {
+	// 187
+	warning("STUB: script opcode 187");
+}
 
-		case 197:{									/* clear bit3 */
-				setBitFlag(512 + getVarOrByte(), false);
-			}
-			break;
+void SimonEngine::o3_resetPVCount(bool &cond, int &ret) {
+	// 191
+	if (getBitFlag(83)) {
+		_PVCount1 = 0;
+		_GPVCount1 = 0;
+	} else {
+		_PVCount = 0;
+		_GPVCount = 0;
+	}
+}
 
-		case 198:{									/* is bit3 clear */
-				condition = !getBitFlag(512 + getVarOrByte());
-			}
-			break;
+void SimonEngine::o3_setPathValues(bool &cond, int &ret) {
+	// 192
+	uint8 a = getVarOrByte();
+	uint8 b = getVarOrByte();
+	uint8 c = getVarOrByte();
+	uint8 d = getVarOrByte();
+	if (getBitFlag(83)) {
+		_pathValues1[_PVCount1++] = a;
+		_pathValues1[_PVCount1++] = b;
+		_pathValues1[_PVCount1++] = c;
+		_pathValues1[_PVCount1++] = d;
+	} else {
+		_pathValues[_PVCount++] = a;
+		_pathValues[_PVCount++] = b;
+		_pathValues[_PVCount++] = c;
+		_pathValues[_PVCount++] = d;
+	}
+}
 
-		case 199:{									/* is bit3 set */
-				condition = getBitFlag(512 + getVarOrByte());
-			}
-			break;
+void SimonEngine::o3_stopClock(bool &cond, int &ret) {
+	// 193: pause clock
+	warning("STUB: script opcode 193");
+}
 
-		default:
-		invalid_opcode:;
-			error("Invalid opcode '%d'", opcode);
+void SimonEngine::o3_restartClock(bool &cond, int &ret) {
+	// 194: resume clock
+	warning("STUB: script opcode 194");
+}
+
+void SimonEngine::o3_setColour(bool &cond, int &ret) {
+	// 195: set palette colour?
+	uint blue = getVarOrByte();
+	uint green = getVarOrByte();
+	uint red = getVarOrByte();
+	uint color = getVarOrByte();
+	warning("STUB: script opcode 195 (%d, %d, %d, %d)", blue, green, red, color);
+}
+
+void SimonEngine::o3_b3Set(bool &cond, int &ret) {
+	// 196: set bit3
+	setBitFlag(512 + getVarOrByte(), true);
+}
+
+void SimonEngine::o3_b3Clear(bool &cond, int &ret) {
+	// 197: clear bit3
+	setBitFlag(512 + getVarOrByte(), false);
+}
+
+void SimonEngine::o3_b3Zero(bool &cond, int &ret) {
+	// 198: is bit3 clear
+	cond = !getBitFlag(512 + getVarOrByte());
+}
+
+void SimonEngine::o3_b3NotZero(bool &cond, int &ret) {
+	// 199: is bit3 set
+	cond = getBitFlag(512 + getVarOrByte());
+}
+
+// -----------------------------------------------------------------------
+
+int SimonEngine::runScript() {
+	byte opcode;
+	int ret;
+	bool flag, condition;
+
+	// NOTE: It is tempting to make 'ret' and 'condition' class variables
+	// to avoid having to pass them to each opcode function. Before you
+	// succumb to that temptation, please remember that this function will
+	// be called recursively.
+
+	ret = 0;
+
+	do {
+		if (_continousMainScript)
+			dumpOpcode(_codePtr);
+
+		opcode = getByte();
+		if (opcode == 0xFF)
+			return 0;
+
+
+		if (_runScriptReturn1)
+			return 1;
+
+		/* Invert condition? */
+		flag = false;
+		if (opcode == 0) {
+			flag = true;
+			opcode = getByte();
+			if (opcode == 0xFF)
+				return 0;
 		}
 
-	} while (condition != flag);
+		condition = true;
 
-	return 0;
+		if (opcode > _numOpcodes || !_opcode_table[opcode])
+			error("Invalid opcode '%d' encountered", opcode);
+
+		(this->*_opcode_table[opcode]) (condition, ret);
+	} while (condition != flag && !ret);
+
+	return ret;
 }
 
 int SimonEngine::startSubroutine(Subroutine *sub) {

Modified: scummvm/trunk/engines/simon/simon.cpp
===================================================================
--- scummvm/trunk/engines/simon/simon.cpp	2006-04-06 17:24:26 UTC (rev 21643)
+++ scummvm/trunk/engines/simon/simon.cpp	2006-04-06 17:56:41 UTC (rev 21644)
@@ -483,6 +483,8 @@
 		return -1;
 	}
 
+	setupOpcodes();
+
 	if (getGameType() == GType_FF) {
 		_screenWidth = 640;
 		_screenHeight = 480;

Modified: scummvm/trunk/engines/simon/simon.h
===================================================================
--- scummvm/trunk/engines/simon/simon.h	2006-04-06 17:24:26 UTC (rev 21643)
+++ scummvm/trunk/engines/simon/simon.h	2006-04-06 17:56:41 UTC (rev 21644)
@@ -143,6 +143,11 @@
 
 	void errorString(const char *buf_input, char *buf_output);
 
+	typedef void (SimonEngine::*OpcodeProc) (bool &cond, int &ret);
+	void setupOpcodes();
+	const OpcodeProc *_opcode_table;
+	int _numOpcodes;
+
 	typedef void (SimonEngine::*VgaOpcodeProc) ();
 	void setupVgaOpcodes();
 	const VgaOpcodeProc *_vga_opcode_table;
@@ -799,6 +804,181 @@
 	void vc83_playSoundLoop();
 	void vc84_stopSoundLoop();
 
+	// Opcodes, Simon 1 and later
+	void o1_at(bool &cond, int &ret);
+	void o1_notAt(bool &cond, int &ret);
+	void o1_carried(bool &cond, int &ret);
+	void o1_notCarried(bool &cond, int &ret);
+	void o1_isAt(bool &cond, int &ret);
+	void o1_zero(bool &cond, int &ret);
+	void o1_notZero(bool &cond, int &ret);
+	void o1_eq(bool &cond, int &ret);
+	void o1_notEq(bool &cond, int &ret);
+	void o1_gt(bool &cond, int &ret);
+	void o1_lt(bool &cond, int &ret);
+	void o1_eqf(bool &cond, int &ret);
+	void o1_notEqf(bool &cond, int &ret);
+	void o1_ltf(bool &cond, int &ret);
+	void o1_gtf(bool &cond, int &ret);
+	void o1_chance(bool &cond, int &ret);
+	void o1_isRoom(bool &cond, int &ret);
+	void o1_isObject(bool &cond, int &ret);
+	void o1_state(bool &cond, int &ret);
+	void o1_oflag(bool &cond, int &ret);
+	void o1_destroy(bool &cond, int &ret);
+	void o1_place(bool &cond, int &ret);
+	void o1_copyff(bool &cond, int &ret);
+	void o1_clear(bool &cond, int &ret);
+	void o1_let(bool &cond, int &ret);
+	void o1_add(bool &cond, int &ret);
+	void o1_sub(bool &cond, int &ret);
+	void o1_addf(bool &cond, int &ret);
+	void o1_subf(bool &cond, int &ret);
+	void o1_mul(bool &cond, int &ret);
+	void o1_div(bool &cond, int &ret);
+	void o1_mulf(bool &cond, int &ret);
+	void o1_divf(bool &cond, int &ret);
+	void o1_mod(bool &cond, int &ret);
+	void o1_modf(bool &cond, int &ret);
+	void o1_random(bool &cond, int &ret);
+	void o1_goto(bool &cond, int &ret);
+	void o1_oset(bool &cond, int &ret);
+	void o1_oclear(bool &cond, int &ret);
+	void o1_putBy(bool &cond, int &ret);
+	void o1_inc(bool &cond, int &ret);
+	void o1_dec(bool &cond, int &ret);
+	void o1_setState(bool &cond, int &ret);
+	void o1_print(bool &cond, int &ret);
+	void o1_message(bool &cond, int &ret);
+	void o1_msg(bool &cond, int &ret);
+	void o1_addTextBox(bool &cond, int &ret);
+	void o1_setShortText(bool &cond, int &ret);
+	void o1_setLongText(bool &cond, int &ret);
+	void o1_end(bool &cond, int &ret);
+	void o1_done(bool &cond, int &ret);
+	void o1_printLongText(bool &cond, int &ret);
+	void o1_process(bool &cond, int &ret);
+	void o1_when(bool &cond, int &ret);
+	void o1_if1(bool &cond, int &ret);
+	void o1_if2(bool &cond, int &ret);
+	void o1_isCalled(bool &cond, int &ret);
+	void o1_is(bool &cond, int &ret);
+	void o1_debug(bool &cond, int &ret);
+	void o1_rescan(bool &cond, int &ret);
+	void o1_comment(bool &cond, int &ret);
+	void o1_haltAnimation(bool &cond, int &ret);
+	void o1_restartAnimation(bool &cond, int &ret);
+	void o1_getParent(bool &cond, int &ret);
+	void o1_getNext(bool &cond, int &ret);
+	void o1_getChildren(bool &cond, int &ret);
+	void o1_picture(bool &cond, int &ret);
+	void o1_loadZone(bool &cond, int &ret);
+	void o1_animate(bool &cond, int &ret);
+	void o1_stopAnimate(bool &cond, int &ret);
+	void o1_killAnimate(bool &cond, int &ret);
+	void o1_defWindow(bool &cond, int &ret);
+	void o1_window(bool &cond, int &ret);
+	void o1_cls(bool &cond, int &ret);
+	void o1_closeWindow(bool &cond, int &ret);
+	void o1_addBox(bool &cond, int &ret);
+	void o1_delBox(bool &cond, int &ret);
+	void o1_enableBox(bool &cond, int &ret);
+	void o1_disableBox(bool &cond, int &ret);
+	void o1_moveBox(bool &cond, int &ret);
+	void o1_doIcons(bool &cond, int &ret);
+	void o1_isClass(bool &cond, int &ret);
+	void o1_setClass(bool &cond, int &ret);
+	void o1_unsetClass(bool &cond, int &ret);
+	void o1_waitSync(bool &cond, int &ret);
+	void o1_sync(bool &cond, int &ret);
+	void o1_defObj(bool &cond, int &ret);
+	void o1_here(bool &cond, int &ret);
+	void o1_doClassIcons(bool &cond, int &ret);
+	void o1_playTune(bool &cond, int &ret);
+	void o1_waitEndTune(bool &cond, int &ret);
+	void o1_ifEndTune(bool &cond, int &ret);
+	void o1_setAdjNoun(bool &cond, int &ret);
+	void o1_saveUserGame(bool &cond, int &ret);
+	void o1_loadUserGame(bool &cond, int &ret);
+	void o1_stopTune(bool &cond, int &ret);
+	void o1_pauseGame(bool &cond, int &ret);
+	void o1_copysf(bool &cond, int &ret);
+	void o1_restoreIcons(bool &cond, int &ret);
+	void o1_freezeZones(bool &cond, int &ret);
+	void o1_placeNoIcons(bool &cond, int &ret);
+	void o1_clearTimers(bool &cond, int &ret);
+	void o1_setDollar(bool &cond, int &ret);
+	void o1_isBox(bool &cond, int &ret);
+	void o1_doTable(bool &cond, int &ret);
+	void o1_storeItem(bool &cond, int &ret);
+	void o1_getItem(bool &cond, int &ret);
+	void o1_bSet(bool &cond, int &ret);
+	void o1_bClear(bool &cond, int &ret);
+	void o1_bZero(bool &cond, int &ret);
+	void o1_bNotZero(bool &cond, int &ret);
+	void o1_getOValue(bool &cond, int &ret);
+	void o1_setOValue(bool &cond, int &ret);
+	void o1_ink(bool &cond, int &ret);
+	void o1_screenTextBox(bool &cond, int &ret);
+	void o1_screenTextMsg(bool &cond, int &ret);
+	void o1_playEffect(bool &cond, int &ret);
+	void o1_getDollar2(bool &cond, int &ret);
+	void o1_isAdjNoun(bool &cond, int &ret);
+	void o1_b2Set(bool &cond, int &ret);
+	void o1_b2Clear(bool &cond, int &ret);
+	void o1_b2Zero(bool &cond, int &ret);
+	void o1_b2NotZero(bool &cond, int &ret);
+	void o1_lockZones(bool &cond, int &ret);
+	void o1_unlockZones(bool &cond, int &ret);
+	void o1_screenTextPObj(bool &cond, int &ret);
+	void o1_getPathPosn(bool &cond, int &ret);
+	void o1_scnTxtLongText(bool &cond, int &ret);
+	void o1_mouseOn(bool &cond, int &ret);
+	void o1_mouseOff(bool &cond, int &ret);
+	void o1_loadBeard(bool &cond, int &ret);
+	void o1_unloadBeard(bool &cond, int &ret);
+	void o1_unloadZone(bool &cond, int &ret);
+	void o1_loadStrings(bool &cond, int &ret);
+	void o1_unfreezeZones(bool &cond, int &ret);
+	void o1_specialFade(bool &cond, int &ret);
+
+	// Opcodes, Simon 2 and later
+	void o2_printLongText(bool &cond, int &ret);
+	void o2_rescan(bool &cond, int &ret);
+	void o2_animate(bool &cond, int &ret);
+	void o2_stopAnimate(bool &cond, int &ret);
+	void o2_mouseOff(bool &cond, int &ret);
+	void o2_isShortText(bool &cond, int &ret);
+	void o2_clearMarks(bool &cond, int &ret);
+	void o2_waitMark(bool &cond, int &ret);
+
+	// Opcodes, Feeble Files
+	void o3_jumpOut(bool &cond, int &ret);
+	void o3_printLongText(bool &cond, int &ret);
+	void o3_oracleTextDown(bool &cond, int &ret);
+	void o3_oracleTextUp(bool &cond, int &ret);
+	void o3_ifTime(bool &cond, int &ret);
+	void o3_setTime(bool &cond, int &ret);
+	void o3_loadUserGame(bool &cond, int &ret);
+	void o3_listSaveGames(bool &cond, int &ret);
+	void o3_checkCD(bool &cond, int &ret);
+	void o3_screenTextBox(bool &cond, int &ret);
+	void o3_hyperLinkOn(bool &cond, int &ret);
+	void o3_hyperLinkOff(bool &cond, int &ret);
+	void o3_checkPaths(bool &cond, int &ret);
+	void o3_loadSmack(bool &cond, int &ret);
+	void o3_playSmack(bool &cond, int &ret);
+	void o3_centreScroll(bool &cond, int &ret);
+	void o3_resetPVCount(bool &cond, int &ret);
+	void o3_setPathValues(bool &cond, int &ret);
+	void o3_stopClock(bool &cond, int &ret);
+	void o3_restartClock(bool &cond, int &ret);
+	void o3_setColour(bool &cond, int &ret);
+	void o3_b3Set(bool &cond, int &ret);
+	void o3_b3Clear(bool &cond, int &ret);
+	void o3_b3Zero(bool &cond, int &ret);
+	void o3_b3NotZero(bool &cond, int &ret);
+
 protected:
 	void drawImages(VC10_state *state);
 	void drawImages_Feeble(VC10_state *state);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list