aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorTravis Howell2006-10-05 13:46:48 +0000
committerTravis Howell2006-10-05 13:46:48 +0000
commitdcbad3a1ab92b8c2c6e5ec9939a75d74ce7eb6b3 (patch)
treefee2f1a4343e0d076663594b5b042a97c98625c2 /engines/agos
parent5af4438cd25c7678544d09f6c574d00af4a84625 (diff)
downloadscummvm-rg350-dcbad3a1ab92b8c2c6e5ec9939a75d74ce7eb6b3.tar.gz
scummvm-rg350-dcbad3a1ab92b8c2c6e5ec9939a75d74ce7eb6b3.tar.bz2
scummvm-rg350-dcbad3a1ab92b8c2c6e5ec9939a75d74ce7eb6b3.zip
Fix startup of Elvira 1
svn-id: r24124
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/agos.cpp47
-rw-r--r--engines/agos/agos.h7
-rw-r--r--engines/agos/intern.h10
-rw-r--r--engines/agos/items.cpp46
-rw-r--r--engines/agos/rooms.cpp9
-rw-r--r--engines/agos/vga.cpp28
6 files changed, 132 insertions, 15 deletions
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