From c22289416fb20a603c83ca33724e1198c39706bb Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Fri, 6 Oct 2006 00:36:13 +0000 Subject: Add more code for Elvira 1/2 svn-id: r24130 --- engines/agos/agos.cpp | 2 + engines/agos/agos.h | 11 +++- engines/agos/intern.h | 1 + engines/agos/items.cpp | 34 ++++++++--- engines/agos/res.cpp | 1 + engines/agos/rooms.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 177 insertions(+), 22 deletions(-) (limited to 'engines') diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index f25ee628de..ab9a26ee74 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -318,6 +318,8 @@ AGOSEngine::AGOSEngine(OSystem *syst) _nextVgaTimerToProcess = 0; + _superRoomNumber = 0; + memset(_objectArray, 0, sizeof(_objectArray)); memset(_itemStore, 0, sizeof(_itemStore)); diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 1bf7253804..9d9d143289 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -899,6 +899,7 @@ public: void o_mod(); void o_modf(); void o_random(); + void o_moveDirn(); void o_goto(); void o_oset(); void o_oclear(); @@ -994,9 +995,16 @@ public: int16 levelOf(Item *item); int wordMatch(Item *item, int16 a, int16 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); - void moveDirn(Item *i, int x); + uint16 getExitState(Item *item, uint16 x, uint16 d); + void moveDirn_e1(Item *i, uint x); + void moveDirn_e2(Item *i, uint x); + void moveDirn_ww(Item *i, uint x); + + uint _superRoomNumber; int sizeContents(Item *x); int sizeOfRec(Item *o, int d); @@ -1015,6 +1023,7 @@ public: void oe1_sibling(); void oe1_notSibling(); void oe1_setFF(); + void oe1_score(); void oe1_opcode176(); void oe1_opcode178(); void oe1_findMaster(); diff --git a/engines/agos/intern.h b/engines/agos/intern.h index 99c071583b..e38b3fcd01 100644 --- a/engines/agos/intern.h +++ b/engines/agos/intern.h @@ -45,6 +45,7 @@ struct SubSuperRoom : Child { uint16 roomX; uint16 roomY; uint16 roomZ; + uint16 *roomExitStates; uint16 roomExit[1]; }; diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp index e225c4478f..e90201afaf 100644 --- a/engines/agos/items.cpp +++ b/engines/agos/items.cpp @@ -220,6 +220,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[74] = &AGOSEngine::o_modf; op[75] = &AGOSEngine::o_random; + op[76] = &AGOSEngine::o_moveDirn; op[77] = &AGOSEngine::o_goto; op[80] = &AGOSEngine::o_oset; @@ -230,8 +231,10 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[86] = &AGOSEngine::o_dec; op[87] = &AGOSEngine::o_setState; + op[89] = &AGOSEngine::o_print; + op[90] = &AGOSEngine::oe1_score; op[91] = &AGOSEngine::o_message; - op[92] = &AGOSEngine::o_message; + op[92] = &AGOSEngine::o_msg; op[97] = &AGOSEngine::o_end; op[98] = &AGOSEngine::o_done; @@ -319,6 +322,7 @@ void AGOSEngine::setupElvira2Opcodes(OpcodeProc *op) { op[34] = &AGOSEngine::o_copyof; op[35] = &AGOSEngine::o_copyfo; + op[54] = &AGOSEngine::o_moveDirn; op[83] = &AGOSEngine::o1_rescan; op[98] = &AGOSEngine::o1_animate; op[99] = &AGOSEngine::o1_stopAnimate; @@ -357,7 +361,7 @@ void AGOSEngine::setupWaxworksOpcodes(OpcodeProc *op) { // Confirmed op[34] = &AGOSEngine::o_copyof; op[35] = &AGOSEngine::o_copyfo; - op[54] = &AGOSEngine::oww_moveDirn; + op[54] = &AGOSEngine::o_moveDirn; op[55] = &AGOSEngine::oww_goto; op[70] = &AGOSEngine::o1_printLongText; op[83] = &AGOSEngine::o1_rescan; @@ -845,6 +849,20 @@ void AGOSEngine::o_random() { writeVariable(var, _rnd.getRandomNumber(value - 1)); } +void AGOSEngine::o_moveDirn() { + // 54: move direction + int16 d = getVarOrByte(); + + if (getGameType() == GType_WW) { + moveDirn_ww(me(), d); + } else if (getGameType() == GType_ELVIRA2) { + moveDirn_e2(me(), d); + } else { + moveDirn_e1(me(), d); + } + +} + void AGOSEngine::o_goto() { // 55: set itemA parent uint item = getNextItemID(); @@ -1763,6 +1781,12 @@ void AGOSEngine::oe1_setFF() { writeNextVarContents(0xFF); } +void AGOSEngine::oe1_score() { + // 90: score + SubPlayer *p = (SubPlayer *) findChildOfType(me(), 3); + showMessageFormat("Your score is %ld.\n", p->score); +} + void AGOSEngine::oe1_opcode176() { // 176 getNextItemPtr(); @@ -1829,12 +1853,6 @@ void AGOSEngine::oe2_opcode161() { // Waxworks Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::oww_moveDirn() { - // 54: move direction - int16 d = getVarOrByte(); - moveDirn(me(), d); -} - void AGOSEngine::oww_goto() { // 55: set itemA parent uint item = getNextItemID(); diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index 8a7777e41d..ebce435fdf 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -389,6 +389,7 @@ void AGOSEngine::readItemChildren(Common::File *in, Item *item, uint type) { subSuperRoom->roomX = x; subSuperRoom->roomY = y; subSuperRoom->roomZ = z; + subSuperRoom->roomExitStates = (uint16 *)calloc(j, sizeof(uint16)); for (i = k = 0; i != j; i++) subSuperRoom->roomExit[k++] = in->readUint16BE(); diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index 66876cd8bb..b3bf2fccb4 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -30,6 +30,22 @@ using Common::File; namespace AGOS { +uint16 AGOSEngine::getDoorOf(Item *i, uint16 d) { + SubGenExit *g; + Item *x; + + g = (SubGenExit *)findChildOfType(i, 4); + if (g == NULL) + return 0; + + x = derefItem(g->dest[d]); + if (x == NULL) + return 0; + if (findChildOfType(x, 1)) + return 0; + return itemPtrToID(x); +} + uint16 AGOSEngine::getDoorState(Item *item, uint16 d) { uint16 mask = 3; uint16 n; @@ -46,11 +62,30 @@ uint16 AGOSEngine::getDoorState(Item *item, uint16 d) { return n; } +uint16 AGOSEngine::getExitOf_e1(Item *item, uint16 d) { + SubGenExit *g; + Item *x; + + g = (SubGenExit *)findChildOfType(item, 4); + if (g == NULL) + return 0; + + x = derefItem(g->dest[d]); + if (x == NULL) + return 0; + if (findChildOfType(x, 1)) + return itemPtrToID(x); + if (x->state != 0) + return 0; + return x->parent; +} + uint16 AGOSEngine::getExitOf(Item *item, uint16 d) { + SubRoom *subRoom; uint16 x; uint16 y = 0; - SubRoom *subRoom = (SubRoom *)findChildOfType(item, 1); + subRoom = (SubRoom *)findChildOfType(item, 1); if (subRoom == NULL) return 0; x = d; @@ -62,13 +97,84 @@ uint16 AGOSEngine::getExitOf(Item *item, uint16 d) { return subRoom->roomExit[d]; } -void AGOSEngine::moveDirn(Item *i, int x) { - Item *d; +uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { + SubSuperRoom *sr; + uint16 mask = 3; uint16 n; + uint16 *c; + + sr = (SubSuperRoom *)findChildOfType(i, 4); + if (sr == NULL) + return 0; + + c = sr->roomExitStates; + c += x - 1; + d <<= 1; + mask <<= d; + n = *c & mask; + n >>= d; + return n; +} + +void AGOSEngine::moveDirn_e1(Item *i, uint x) { + Item *d, *p; + uint16 n; + + if (i->parent == 0) + return; + + p = derefItem(i->parent); + + n = getExitOf_e1(p, x); + d = derefItem(n); + if (n) { + if (canPlace(i, d)) + return; + + setItemParent(i, d); + return; + } + + d = derefItem(getDoorOf(p, x)); + if (d) { + const byte *name = getStringPtrByID(d->itemName); + if (d->state == 1) + showMessageFormat("%s is closed.\n", name); + else + showMessageFormat("%s is locked.\n", name); + return; + } + + showMessageFormat("You can't go that way.\n"); +} + +void AGOSEngine::moveDirn_e2(Item *i, uint x) { + SubSuperRoom *sr; + Item *d, *p; + uint16 a, n; if (i->parent == 0) return; + p = derefItem(i->parent); + if (findChildOfType(p, 4)) { + n = getExitState(p, _superRoomNumber,x); + if (n == 1) { + sr = (SubSuperRoom *)findChildOfType(p, 4); + switch (x) { + case 0: a = -(sr->roomX); break; + case 1: a = 1; break; + case 2: a = sr->roomX; break; + case 3: a = (uint)-1; break; + case 4: a = -(sr->roomX * sr->roomY); break; + case 5: a = (sr->roomX * sr->roomY); break; + default: return; + } + _superRoomNumber += a; + } + return; + } + n = getExitOf(derefItem(i->parent), x); if (derefItem(n) == NULL) { loadRoomItems(n); @@ -78,9 +184,32 @@ void AGOSEngine::moveDirn(Item *i, int x) { d = derefItem(n); if (d) { n = getDoorState(derefItem(i->parent), x); - if(n == 1) { - if(!canPlace(i,d)) - setItemParent(i,d); + if (n == 1) { + if (!canPlace(i, d)) + setItemParent(i, d); + } + } +} + +void AGOSEngine::moveDirn_ww(Item *i, uint x) { + Item *d; + uint16 n; + + if (i->parent == 0) + return; + + n = getExitOf(derefItem(i->parent), x); + if (derefItem(n) == NULL) { + loadRoomItems(n); + n = getExitOf(derefItem(i->parent), x); + } + + d = derefItem(n); + if (d) { + n = getDoorState(derefItem(i->parent), x); + if (n == 1) { + if(!canPlace(i, d)) + setItemParent(i, d); } } } @@ -116,13 +245,8 @@ bool AGOSEngine::loadRoomItems(uint item) { } while ((i = in.readUint16BE()) != 0) { - Item *item = derefItem(i); - item = (Item *)allocateItem(sizeof(Item)); - readItemFromGamePc(&in, item); - - item->child = NULL; - item->parent = NULL; - + _itemArrayPtr[i] = (Item *)allocateItem(sizeof(Item)); + readItemFromGamePc(&in, _itemArrayPtr[i]); } in.close(); -- cgit v1.2.3