From dcbad3a1ab92b8c2c6e5ec9939a75d74ce7eb6b3 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Thu, 5 Oct 2006 13:46:48 +0000 Subject: Fix startup of Elvira 1 svn-id: r24124 --- engines/agos/agos.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- engines/agos/agos.h | 7 +++++++ engines/agos/intern.h | 10 ++++++++++ engines/agos/items.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ engines/agos/rooms.cpp | 9 +++++++-- engines/agos/vga.cpp | 28 ++++++++++++++++++---------- 6 files changed, 132 insertions(+), 15 deletions(-) (limited to 'engines') diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 150c4dd748..f25ee628de 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -775,16 +775,23 @@ void AGOSEngine::setUserFlag(Item *item, int a, int b) { } void AGOSEngine::createPlayer() { - Child *child; + SubPlayer *p; _currentPlayer = _itemArrayPtr[1]; _currentPlayer->adjective = -1; _currentPlayer->noun = 10000; - child = (Child *)allocateChildBlock(_currentPlayer, 3, sizeof(Child)); - if (child == NULL) + p = (SubPlayer *)allocateChildBlock(_currentPlayer, 3, sizeof(SubPlayer)); + if (p == NULL) error("createPlayer: player create failure"); + p->size = 0; + p->weight = 0; + p->strength = 6000; + //p->flag = xxx; + p->level = 1; + p->score = 0; + setUserFlag(_currentPlayer, 0, 0); } @@ -1798,6 +1805,15 @@ void AGOSEngine::skipSpeech() { } } +int AGOSEngine::wordMatch(Item *item, int16 a, int16 n) { + if ((a == -1) && (n == item->noun)) + return 1; + if ((a == item->adjective) && (n == item->noun)) + return 1 ; + + return 0; +} + Item *AGOSEngine::derefItem(uint item) { if (item >= _itemArraySize) { debug(1, "derefItem: invalid item %d", item); @@ -1806,6 +1822,31 @@ Item *AGOSEngine::derefItem(uint item) { return _itemArrayPtr[item]; } +Item *AGOSEngine::findMaster(int16 pe, int16 a, int16 n) { + uint j; + + for (j = 1; j < _itemArraySize; j++) { + Item *item = derefItem(j); + if (wordMatch(item, a, n)) + return item; + } + + return NULL; +} + +Item *AGOSEngine::nextMaster(int16 pe, Item *i, int16 a, int16 n) { + uint j; + uint first = itemPtrToID(i) + 1; + + for (j = first; j < _itemArraySize; j++) { + Item *item = derefItem(j); + if (wordMatch(item, a, n)) + return item; + } + + return NULL; +} + uint AGOSEngine::itemPtrToID(Item *id) { uint i; for (i = 0; i != _itemArraySize; i++) diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 4a54843422..1bf7253804 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -989,6 +989,11 @@ public: void o_unloadZone(); void o_unfreezeZones(); + Item *findMaster(int16 pe, int16 a, int16 n); + Item *nextMaster(int16 pe, Item *item, int16 a, int16 n); + int16 levelOf(Item *item); + int wordMatch(Item *item, int16 a, int16 n); + uint16 getDoorState(Item *item, uint16 d); uint16 getExitOf(Item *item, uint16 d); void moveDirn(Item *i, int x); @@ -1012,6 +1017,8 @@ public: void oe1_setFF(); void oe1_opcode176(); void oe1_opcode178(); + void oe1_findMaster(); + void oe1_nextMaster(); void oe1_zoneDisk(); void oe1_printStats(); diff --git a/engines/agos/intern.h b/engines/agos/intern.h index 64160918c7..99c071583b 100644 --- a/engines/agos/intern.h +++ b/engines/agos/intern.h @@ -56,6 +56,16 @@ struct SubObject : Child { int16 objectFlagValue[1]; }; +struct SubPlayer : Child { + int16 userKey; + int16 size; + int16 weight; + int16 strength; + int16 flags; + int16 level; + int32 score; +}; + struct SubUserChain : Child { uint16 subroutine_id; uint16 chChained; diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp index 2592b850d4..e225c4478f 100644 --- a/engines/agos/items.cpp +++ b/engines/agos/items.cpp @@ -248,6 +248,8 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[152] = &AGOSEngine::o_debug; + op[164] = &AGOSEngine::o1_rescan; + op[176] = &AGOSEngine::oe1_opcode176; op[178] = &AGOSEngine::oe1_opcode178; @@ -260,6 +262,9 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { op[207] = &AGOSEngine::o_getNext; op[208] = &AGOSEngine::o_getChildren; + op[219] = &AGOSEngine::oe1_findMaster; + op[220] = &AGOSEngine::oe1_nextMaster; + op[224] = &AGOSEngine::o_picture; op[225] = &AGOSEngine::o_loadZone; op[226] = &AGOSEngine::o1_animate; @@ -1759,16 +1764,49 @@ void AGOSEngine::oe1_setFF() { } void AGOSEngine::oe1_opcode176() { + // 176 getNextItemPtr(); getVarOrWord(); getNextItemPtr(); } void AGOSEngine::oe1_opcode178() { + // 178 getNextItemPtr(); getVarOrWord(); } +void AGOSEngine::oe1_findMaster() { + // 219: find master + int16 ad, no; + int16 d = getVarOrWord(); + + ad = (d == 1) ? _scriptAdj1 : _scriptAdj2; + no = (d == 1) ? _scriptNoun1 : _scriptNoun2; + + d = getVarOrWord(); + if (d == 1) + _subjectItem = findMaster(levelOf(me()), ad, no); + else + _objectItem = findMaster(levelOf(me()), ad, no); +} + +void AGOSEngine::oe1_nextMaster() { + // 220: next master + int16 ad, no; + Item *item = getNextItemPtr(); + int16 d = getVarOrWord(); + + ad = (d == 1) ? _scriptAdj1 : _scriptAdj2; + no = (d == 1) ? _scriptNoun1 : _scriptNoun2; + + d = getVarOrWord(); + if (d == 1) + _subjectItem = nextMaster(levelOf(me()), item, ad, no); + else + _objectItem = nextMaster(levelOf(me()), item, ad, no); +} + void AGOSEngine::oe1_zoneDisk() { // 267: zone disk getVarOrWord(); @@ -2813,4 +2851,12 @@ void AGOSEngine::stopAnimateSimon2(uint a, uint b) { _lockWord &= ~0x8000; } +int16 AGOSEngine::levelOf(Item *item) { + SubPlayer *p = (SubPlayer *) findChildOfType(item, 3); + if(p == NULL) + return 0; + + return p->level; +} + } // End of namespace AGOS diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index f980d9eeae..66876cd8bb 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -116,8 +116,13 @@ bool AGOSEngine::loadRoomItems(uint item) { } while ((i = in.readUint16BE()) != 0) { - _itemArrayPtr[i] = (Item *)allocateItem(sizeof(Item)); - readItemFromGamePc(&in, _itemArrayPtr[i]); + Item *item = derefItem(i); + item = (Item *)allocateItem(sizeof(Item)); + readItemFromGamePc(&in, item); + + item->child = NULL; + item->parent = NULL; + } in.close(); diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index fac6b817d7..dc2e065193 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -1278,20 +1278,28 @@ void AGOSEngine::drawImages(VC10_state *state) { uint offs, offs2; if (getGameType() == GType_ELVIRA) { - if (_windowNum == 2 || _windowNum == 3) { - offs = state->x * 8; - offs2 = state->y; - } else { - offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; - offs2 = (vlut[1] - _video_windows[17] + state->y); - } - } else if (getGameType() == GType_WW) { + //if (_windowNum != 2 && _windowNum != 3) { + // offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; + // offs2 = (vlut[1] - _video_windows[17] + state->y); + //} else { + offs = (vlut[0] * 2 + state->x) * 8; + offs2 = vlut[1] + state->y; + //} + } else if (getGameType() == GType_ELVIRA2) { //if (_windowNum == 4 || _windowNum >= 10) { - offs = state->x * 8; - offs2 = state->y; + // offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; + // offs2 = (vlut[1] - _video_windows[17] + state->y); //} else { + offs = (vlut[0] * 2 + state->x) * 8; + offs2 = vlut[1] + state->y; + //} + } else if (getGameType() == GType_WW) { + //if (_windowNum == 4 || (_windowNum >= 10 && _windowsNum < 28)) { // offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; // offs2 = (vlut[1] - _video_windows[17] + state->y); + //} else { + offs = (vlut[0] * 2 + state->x) * 8; + offs2 = vlut[1] + state->y; //} } else if (getGameType() == GType_SIMON1) { // Allow one section of Simon the Sorcerer 1 introduction to be displayed -- cgit v1.2.3