aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTorbjörn Andersson2006-04-06 17:56:41 +0000
committerTorbjörn Andersson2006-04-06 17:56:41 +0000
commit1fa1f9520d1a021de6d16fc8dca523c031ea9f84 (patch)
tree539698d9147c7bc048417969ec0a7ebe5be51516 /engines
parent52d1d9ab8e8cf49894fa32ee3414e628dd9577f5 (diff)
downloadscummvm-rg350-1fa1f9520d1a021de6d16fc8dca523c031ea9f84.tar.gz
scummvm-rg350-1fa1f9520d1a021de6d16fc8dca523c031ea9f84.tar.bz2
scummvm-rg350-1fa1f9520d1a021de6d16fc8dca523c031ea9f84.zip
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! svn-id: r21644
Diffstat (limited to 'engines')
-rw-r--r--engines/simon/items.cpp2390
-rw-r--r--engines/simon/simon.cpp2
-rw-r--r--engines/simon/simon.h180
3 files changed, 1542 insertions, 1030 deletions
diff --git a/engines/simon/items.cpp b/engines/simon/items.cpp
index 8a8ecaeda2..2ac85484d3 100644
--- a/engines/simon/items.cpp
+++ b/engines/simon/items.cpp
@@ -34,1215 +34,1545 @@ extern bool isSmartphone(void);
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.
+
+ 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_table = opcode_table;
+ _numOpcodes = ARRAYSIZE(opcode_table);
+
+ 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");
+ }
+}
- do {
- if (_continousMainScript)
- dumpOpcode(_codePtr);
+// -----------------------------------------------------------------------
+// Simon 1 Opcodes
+// -----------------------------------------------------------------------
- opcode = getByte();
- if (opcode == 0xFF)
- return 0;
+void SimonEngine::o1_at(bool &cond, int &ret) {
+ // 1: ptrA parent is
+ cond = (getItem1Ptr()->parent == getNextItemID());
+}
- if (_runScriptReturn1)
- return 1;
+void SimonEngine::o1_notAt(bool &cond, int &ret) {
+ // 2: ptrA parent is not
+ cond = (getItem1Ptr()->parent != getNextItemID());
+}
- /* Invert condition? */
- flag = false;
- if (opcode == 0) {
- flag = true;
- opcode = getByte();
- if (opcode == 0xFF)
- return 0;
- }
+void SimonEngine::o1_carried(bool &cond, int &ret) {
+ // 5: parent is 1
+ cond = (getNextItemPtr()->parent == getItem1ID());
+}
- condition = true;
+void SimonEngine::o1_notCarried(bool &cond, int &ret) {
+ // 6: parent isnot 1
+ cond = (getNextItemPtr()->parent != getItem1ID());
+}
- switch (opcode) {
- case 1:{ /* ptrA parent is */
- condition = (getItem1Ptr()->parent == getNextItemID());
- }
- break;
+void SimonEngine::o1_isAt(bool &cond, int &ret) {
+ // 7: parent is
+ Item *item = getNextItemPtr();
+ cond = (item->parent == getNextItemID());
+}
- case 2:{ /* ptrA parent is not */
- condition = (getItem1Ptr()->parent != getNextItemID());
- }
- break;
+void SimonEngine::o1_zero(bool &cond, int &ret) {
+ // 11: is zero
+ cond = (getNextVarContents() == 0);
+}
- case 5:{ /* parent is 1 */
- condition = (getNextItemPtr()->parent == getItem1ID());
- }
- break;
+void SimonEngine::o1_notZero(bool &cond, int &ret) {
+ // 12: isnot zero
+ cond = (getNextVarContents() != 0);
+}
- case 6:{ /* parent isnot 1 */
- condition = (getNextItemPtr()->parent != getItem1ID());
- }
- break;
+void SimonEngine::o1_eq(bool &cond, int &ret) {
+ // 13: equal
+ uint tmp = getNextVarContents();
+ cond = (tmp == getVarOrWord());
+}
- case 7:{ /* parent is */
- Item *item = getNextItemPtr();
- condition = (item->parent == getNextItemID());
- }
- break;
+void SimonEngine::o1_notEq(bool &cond, int &ret) {
+ // 14: not equal
+ uint tmp = getNextVarContents();
+ cond = (tmp != getVarOrWord());
+}
- case 11:{ /* is zero */
- condition = (getNextVarContents() == 0);
- }
- break;
+void SimonEngine::o1_gt(bool &cond, int &ret) {
+ // 15: is greater
+ uint tmp = getNextVarContents();
+ cond = (tmp > getVarOrWord());
+}
- case 12:{ /* isnot zero */
- condition = (getNextVarContents() != 0);
- }
- break;
+void SimonEngine::o1_lt(bool &cond, int &ret) {
+ // 16: is less
+ uint tmp = getNextVarContents();
+ cond = (tmp < getVarOrWord());
+}
- case 13:{ /* equal */
- 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 14:{ /* not equal */
- uint tmp = getNextVarContents();
- condition = (tmp != getVarOrWord());
- }
- break;
+void SimonEngine::o1_notEqf(bool &cond, int &ret) {
+ // 18: is not equal f
+ uint tmp = getNextVarContents();
+ cond = (tmp != getNextVarContents());
+}
- case 15:{ /* is greater */
- uint tmp = getNextVarContents();
- condition = (tmp > getVarOrWord());
- }
- break;
+void SimonEngine::o1_ltf(bool &cond, int &ret) {
+ // 19: is greater f
+ uint tmp = getNextVarContents();
+ cond = (tmp < getNextVarContents());
+}
- case 16:{ /* is less */
- uint tmp = getNextVarContents();
- condition = (tmp < getVarOrWord());
- }
- break;
+void SimonEngine::o1_gtf(bool &cond, int &ret) {
+ // 20: is less f
+ uint tmp = getNextVarContents();
+ cond = (tmp > getNextVarContents());
+}
- case 17:{ /* is eq f */
- uint tmp = getNextVarContents();
- condition = (tmp == getNextVarContents());
- }
- break;
+void SimonEngine::o1_chance(bool &cond, int &ret) {
+ // 23
+ cond = o_chance(getVarOrWord());
+}
- case 18:{ /* is not equal f */
- uint tmp = getNextVarContents();
- condition = (tmp != getNextVarContents());
- }
- break;
+void SimonEngine::o1_isRoom(bool &cond, int &ret) {
+ // 25: is room
+ cond = isRoom(getNextItemPtr());
+}
- case 19:{ /* is greater f */
- uint tmp = getNextVarContents();
- condition = (tmp < getNextVarContents());
- }
- break;
+void SimonEngine::o1_isObject(bool &cond, int &ret) {
+ // 26: is object
+ cond = isObject(getNextItemPtr());
+}
- case 20:{ /* is less f */
- uint tmp = getNextVarContents();
- condition = (tmp > getNextVarContents());
- }
- break;
+void SimonEngine::o1_state(bool &cond, int &ret) {
+ // 27: item state is
+ Item *item = getNextItemPtr();
+ cond = ((uint) item->state == getVarOrWord());
+}
- case 23:{
- condition = o_chance(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 25:{ /* is room */
- condition = isRoom(getNextItemPtr());
- }
- break;
+void SimonEngine::o1_destroy(bool &cond, int &ret) {
+ // 31: set no parent
+ setItemParent(getNextItemPtr(), NULL);
+}
- case 26:{ /* is object */
- condition = isObject(getNextItemPtr());
- }
- break;
+void SimonEngine::o1_place(bool &cond, int &ret) {
+ // 33: set item parent
+ Item *item = getNextItemPtr();
+ setItemParent(item, getNextItemPtr());
+}
- case 27:{ /* item state is */
- Item *item = getNextItemPtr();
- condition = ((uint) item->state == getVarOrWord());
- }
- break;
+void SimonEngine::o1_copyff(bool &cond, int &ret) {
+ // 36: copy var
+ uint value = getNextVarContents();
+ writeNextVarContents(value);
+}
- 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_clear(bool &cond, int &ret) {
+ // 41: zero var
+ writeNextVarContents(0);
+}
- case 31:{ /* set no parent */
- setItemParent(getNextItemPtr(), NULL);
- }
- break;
+void SimonEngine::o1_let(bool &cond, int &ret) {
+ // 42: set var
+ uint var = getVarOrByte();
+ writeVariable(var, getVarOrWord());
+}
- case 33:{ /* set item parent */
- Item *item = getNextItemPtr();
- setItemParent(item, getNextItemPtr());
- }
- break;
+void SimonEngine::o1_add(bool &cond, int &ret) {
+ // 43: add
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) + getVarOrWord());
+}
- case 36:{ /* copy var */
- uint value = getNextVarContents();
- writeNextVarContents(value);
- }
- break;
+void SimonEngine::o1_sub(bool &cond, int &ret) {
+ // 44: sub
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) - getVarOrWord());
+}
- case 37:{
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+void SimonEngine::o1_addf(bool &cond, int &ret) {
+ // 45: add f
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) + getNextVarContents());
+}
- getVarOrByte();
- _runScriptReturn1 = 1;
- }
- break;
+void SimonEngine::o1_subf(bool &cond, int &ret) {
+ // 46: sub f
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) - getNextVarContents());
+}
- case 41:{ /* zero var */
- writeNextVarContents(0);
- }
- break;
+void SimonEngine::o1_mul(bool &cond, int &ret) {
+ // 47: mul
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) * getVarOrWord());
+}
- case 42:{ /* set var */
- uint var = getVarOrByte();
- writeVariable(var, getVarOrWord());
- }
- 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 43:{ /* add */
- uint var = getVarOrByte();
- writeVariable(var, readVariable(var) + getVarOrWord());
- }
- break;
+void SimonEngine::o1_mulf(bool &cond, int &ret) {
+ // 49: mul f
+ uint var = getVarOrByte();
+ writeVariable(var, readVariable(var) * getNextVarContents());
+}
- case 44:{ /* sub */
- 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 45:{ /* add f */
- uint var = getVarOrByte();
- writeVariable(var, readVariable(var) + getNextVarContents());
- }
- 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 46:{ /* sub 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 47:{ /* mul */
- uint var = getVarOrByte();
- writeVariable(var, readVariable(var) * getVarOrWord());
- }
- break;
+void SimonEngine::o1_random(bool &cond, int &ret) {
+ // 53: random
+ uint var = getVarOrByte();
+ uint value = (uint16)getVarOrWord();
- case 48:{ /* div */
- uint var = getVarOrByte();
- int value = getVarOrWord();
- if (value == 0)
- error("Division by zero in div");
- 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 49:{ /* mul f */
- uint var = getVarOrByte();
- writeVariable(var, readVariable(var) * getNextVarContents());
- }
- break;
+void SimonEngine::o1_goto(bool &cond, int &ret) {
+ // 55: set itemA parent
+ setItemParent(getItem1Ptr(), getNextItemPtr());
+}
- 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_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;
+}
- case 51:{ /* mod */
- uint var = getVarOrByte();
- int value = getVarOrWord();
- if (value == 0)
- error("Division by zero in mod");
- writeVariable(var, readVariable(var) % value);
- }
- 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 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_putBy(bool &cond, int &ret) {
+ // 58: make siblings
+ Item *item = getNextItemPtr();
+ setItemParent(item, derefItem(getNextItemPtr()->parent));
+}
- case 53:{ /* random */
- uint var = getVarOrByte();
- uint value = (uint16)getVarOrWord();
+void SimonEngine::o1_inc(bool &cond, int &ret) {
+ // 59: item inc state
+ Item *item = getNextItemPtr();
+ if (item->state <= 30000)
+ setItemState(item, item->state + 1);
+}
- // 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_dec(bool &cond, int &ret) {
+ // 60: item dec state
+ Item *item = getNextItemPtr();
+ if (item->state >= 0)
+ setItemState(item, item->state - 1);
+}
- case 55:{ /* set itemA parent */
- setItemParent(getItem1Ptr(), getNextItemPtr());
- }
- 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 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_print(bool &cond, int &ret) {
+ // 62: show int
+ showMessageFormat("%d", getNextVarContents());
+}
- 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_message(bool &cond, int &ret) {
+ // 63: show string nl
+ showMessageFormat("%s\n", getStringPtrByID(getNextStringID()));
+}
- case 58:{ /* make siblings */
- Item *item = getNextItemPtr();
- setItemParent(item, derefItem(getNextItemPtr()->parent));
- }
- break;
+void SimonEngine::o1_msg(bool &cond, int &ret) {
+ // 64: show string
+ showMessageFormat("%s", getStringPtrByID(getNextStringID()));
+}
- case 59:{ /* item inc state */
- Item *item = getNextItemPtr();
- if (item->state <= 30000)
- setItemState(item, item->state + 1);
- }
- 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 60:{ /* item dec state */
- Item *item = getNextItemPtr();
- if (item->state >= 0)
- setItemState(item, item->state - 1);
- }
- 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 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_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 62:{ /* show int */
- showMessageFormat("%d", getNextVarContents());
- }
- break;
+void SimonEngine::o1_end(bool &cond, int &ret) {
+ // 68: exit interpreter
+ shutdown();
+}
- case 63:{ /* show string nl */
- showMessageFormat("%s\n", getStringPtrByID(getNextStringID()));
- }
- break;
+void SimonEngine::o1_done(bool &cond, int &ret) {
+ // 69: return 1
+ ret = 1;
+}
- case 64:{ /* show string */
- showMessageFormat("%s", getStringPtrByID(getNextStringID()));
- }
- 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 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_process(bool &cond, int &ret) {
+ // 71: start subroutine
+ Subroutine *sub = getSubroutineByID(getVarOrWord());
+ if (sub != NULL)
+ startSubroutine(sub);
+}
- case 66:{ /* set item name */
- uint var = getVarOrByte();
- uint stringId = getNextStringID();
- if (var < 20)
- _stringIdArray2[var] = stringId;
- }
- break;
+void SimonEngine::o1_when(bool &cond, int &ret) {
+ // 76: add timeout
+ uint timeout = getVarOrWord();
+ addTimeEvent(timeout, getVarOrWord());
+}
- 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_if1(bool &cond, int &ret) {
+ // 77: has item minus 1
+ cond = _subjectItem != NULL;
+}
- case 68:{ /* exit interpreter */
- shutdown();
- }
- break;
+void SimonEngine::o1_if2(bool &cond, int &ret) {
+ // 78: has item minus 3
+ cond = _objectItem != NULL;
+}
- case 69:{ /* return 1 */
- return 1;
- }
+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 70:{ /* show string from array */
- const char *str = (const char *)getStringPtrByID(_stringIdArray3[getVarOrByte()]);
+void SimonEngine::o1_is(bool &cond, int &ret) {
+ // 80: item equal
+ cond = getNextItemPtr() == getNextItemPtr();
+}
- if (getGameType() == GType_SIMON2) {
- writeVariable(51, strlen(str) / 53 * 8 + 8);
- }
+void SimonEngine::o1_debug(bool &cond, int &ret) {
+ // 82: debug opcode
+ getVarOrByte();
+}
- showMessageFormat("%s\n", str);
- }
- break;
+void SimonEngine::o1_rescan(bool &cond, int &ret) {
+ // 83: restart subroutine
+ ret = -10;
+}
- case 71:{ /* start subroutine */
- Subroutine *sub = getSubroutineByID(getVarOrWord());
- if (sub != NULL)
- startSubroutine(sub);
- }
- break;
+void SimonEngine::o1_comment(bool &cond, int &ret) {
+ // 87: comment
+ getNextStringID();
+}
- case 76:{ /* add timeout */
- uint timeout = getVarOrWord();
- addTimeEvent(timeout, getVarOrWord());
- }
- break;
+void SimonEngine::o1_haltAnimation(bool &cond, int &ret) {
+ // 88: stop animation
+ _lockWord |= 0x10;
+}
- case 77:{ /* has item minus 1 */
- condition = _subjectItem != NULL;
- }
- break;
+void SimonEngine::o1_restartAnimation(bool &cond, int &ret) {
+ // 89: restart animation
+ _lockWord &= ~0x10;
+}
- case 78:{ /* has item minus 3 */
- condition = _objectItem != NULL;
- }
- 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 79:{ /* childstruct fr2 is */
- SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
- uint stringId = getNextStringID();
- condition = (subObject != NULL) && subObject->objectName == stringId;
- }
- break;
+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 80:{ /* item equal */
- condition = getNextItemPtr() == getNextItemPtr();
- }
- 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 82:{ /* debug opcode */
- getVarOrByte();
- }
- break;
+void SimonEngine::o1_picture(bool &cond, int &ret) {
+ // 96
+ uint val = getVarOrWord();
+ o_set_video_mode(getVarOrByte(), val);
+}
- case 83:{ /* restart subroutine */
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF)
- o_83_helper();
- return -10;
- }
+void SimonEngine::o1_loadZone(bool &cond, int &ret) {
+ // 97: load vga
+ o_loadZone(getVarOrWord());
+}
- case 87:{ /* comment */
- getNextStringID();
- }
- 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 88:{ /* stop animation */
- _lockWord |= 0x10;
- }
- break;
+void SimonEngine::o1_stopAnimate(bool &cond, int &ret) {
+ // 99: kill sprite
+ o_kill_sprite_simon1(getVarOrWord());
+}
- case 89:{ /* restart animation */
- _lockWord &= ~0x10;
- }
- break;
+void SimonEngine::o1_killAnimate(bool &cond, int &ret) {
+ // 100: vga reset
+ o_vga_reset();
+}
- 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_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 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_window(bool &cond, int &ret) {
+ // 102
+ changeWindow(getVarOrByte() & 7);
+}
- 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_cls(bool &cond, int &ret) {
+ // 103
+ o_unk_103();
+}
- case 96:{
- uint val = getVarOrWord();
- o_set_video_mode(getVarOrByte(), val);
- }
- break;
+void SimonEngine::o1_closeWindow(bool &cond, int &ret) {
+ // 104
+ closeWindow(getVarOrByte() & 7);
+}
- case 97:{ /* load vga */
- o_loadZone(getVarOrWord());
- }
- 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;
+
+ id = id % 1000;
+
+ 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;
+
+ 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 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_delBox(bool &cond, int &ret) {
+ // 108: delete hitarea
+ delete_hitarea(getVarOrWord());
+}
- 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_enableBox(bool &cond, int &ret) {
+ // 109: clear hitarea bit 0x40
+ clear_hitarea_bit_0x40(getVarOrWord());
+}
- case 100:{ /* vga reset */
- o_vga_reset();
- }
- break;
+void SimonEngine::o1_disableBox(bool &cond, int &ret) {
+ // 110: set hitarea bit 0x40
+ set_hitarea_bit_0x40(getVarOrWord());
+}
- 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;
+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);
+}
- case 102:{
- changeWindow(getVarOrByte() & 7);
- }
- break;
+void SimonEngine::o1_doIcons(bool &cond, int &ret) {
+ // 114
+ Item *item = getNextItemPtr();
+ uint num = getVarOrByte();
+ mouseOff();
+ drawIconArray(num, item, 0, 0);
+ mouseOn();
+}
- case 103:{
- o_unk_103();
- }
- break;
+void SimonEngine::o1_isClass(bool &cond, int &ret) {
+ // 115: item has flag
+ Item *item = getNextItemPtr();
+ cond = (item->classFlags & (1 << getVarOrByte())) != 0;
+}
- case 104:{
- closeWindow(getVarOrByte() & 7);
- }
- break;
+void SimonEngine::o1_setClass(bool &cond, int &ret) {
+ // 116: item set flag
+ Item *item = getNextItemPtr();
+ item->classFlags |= (1 << getVarOrByte());
+}
- case 107:{ /* add item hitarea */
- uint flags = 0;
- uint id = getVarOrWord();
- uint params = id / 1000;
- uint x, y, w, h, verb;
- Item *item;
-
- id = id % 1000;
-
- 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;
-
- 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_unsetClass(bool &cond, int &ret) {
+ // 117: item clear flag
+ Item *item = getNextItemPtr();
+ item->classFlags &= ~(1 << getVarOrByte());
+}
- case 108:{ /* delete hitarea */
- delete_hitarea(getVarOrWord());
- }
- break;
+void SimonEngine::o1_waitSync(bool &cond, int &ret) {
+ // 119: wait vga
+ uint var = getVarOrWord();
+ _scriptVar2 = (var == 200);
- case 109:{ /* clear hitarea bit 0x40 */
- clear_hitarea_bit_0x40(getVarOrWord());
- }
- break;
+ if (var != 200 || !_skipVgaWait)
+ o_waitForSync(var);
+ _skipVgaWait = false;
+}
- case 110:{ /* set hitarea bit 0x40 */
- set_hitarea_bit_0x40(getVarOrWord());
- }
- break;
+void SimonEngine::o1_sync(bool &cond, int &ret) {
+ // 120: sync
+ o_sync(getVarOrWord());
+}
- case 111:{ /* set hitarea xy */
- uint hitarea_id = getVarOrWord();
- uint x = getVarOrWord();
- uint y = getVarOrWord();
- moveBox(hitarea_id, x, y);
- }
- break;
+void SimonEngine::o1_defObj(bool &cond, int &ret) {
+ // 121: set vga item
+ uint slot = getVarOrByte();
+ _vcItemArray[slot] = getNextItemPtr();
+}
- case 114:{
- Item *item = getNextItemPtr();
- uint num = getVarOrByte();
- mouseOff();
- drawIconArray(num, item, 0, 0);
- mouseOn();
- }
- 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 115:{ /* item has flag */
- Item *item = getNextItemPtr();
- condition = (item->classFlags & (1 << getVarOrByte())) != 0;
- }
- break;
+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();
+}
- case 116:{ /* item set flag */
- Item *item = getNextItemPtr();
- item->classFlags |= (1 << getVarOrByte());
- }
- break;
+void SimonEngine::o1_playTune(bool &cond, int &ret) {
+ // 127: deals with music
+ o_playMusic();
+}
- case 117:{ /* item clear flag */
- Item *item = getNextItemPtr();
- item->classFlags &= ~(1 << getVarOrByte());
- }
- break;
+void SimonEngine::o1_waitEndTune(bool &cond, int &ret) {
+ // 128: dummy instruction
+ getVarOrWord();
+}
- case 119:{ /* wait vga */
- uint var = getVarOrWord();
- _scriptVar2 = (var == 200);
+void SimonEngine::o1_ifEndTune(bool &cond, int &ret) {
+ // 129: dummy instruction
+ getVarOrWord();
+ cond = true;
+}
- if (var != 200 || !_skipVgaWait)
- o_waitForSync(var);
- _skipVgaWait = false;
- }
- break;
+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();
+ }
+}
- case 120:{
- o_sync(getVarOrWord());
- }
- 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 121:{ /* set vga item */
- uint slot = getVarOrByte();
- _vcItemArray[slot] = getNextItemPtr();
- }
- break;
+void SimonEngine::o1_loadUserGame(bool &cond, int &ret) {
+ // 133: load game
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+ o_loadGame();
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+}
- case 122:{ /* oracle text down */
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+void SimonEngine::o1_stopTune(bool &cond, int &ret) {
+ // 134: dummy opcode?
+ midi.stop();
+ _lastMusicPlayed = -1;
+}
- oracleTextDown();
- }
- break;
+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);
+}
- case 123:{ /* oracle text down */
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+void SimonEngine::o1_copysf(bool &cond, int &ret) {
+ // 136: set var to item unk3
+ Item *item = getNextItemPtr();
+ writeNextVarContents(item->state);
+}
- oracleTextUp();
- }
- break;
+void SimonEngine::o1_restoreIcons(bool &cond, int &ret) {
+ // 137
+ o_restoreIconArray(getVarOrByte());
+}
- case 124:{ /* if time */
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+void SimonEngine::o1_freezeZones(bool &cond, int &ret) {
+ // 138: vga pointer op 4
+ o_freezeBottom();
+}
- uint time = getVarOrWord();
- condition = 1;
- warning("STUB: script opcode 124 (%d)", time);
- }
- break;
+void SimonEngine::o1_placeNoIcons(bool &cond, int &ret) {
+ // 139: set parent special
+ Item *item = getNextItemPtr();
+ _noParentNotify = true;
+ setItemParent(item, getNextItemPtr());
+ _noParentNotify = false;
+}
- case 125:{ /* item is sibling with item 1 */
- Item *item = getNextItemPtr();
- condition = (getItem1Ptr()->parent == item->parent);
- }
- break;
+void SimonEngine::o1_clearTimers(bool &cond, int &ret) {
+ // 140: del te and add one
+ killAllTimers();
+ addTimeEvent(3, 0xA0);
+}
- case 126:{
- Item *item = getNextItemPtr();
- uint num = getVarOrByte();
- uint a = 1 << getVarOrByte();
- mouseOff();
- drawIconArray(num, item, 1, a);
- mouseOn();
- }
- 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 127:{ /* deals with music */
- o_playMusic();
- }
- break;
+void SimonEngine::o1_isBox(bool &cond, int &ret) {
+ // 142: is hitarea 0x40 clear
+ cond = is_hitarea_0x40_clear(getVarOrWord());
+}
- case 128:{ /* dummy instruction */
- getVarOrWord();
- }
- 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 129:{ /* dummy instruction */
- getVarOrWord();
- condition = true;
- }
- break;
+void SimonEngine::o1_storeItem(bool &cond, int &ret) {
+ // 151: set array6 to item
+ uint var = getVarOrByte();
+ Item *item = getNextItemPtr();
+ _itemArray6[var] = 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_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 131:{
- warning("STUB: script opcode 131");
- }
- break;
+void SimonEngine::o1_bSet(bool &cond, int &ret) {
+ // 153: set bit
+ setBitFlag(getVarOrByte(), true);
+}
- case 132:{ /* save game */
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- o_saveGame();
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
- }
- break;
+void SimonEngine::o1_bClear(bool &cond, int &ret) {
+ // 154: clear bit
+ setBitFlag(getVarOrByte(), false);
+}
- 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_bZero(bool &cond, int &ret) {
+ // 155: is bit clear
+ cond = !getBitFlag(getVarOrByte());
+}
- case 134:{ /* dummy opcode? */
- if (getGameType() == GType_FF) {
- listSaveGames(1);
- } else {
- midi.stop();
- _lastMusicPlayed = -1;
- }
- }
- break;
+void SimonEngine::o1_bNotZero(bool &cond, int &ret) {
+ // 156: is bit set
+ uint bit = getVarOrByte();
- 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;
+ // WORKAROUND: Fix for glitch in some versions
+ if (getGameType() == GType_SIMON1 && _subroutine == 2962 && bit == 63) {
+ bit = 50;
+ }
- case 136:{ /* set var to item unk3 */
- Item *item = getNextItemPtr();
- writeNextVarContents(item->state);
- }
- break;
+ cond = getBitFlag(bit);
+}
- case 137:{
- o_restoreIconArray(getVarOrByte());
- }
- 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 138:{ /* vga pointer op 4 */
- o_freezeBottom();
- }
- break;
+ if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
+ uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
+ writeNextVarContents(subObject->objectFlagValue[offs]);
+ } else {
+ writeNextVarContents(0);
+ }
+}
- case 139:{ /* set parent special */
- Item *item = getNextItemPtr();
- _noParentNotify = true;
- setItemParent(item, getNextItemPtr());
- _noParentNotify = false;
- }
- 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 140:{ /* del te and add one */
- killAllTimers();
- addTimeEvent(3, 0xA0);
- }
- break;
+ if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
+ uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
+ subObject->objectFlagValue[offs] = value;
+ }
+}
- case 141:{ /* set m1 or m3 */
- uint which = getVarOrByte();
- Item *item = getNextItemPtr();
- if (which == 1) {
- _subjectItem = item;
- } else {
- _objectItem = item;
- }
- }
- break;
+void SimonEngine::o1_ink(bool &cond, int &ret) {
+ // 160
+ o_setTextColor(getVarOrByte());
+}
- case 142:{ /* is hitarea 0x40 clear */
- condition = is_hitarea_0x40_clear(getVarOrWord());
- }
- break;
+void SimonEngine::o1_screenTextBox(bool &cond, int &ret) {
+ // 161: setup text
+ TextLocation *tl = getTextLocation(getVarOrByte());
- 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;
+ tl->x = getVarOrWord();
+ tl->y = getVarOrByte();
+ tl->width = getVarOrWord();
+}
+
+void SimonEngine::o1_screenTextMsg(bool &cond, int &ret) {
+ // 162: print string
+ o_printStr();
+}
- case 151:{ /* set array6 to item */
- uint var = getVarOrByte();
- Item *item = getNextItemPtr();
- _itemArray6[var] = item;
- }
- break;
+void SimonEngine::o1_playEffect(bool &cond, int &ret) {
+ // 163: play sound
+ o_playSFX(getVarOrWord());
+}
- 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_getDollar2(bool &cond, int &ret) {
+ // 164
+ _showPreposition = true;
+ o_setup_cond_c();
+ _showPreposition = false;
+}
- case 153:{ /* set bit */
- setBitFlag(getVarOrByte(), true);
- 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 154:{ /* clear bit */
- setBitFlag(getVarOrByte(), false);
- break;
- }
+void SimonEngine::o1_b2Set(bool &cond, int &ret) {
+ // 166: set bit2
+ setBitFlag(256 + getVarOrByte(), true);
+}
- case 155:{ /* is bit clear */
- condition = !getBitFlag(getVarOrByte());
- }
- break;
+void SimonEngine::o1_b2Clear(bool &cond, int &ret) {
+ // 167: clear bit2
+ setBitFlag(256 + getVarOrByte(), 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_b2Zero(bool &cond, int &ret) {
+ // 168: is bit2 clear
+ cond = !getBitFlag(256 + getVarOrByte());
+}
- case 157:{ /* get item int prop */
- Item *item = getNextItemPtr();
- SubObject *subObject = (SubObject *)findChildOfType(item, 2);
- uint prop = getVarOrByte();
+void SimonEngine::o1_b2NotZero(bool &cond, int &ret) {
+ // 169: is bit2 set
+ cond = getBitFlag(256 + getVarOrByte());
+}
- 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_lockZones(bool &cond, int &ret) {
+ // 175: vga pointer op 1
+ o_lockZone();
+}
- case 158:{ /* set item prop */
- Item *item = getNextItemPtr();
- SubObject *subObject = (SubObject *)findChildOfType(item, 2);
- uint prop = getVarOrByte();
- int value = getVarOrWord();
+void SimonEngine::o1_unlockZones(bool &cond, int &ret) {
+ // 176: vga pointer op 2
+ o_unlockZone();
+}
- if (subObject != NULL && subObject->objectFlags & (1 << prop) && prop < 16) {
- uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
- subObject->objectFlagValue[offs] = value;
- }
- }
- break;
+void SimonEngine::o1_screenTextPObj(bool &cond, int &ret) {
+ // 177: inventory descriptions
+ o_inventory_descriptions();
+}
- case 160:{
- o_setTextColor(getVarOrByte());
- }
- 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 161:{ /* setup text */
- TextLocation *tl = getTextLocation(getVarOrByte());
+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;
+
+ const char *string_ptr = (const char *)getStringPtrByID(_stringIdArray3[stringId]);
+ TextLocation *tl = getTextLocation(vgaSpriteId);
+ if (getFeatures() & GF_TALKIE)
+ speechId = _speechIdArray4[stringId];
+
+ if (_speech && speechId != 0)
+ playSpeech(speechId, vgaSpriteId);
+ if (string_ptr != NULL && _subtitles)
+ printText(vgaSpriteId, color, string_ptr, tl->x, tl->y, tl->width);
+}
- tl->x = getVarOrWord();
- if (getGameType() == GType_FF)
- tl->y = getVarOrWord();
- else
- tl->y = getVarOrByte();
- tl->width = getVarOrWord();
- }
- break;
+void SimonEngine::o1_mouseOn(bool &cond, int &ret) {
+ // 180: force mouseOn
+ o_mouseOn();
+}
- case 162:{ /* print string */
- o_printStr();
- }
- break;
+void SimonEngine::o1_mouseOff(bool &cond, int &ret) {
+ // 181: force mouseOff
+ o_mouseOff();
+}
- case 163:{ /* play sound */
- o_playSFX(getVarOrWord());
- }
- break;
+void SimonEngine::o1_loadBeard(bool &cond, int &ret) {
+ // 182: load beard
+ o_loadBeard();
+}
- case 164:{
- _showPreposition = true;
- o_setup_cond_c();
- _showPreposition = false;
- }
- break;
+void SimonEngine::o1_unloadBeard(bool &cond, int &ret) {
+ // 183: unload beard
+ o_unloadBeard();
+}
- case 165:{ /* item unk1 unk2 is */
- Item *item = getNextItemPtr();
- int16 a = getNextWord(), b = getNextWord();
- condition = (item->adjective == a && item->noun == b);
- } break;
+void SimonEngine::o1_unloadZone(bool &cond, int &ret) {
+ // 184: clear vgapointer entry
+ o_unloadZone(getVarOrWord());
+}
- case 166:{ /* set bit2 */
- setBitFlag(256 + getVarOrByte(), true);
- }
- 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 167:{ /* clear bit2 */
- setBitFlag(256 + getVarOrByte(), false);
- }
- break;
+void SimonEngine::o1_unfreezeZones(bool &cond, int &ret) {
+ // 186: vga pointer op 3
+ o_unfreezeBottom();
+}
- case 168:{ /* is bit2 clear */
- condition = !getBitFlag(256 + getVarOrByte());
- }
- break;
+void SimonEngine::o1_specialFade(bool &cond, int &ret) {
+ // 187: fade to black
+ o_fadeToBlack();
+}
- case 169:{ /* is bit2 set */
- condition = getBitFlag(256 + getVarOrByte());
- }
- break;
+// -----------------------------------------------------------------------
+// Simon 2 Opcodes
+// -----------------------------------------------------------------------
- case 171:{ /* oracle hyperlink on */
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+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);
+}
- hyperLinkOn(getVarOrWord());
- }
- break;
+void SimonEngine::o2_rescan(bool &cond, int &ret) {
+ // 83: restart subroutine
+ o_83_helper();
+ ret = -10;
+}
- case 172:{ /* oracle hyperlink off */
- if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2)
- goto invalid_opcode;
+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);
+}
- hyperLinkOff();
- }
- 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 173:{
- warning("STUB: script opcode 173");
- }
- break;
+void SimonEngine::o2_mouseOff(bool &cond, int &ret) {
+ // 181: force mouseOff
+ o_mouseOff();
+ changeWindow(1);
+ showMessageFormat("\xC");
+}
- case 175:{ /* vga pointer op 1 */
- o_lockZone();
- }
- break;
+void SimonEngine::o2_isShortText(bool &cond, int &ret) {
+ // 188: string2 is
+ uint i = getVarOrByte();
+ uint str = getNextStringID();
+ cond = (str < 20 && _stringIdArray2[i] == str);
+}
- case 176:{ /* vga pointer op 2 */
- o_unlockZone();
- }
- break;
+void SimonEngine::o2_clearMarks(bool &cond, int &ret) {
+ // 189: clear_op189_flag
+ _marks = 0;
+}
- case 177:{ /* inventory descriptions */
- o_inventory_descriptions();
- }
- break;
+void SimonEngine::o2_waitMark(bool &cond, int &ret) {
+ // 190
+ uint i = getVarOrByte();
+ if (!(_marks & (1 << i)))
+ o_waitForMark(i);
+}
- case 178:{ /* path find */
- uint a = getVarOrWord();
- uint b = getVarOrWord();
- uint c = getVarOrByte();
- uint d = getVarOrByte();
- o_pathfind(a, b, c, d);
- }
- break;
+// -----------------------------------------------------------------------
+// Feeble Files Opcodes
+// -----------------------------------------------------------------------
- case 179:{ /* conversation responses */
- uint vgaSpriteId = getVarOrByte(); /* and room descriptions */
- uint color = getVarOrByte();
- uint stringId = getVarOrByte();
- uint speechId = 0;
-
- const char *string_ptr = (const char *)getStringPtrByID(_stringIdArray3[stringId]);
- TextLocation *tl = getTextLocation(vgaSpriteId);
- if (getFeatures() & GF_TALKIE)
- speechId = _speechIdArray4[stringId];
-
- 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::o3_jumpOut(bool &cond, int &ret) {
+ // 37
+ getVarOrByte();
+ ret = 1;
+}
- case 180:{ /* force mouseOn */
- o_mouseOn();
- }
- 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 181:{ /* force mouseOff */
- o_mouseOff();
- if (getGameType() == GType_SIMON2) {
- changeWindow(1);
- showMessageFormat("\xC");
- }
- }
- break;
+void SimonEngine::o3_oracleTextDown(bool &cond, int &ret) {
+ // 122: oracle text down
+ oracleTextDown();
+}
- 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_oracleTextUp(bool &cond, int &ret) {
+ // 123: oracle text up
+ oracleTextUp();
+}
- 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_ifTime(bool &cond, int &ret) {
+ // 124: if time
+ uint time = getVarOrWord();
+ cond = true;
+ warning("STUB: script opcode 124 (%d)", time);
+}
- case 184:{ /* clear vgapointer entry */
- o_unloadZone(getVarOrWord());
- }
- break;
+void SimonEngine::o3_setTime(bool &cond, int &ret) {
+ // 131
+ warning("STUB: script opcode 131");
+}
- case 185:{ /* load sound files */
- if (getGameType() == GType_SIMON2)
- goto invalid_opcode;
-
- _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_loadUserGame(bool &cond, int &ret) {
+ // 133: load game
+ loadGame(readVariable(55));
+}
- }
- break;
+void SimonEngine::o3_listSaveGames(bool &cond, int &ret) {
+ // 134: dummy opcode?
+ listSaveGames(1);
+}
- case 186:{ /* vga pointer op 3 */
- o_unfreezeBottom();
- }
- break;
+void SimonEngine::o3_checkCD(bool &cond, int &ret) {
+ // 135: switch CD
+ debug(1, "Switch to CD number %d", readVariable(97));
+}
- 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_screenTextBox(bool &cond, int &ret) {
+ // 161: setup text
+ TextLocation *tl = getTextLocation(getVarOrByte());
- case 188: /* string2 is */
- if (getGameType() == GType_SIMON1)
- goto invalid_opcode;
- {
- uint i = getVarOrByte();
- uint str = getNextStringID();
- condition = (str < 20 && _stringIdArray2[i] == str);
- }
- break;
+ tl->x = getVarOrWord();
+ tl->y = getVarOrWord();
+ tl->width = getVarOrWord();
+}
- case 189:{ /* clear_op189_flag */
- if (getGameType() == GType_SIMON1)
- goto invalid_opcode;
- _marks = 0;
- }
- break;
+void SimonEngine::o3_hyperLinkOn(bool &cond, int &ret) {
+ // 171: oracle hyperlink on
+ hyperLinkOn(getVarOrWord());
+}
- case 190:{
- uint i;
- if (getGameType() == GType_SIMON1)
- goto invalid_opcode;
- i = getVarOrByte();
- if (!(_marks & (1 << i)))
- o_waitForMark(i);
- }
- break;
+void SimonEngine::o3_hyperLinkOff(bool &cond, int &ret) {
+ // 172: oracle hyperlink off
+ hyperLinkOff();
+}
- // Feeble opcodes
- case 191:
- if (getBitFlag(83)) {
- _PVCount1 = 0;
- _GPVCount1 = 0;
- } else {
- _PVCount = 0;
- _GPVCount = 0;
- }
- break;
+void SimonEngine::o3_checkPaths(bool &cond, int &ret) {
+ // 173
+ warning("STUB: script opcode 173");
+}
- 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_loadSmack(bool &cond, int &ret) {
+ // 182: load video file
+ debug(1,"Load video file: %s", getStringPtrByID(getNextStringID()));
+}
- case 193:
- // pause clock
- warning("STUB: script opcode 193");
- break;
+void SimonEngine::o3_playSmack(bool &cond, int &ret) {
+ // 183: play video
+ debug(1, "Play video");
+}
- case 194:
- // resume clock
- warning("STUB: script opcode 194");
- break;
+void SimonEngine::o3_centreScroll(bool &cond, int &ret) {
+ // 187
+ warning("STUB: script opcode 187");
+}
- 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_resetPVCount(bool &cond, int &ret) {
+ // 191
+ if (getBitFlag(83)) {
+ _PVCount1 = 0;
+ _GPVCount1 = 0;
+ } else {
+ _PVCount = 0;
+ _GPVCount = 0;
+ }
+}
- case 196:{ /* set bit3 */
- setBitFlag(512 + getVarOrByte(), true);
- }
- 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 197:{ /* clear bit3 */
- setBitFlag(512 + getVarOrByte(), false);
- }
- break;
+void SimonEngine::o3_stopClock(bool &cond, int &ret) {
+ // 193: pause clock
+ warning("STUB: script opcode 193");
+}
- case 198:{ /* is bit3 clear */
- condition = !getBitFlag(512 + getVarOrByte());
- }
- break;
+void SimonEngine::o3_restartClock(bool &cond, int &ret) {
+ // 194: resume clock
+ warning("STUB: script opcode 194");
+}
- case 199:{ /* is bit3 set */
- condition = getBitFlag(512 + getVarOrByte());
- }
- break;
+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);
+}
- default:
- invalid_opcode:;
- error("Invalid opcode '%d'", opcode);
+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) {
diff --git a/engines/simon/simon.cpp b/engines/simon/simon.cpp
index 7c522c4ab1..906bdb578b 100644
--- a/engines/simon/simon.cpp
+++ b/engines/simon/simon.cpp
@@ -483,6 +483,8 @@ int SimonEngine::init(GameDetector &detector) {
return -1;
}
+ setupOpcodes();
+
if (getGameType() == GType_FF) {
_screenWidth = 640;
_screenHeight = 480;
diff --git a/engines/simon/simon.h b/engines/simon/simon.h
index 34949a4aa9..8c6b2042b2 100644
--- a/engines/simon/simon.h
+++ b/engines/simon/simon.h
@@ -143,6 +143,11 @@ class SimonEngine : public Engine {
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 @@ public:
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);