aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2006-10-06 00:36:13 +0000
committerTravis Howell2006-10-06 00:36:13 +0000
commitc22289416fb20a603c83ca33724e1198c39706bb (patch)
tree61c2627aa26736fe670039a8bf0df54d1888d73c /engines
parent3dc7c88e067b4fcf8828523b465ab9d377368784 (diff)
downloadscummvm-rg350-c22289416fb20a603c83ca33724e1198c39706bb.tar.gz
scummvm-rg350-c22289416fb20a603c83ca33724e1198c39706bb.tar.bz2
scummvm-rg350-c22289416fb20a603c83ca33724e1198c39706bb.zip
Add more code for Elvira 1/2
svn-id: r24130
Diffstat (limited to 'engines')
-rw-r--r--engines/agos/agos.cpp2
-rw-r--r--engines/agos/agos.h11
-rw-r--r--engines/agos/intern.h1
-rw-r--r--engines/agos/items.cpp34
-rw-r--r--engines/agos/res.cpp1
-rw-r--r--engines/agos/rooms.cpp150
6 files changed, 177 insertions, 22 deletions
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();