From 7dd6b31aef45b4cef6009f1968491ba46507c2c8 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Wed, 25 Oct 2006 08:12:05 +0000 Subject: Add more opcodes for Elvira 1/2 svn-id: r24492 --- engines/agos/agos.h | 25 +++++++++++++-- engines/agos/debug.h | 26 +++++++-------- engines/agos/rooms.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++ engines/agos/script_e1.cpp | 25 +++++++++++++++ engines/agos/script_e2.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 211 insertions(+), 16 deletions(-) diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 2ad783c98e..434ee8d207 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -682,15 +682,23 @@ protected: void setup_cond_c_helper(); uint16 getBackExit(int n); - uint16 getDoorOf(Item *item, uint16 d); uint16 getDoorState(Item *item, uint16 d); - uint16 getExitOf_e1(Item *item, uint16 d); uint16 getExitOf(Item *item, uint16 d); - uint16 getExitState(Item *item, uint16 x, uint16 d); void changeDoorState(SubRoom *r, uint16 d, uint16 n); void setDoorState(Item *i, uint16 d, uint16 n); + + // Elvira 1 specific + uint16 getDoorOf(Item *item, uint16 d); + uint16 getExitOf_e1(Item *item, uint16 d); void moveDirn_e1(Item *i, uint x); + + // Elvira 2 specific + int changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s); + uint16 getExitState(Item *item, uint16 x, uint16 d); + void setExitState(Item *i, uint16 n, uint16 d, uint16 s); void moveDirn_e2(Item *i, uint x); + + // Waxworks specific void moveDirn_ww(Item *i, uint x); int canPlace(Item *x, Item *y); @@ -1106,6 +1114,7 @@ public: void oe1_isNotIn(); void oe1_isPlayer(); void oe1_canPut(); + void oe1_create(); void oe1_copyof(); void oe1_copyfo(); void oe1_whatO(); @@ -1113,6 +1122,7 @@ public: void oe1_setFF(); void oe1_moveDirn(); void oe1_score(); + void oe1_look(); void oe1_doClass(); void oe1_pObj(); void oe1_pName(); @@ -1123,6 +1133,8 @@ public: void oe1_getUserItem(); void oe1_whereTo(); void oe1_doorExit(); + void oe1_saveGame(); + void oe1_loadGame(); void oe1_clearUserItem(); void oe1_findMaster(); void oe1_nextMaster(); @@ -1142,6 +1154,7 @@ public: // Opcodes, Elvira 2 only void oe2_moveDirn(); + void oe2_doClass(); void oe2_pObj(); void oe2_loadUserGame(); void oe2_drawItem(); @@ -1155,6 +1168,12 @@ public: void oe2_unk162(); void oe2_setSuperRoom(); void oe2_getSuperRoom(); + void oe2_setExitOpen(); + void oe2_setExitClosed(); + void oe2_setExitLocked(); + void oe2_ifExitOpen(); + void oe2_ifExitClosed(); + void oe2_ifExitLocked(); void oe2_unk177(); void oe2_unk178(); diff --git a/engines/agos/debug.h b/engines/agos/debug.h index 4fe7f12f8d..2323963bb1 100644 --- a/engines/agos/debug.h +++ b/engines/agos/debug.h @@ -86,7 +86,7 @@ static const char *const elvira1_opcodeNameTable[300] = { NULL, NULL, NULL, - NULL, + "I|CREATE", /* 48 */ "I|SET_NO_PARENT", NULL, @@ -148,7 +148,7 @@ static const char *const elvira1_opcodeNameTable[300] = { NULL, NULL, /* 96 */ - NULL, + "|LOOK", "x|END", "x|DONE", NULL, @@ -279,8 +279,8 @@ static const char *const elvira1_opcodeNameTable[300] = { NULL, /* 200 */ NULL, - NULL, - NULL, + "T|SAVE_GAME", + "T|LOAD_GAME", "|NOT", /* 204 */ NULL, @@ -476,7 +476,7 @@ static const char *const elvira2_opcodeNameTable[256] = { NULL, "W|START_SUB", /* 72 */ - NULL, + "IBW|DO_CLASS", "I|PRINT_OBJ", "I|PRINT_NAME", "I|PRINT_CNAME", @@ -593,16 +593,16 @@ static const char *const elvira2_opcodeNameTable[256] = { /* 164 */ NULL, "W|SET_SUPER_ROOM", - "BV|GET_SUPER_ROOM", - NULL, + "V|GET_SUPER_ROOM", + "IWB|SET_EXIT_OPEN", /* 168 */ - NULL, - NULL, - NULL, - NULL, + "IWB|SET_EXIT_CLOSED", + "IWB|SET_EXIT_LOCKED", + "IWB|SET_EXIT_CLOSED", + "IWBJ|IF_EXIT_OPEN", /* 172 */ - NULL, - NULL, + "IWBJ|IF_EXIT_CLOSED", + "IWBJ|IF_EXIT_LOCKED", "W|UNK_174", "|getDollar2", /* 176 */ diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index 9977e66ea4..8154596562 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -191,6 +191,72 @@ void AGOSEngine::moveDirn_e1(Item *i, uint x) { } // Elvira 2 specific +int AGOSEngine::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) { + int b, bd; + uint16 *c; + uint16 mask = 3; + uint16 bs = s; + + switch (d) { + case 0: + b =- (sr->roomX); bd = 2; + if (((n % (sr->roomX * sr->roomY)) / sr->roomX) == 0) + return(0); + else + break; + case 1: + b = 1; bd = 3; + if (((n % (sr->roomX * sr->roomY)) % sr->roomX) == 0) + return 0; + else + break; + case 2: + b = sr->roomX; bd = 0; + if (((n % (sr->roomX * sr->roomY)) / sr->roomX) == (sr->roomY - 1)) + return 0; + else + break; + case 3: + b =- 1; bd = 1; + if (((n % (sr->roomX * sr->roomY)) % sr->roomX) == 1) + return 0; + else + break; + case 4: + b =- (sr->roomX * sr->roomY); bd = 5; + if (n < (sr->roomX * sr->roomY)) + return 0; + else + break; + case 5: + b = sr->roomX * sr->roomY; bd = 4; + if (n > (sr->roomX * sr->roomY * (sr->roomZ - 1))) + return 0; + else + break; + default: + return 0; + } + n--; + c = sr->roomExitStates; + c += n; + d <<= 1; + mask <<= d; + s <<= d; + *c &= ~mask; + *c |= s; + mask = 3; + n += b; + c = sr->roomExitStates; + c += n; + bd <<= 1; + mask <<= bd; + bs <<= bd; + *c &= ~mask; + *c |= bs; + return 1; +} + uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { SubSuperRoom *sr; uint16 mask = 3; @@ -210,6 +276,12 @@ uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { return n; } +void AGOSEngine::setExitState(Item *i, uint16 n, uint16 d, uint16 s) { + SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, 4); + if (sr) + changeExitStates(sr, n, d, s); +} + void AGOSEngine::moveDirn_e2(Item *i, uint x) { SubSuperRoom *sr; Item *d, *p; diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp index 5468e1cb27..9fbe05fc1f 100644 --- a/engines/agos/script_e1.cpp +++ b/engines/agos/script_e1.cpp @@ -63,6 +63,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[36] = &AGOSEngine::o_oflag; op[37] = &AGOSEngine::oe1_canPut; + op[47] = &AGOSEngine::oe1_create; op[48] = &AGOSEngine::o_destroy; op[51] = &AGOSEngine::o_place; @@ -105,6 +106,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[91] = &AGOSEngine::o_message; op[92] = &AGOSEngine::o_msg; + op[96] = &AGOSEngine::oe1_look; op[97] = &AGOSEngine::o_end; op[98] = &AGOSEngine::o_done; @@ -140,6 +142,9 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[198] = &AGOSEngine::o_comment; + op[201] = &AGOSEngine::oe1_saveGame; + op[202] = &AGOSEngine::oe1_loadGame; + op[206] = &AGOSEngine::o_getParent; op[207] = &AGOSEngine::o_getNext; op[208] = &AGOSEngine::o_getChildren; @@ -290,6 +295,11 @@ void AGOSEngine::oe1_canPut() { setScriptCondition(canPlace(item1, item2) == 0); } +void AGOSEngine::oe1_create() { + // 47: create + setItemParent(getNextItemPtr(), derefItem(me()->parent)); +} + void AGOSEngine::oe1_copyof() { // 54: copy of Item *item = getNextItemPtr(); @@ -337,6 +347,11 @@ void AGOSEngine::oe1_score() { showMessageFormat("Your score is %ld.\n", p->score); } +void AGOSEngine::oe1_look() { + // 96: look + debug(0, "oe1_look: stub"); +} + void AGOSEngine::oe1_doClass() { // 106: do class Item *i = getNextItemPtr(); @@ -461,6 +476,16 @@ void AGOSEngine::oe1_doorExit() { writeVariable(f, 255); } +void AGOSEngine::oe1_saveGame() { + // 201: save game + debug(0, "oe1_saveGame: stub (%s)", getStringPtrByID(getNextStringID())); +} + +void AGOSEngine::oe1_loadGame() { + // 202: load game + debug(0, "oe1_loadGame: stub (%s)", getStringPtrByID(getNextStringID())); +} + void AGOSEngine::oe1_clearUserItem() { // 178: clear user item Item *i = getNextItemPtr(); diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp index fc573ea63a..3594255d5b 100644 --- a/engines/agos/script_e2.cpp +++ b/engines/agos/script_e2.cpp @@ -42,6 +42,7 @@ void AGOSEngine::setupElvira2Opcodes(OpcodeProc *op) { op[37] = &AGOSEngine::oe1_whatO; op[39] = &AGOSEngine::oe1_weigh; op[54] = &AGOSEngine::oe2_moveDirn; + op[72] = &AGOSEngine::oe2_doClass; op[73] = &AGOSEngine::oe2_pObj; op[74] = &AGOSEngine::oe1_pName; op[75] = &AGOSEngine::oe1_pcName; @@ -66,6 +67,13 @@ void AGOSEngine::setupElvira2Opcodes(OpcodeProc *op) { op[162] = &AGOSEngine::oe2_unk162; op[165] = &AGOSEngine::oe2_setSuperRoom; op[166] = &AGOSEngine::oe2_getSuperRoom; + op[167] = &AGOSEngine::oe2_setExitOpen; + op[168] = &AGOSEngine::oe2_setExitClosed; + op[169] = &AGOSEngine::oe2_setExitLocked; + op[170] = &AGOSEngine::oe2_setExitClosed; + op[171] = &AGOSEngine::oe2_ifExitOpen; + op[172] = &AGOSEngine::oe2_ifExitClosed; + op[173] = &AGOSEngine::oe2_ifExitLocked; op[175] = &AGOSEngine::o_getDollar2; op[177] = &AGOSEngine::oe2_unk177; op[178] = &AGOSEngine::oe2_unk178; @@ -86,6 +94,29 @@ void AGOSEngine::oe2_moveDirn() { moveDirn_e2(me(), d); } +void AGOSEngine::oe2_doClass() { + // 72: do class + Item *i = getNextItemPtr(); + byte cm = getByte(); + int16 num = getVarOrWord(); + + _classMask = (cm != 0xFF) ? 1 << cm : 0; + _classLine = (SubroutineLine *)((byte *)_currentTable + _currentLine->next); + if (num == 1) { + _subjectItem = findInByClass(i, (1 << cm)); + if (_subjectItem) + _classMode1 = 1; + else + _classMode1 = 0; + } else { + _objectItem = findInByClass(i, (1 << cm)); + if (_objectItem) + _classMode2 = 1; + else + _classMode2 = 0; + } +} + void AGOSEngine::oe2_pObj() { // 73: print object SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2); @@ -211,6 +242,54 @@ void AGOSEngine::oe2_getSuperRoom() { writeNextVarContents(_superRoomNumber); } +void AGOSEngine::oe2_setExitOpen() { + // 167: set exit open + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setExitState(i, n, d, 1); +} + +void AGOSEngine::oe2_setExitClosed() { + // 168: set exit closed + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setExitState(i, n, d, 2); +} + +void AGOSEngine::oe2_setExitLocked() { + // 169: set exit locked + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setExitState(i, n, d, 3); +} + +void AGOSEngine::oe2_ifExitOpen() { + // 171: if exit open + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setScriptCondition(getExitState(i, n, d) == 1); +} + +void AGOSEngine::oe2_ifExitClosed() { + // 172: if exit closed + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setScriptCondition(getExitState(i, n, d) == 2); +} + +void AGOSEngine::oe2_ifExitLocked() { + // 173: if exit locked + Item *i = getNextItemPtr(); + uint16 n = getVarOrWord(); + uint16 d = getVarOrByte(); + setScriptCondition(getExitState(i, n, d) == 3); +} + void AGOSEngine::oe2_unk177() { // 177: set unknown vga event uint a = getVarOrByte(); -- cgit v1.2.3