aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/agos/agos.cpp62
-rw-r--r--engines/agos/agos.h16
-rw-r--r--engines/agos/debug.h10
-rw-r--r--engines/agos/icons.cpp8
-rw-r--r--engines/agos/intern.h2
-rw-r--r--engines/agos/items.cpp75
-rw-r--r--engines/agos/res.cpp6
-rw-r--r--engines/agos/saveload.cpp6
8 files changed, 143 insertions, 42 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 171648970a..44c307c06a 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -318,6 +318,9 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_nextVgaTimerToProcess = 0;
+ _classMask = 0;
+ _classMode1 = 0;
+ _classMode2 = 0;
_superRoomNumber = 0;
memset(_objectArray, 0, sizeof(_objectArray));
@@ -776,6 +779,31 @@ void AGOSEngine::setUserFlag(Item *item, int a, int b) {
subUserFlag->userFlags[a] = b;
}
+int AGOSEngine::getUserItem(Item *item, int n) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL)
+ return 0;
+
+ if (n < 0 || n > 0)
+ return 0;
+
+ return subUserFlag->userItems[n];
+}
+
+void AGOSEngine::setUserItem(Item *item, int n, int m) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL) {
+ subUserFlag = (SubUserFlag *) allocateChildBlock(item, 9, sizeof(SubUserFlag));
+ }
+
+ if (n == 0)
+ subUserFlag->userItems[n] = m;
+}
+
void AGOSEngine::createPlayer() {
SubPlayer *p;
@@ -1051,23 +1079,23 @@ void AGOSEngine::unlinkItem(Item *item) {
// the node to remove is first in the parent's children?
if (first == item) {
- parent->child = item->sibling;
+ parent->child = item->next;
item->parent = 0;
- item->sibling = 0;
+ item->next = 0;
return;
}
for (;;) {
if (!first)
error("unlinkItem: parent empty");
- if (first->sibling == 0)
+ if (first->next == 0)
error("unlinkItem: parent does not contain child");
- next = derefItem(first->sibling);
+ next = derefItem(first->next);
if (next == item) {
- first->sibling = next->sibling;
+ first->next = next->next;
item->parent = 0;
- item->sibling = 0;
+ item->next = 0;
return;
}
first = next;
@@ -1084,10 +1112,10 @@ void AGOSEngine::linkItem(Item *item, Item *parent) {
item->parent = id;
if (parent != 0) {
- item->sibling = parent->child;
+ item->next = parent->child;
parent->child = itemPtrToID(item);
} else {
- item->sibling = 0;
+ item->next = 0;
}
}
@@ -1837,6 +1865,24 @@ Item *AGOSEngine::derefItem(uint item) {
return _itemArrayPtr[item];
}
+Item *AGOSEngine::findInByClass(Item *i, int16 m) {
+ i = derefItem(i->child);
+
+ while(i) {
+ if(i->classFlags & m) {
+ //_findNextPtr = derefItem(i->next);
+ return i;
+ }
+ if (m == 0) {
+ //_findNextPtr = derefItem(i->next);
+ return i;
+ }
+ i = derefItem(i->next);
+ }
+
+ return NULL;
+}
+
Item *AGOSEngine::findMaster(int16 pe, int16 a, int16 n) {
uint j;
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index d3ddaff1c8..f582b9aa47 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -514,8 +514,6 @@ protected:
uint32 readUint32Wrapper(const void *src);
int allocGamePcVars(Common::File *in);
- int getUserFlag(Item *item, int a);
- void setUserFlag(Item *item, int a, int b);
void createPlayer();
void allocateStringTable(int num);
void setupStringTable(byte *mem, int num);
@@ -529,6 +527,11 @@ protected:
void loadSound(uint sound, int pan, int vol, uint type);
void loadVoice(uint speechId);
+ int getUserFlag(Item *item, int a);
+ int getUserItem(Item *item, int n);
+ void setUserFlag(Item *item, int a, int b);
+ void setUserItem(Item *item, int n, int m);
+
void paletteFadeOut(byte *palPtr, uint num, uint size);
byte *allocateItem(uint size);
@@ -990,6 +993,7 @@ public:
void o_unloadZone();
void o_unfreezeZones();
+ Item *findInByClass(Item *i, int16 m);
Item *findMaster(int16 pe, int16 a, int16 n);
Item *nextMaster(int16 pe, Item *item, int16 a, int16 n);
int16 levelOf(Item *item);
@@ -1004,6 +1008,7 @@ public:
void moveDirn_e2(Item *i, uint x);
void moveDirn_ww(Item *i, uint x);
+ uint _classMask, _classMode1, _classMode2;
uint _superRoomNumber;
int sizeContents(Item *x);
@@ -1024,10 +1029,13 @@ public:
void oe1_notSibling();
void oe1_setFF();
void oe1_score();
- void oe1_opcode176();
- void oe1_opcode178();
+ void oe1_doClass();
+ void oe1_setUserItem();
+ void oe1_getUserItem();
+ void oe1_clearUserItem();
void oe1_findMaster();
void oe1_nextMaster();
+ void oe1_bitTest();
void oe1_zoneDisk();
void oe1_printStats();
diff --git a/engines/agos/debug.h b/engines/agos/debug.h
index 83bab44781..bcb500f89e 100644
--- a/engines/agos/debug.h
+++ b/engines/agos/debug.h
@@ -160,7 +160,7 @@ static const char *const elvira1_opcode_name_table[300] = {
/* 104 */
NULL,
"W|START_SUB",
- NULL,
+ "IWW|DO_CLASS",
NULL,
/* 108 */
NULL,
@@ -248,9 +248,9 @@ static const char *const elvira1_opcode_name_table[300] = {
NULL,
NULL,
/* 176 */
- "IWI|UNK176",
- NULL,
- "IW|UNK178",
+ "IWI|SET_USER_ITEM",
+ "IWW|GET_USER_ITEM",
+ "IW|CLEAR_USER_ITEM",
NULL,
/* 180 */
"IWW|WHERE_TO",
@@ -344,7 +344,7 @@ static const char *const elvira1_opcode_name_table[300] = {
NULL,
/* 252 */
NULL,
- NULL,
+ "WWJ|BIT_TEST",
NULL,
"W|WAIT_SYNC",
/* 256 */
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 1844499866..5bd5d3a968 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -251,7 +251,7 @@ void AGOSEngine::drawIconArray_Simon(uint num, Item *itemRef, int line, int clas
while (itemRef && width > curWidth) {
if ((classMask == 0 || itemRef->classFlags & classMask) && has_item_childflag_0x10(itemRef))
curWidth += iconSize;
- itemRef = derefItem(itemRef->sibling);
+ itemRef = derefItem(itemRef->next);
}
}
@@ -293,7 +293,7 @@ void AGOSEngine::drawIconArray_Simon(uint num, Item *itemRef, int line, int clas
item_again = true;
}
}
- itemRef = derefItem(itemRef->sibling);
+ itemRef = derefItem(itemRef->next);
}
window->iconPtr->iconArray[k].item = NULL;
@@ -351,7 +351,7 @@ void AGOSEngine::drawIconArray_FF(uint num, Item *itemRef, int line, int classMa
k++;
}
}
- itemRef = derefItem(itemRef->sibling);
+ itemRef = derefItem(itemRef->next);
}
line -= 52;
if (k == (flagnumber + 18))
@@ -394,7 +394,7 @@ void AGOSEngine::drawIconArray_FF(uint num, Item *itemRef, int line, int classMa
idone = 1; /* Note completed screen */
}
}
-l1:; itemRef = derefItem(itemRef->sibling);
+l1:; itemRef = derefItem(itemRef->next);
}
window->iconPtr->iconArray[icount].item = NULL; /* END MARKINGS */
if (_variableArray[30] == 0) {
diff --git a/engines/agos/intern.h b/engines/agos/intern.h
index f03cb605f1..dd5768742e 100644
--- a/engines/agos/intern.h
+++ b/engines/agos/intern.h
@@ -103,7 +103,7 @@ enum {
struct Item {
uint16 parent;
uint16 child;
- uint16 sibling;
+ uint16 next;
int16 noun;
int16 adjective;
int16 state; /* signed int */
diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp
index 2f5f211e8b..65e20d9ec5 100644
--- a/engines/agos/items.cpp
+++ b/engines/agos/items.cpp
@@ -240,6 +240,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[98] = &AGOSEngine::o_done;
op[105] = &AGOSEngine::o_process;
+ op[106] = &AGOSEngine::oe1_doClass;
op[119] = &AGOSEngine::o_when;
@@ -253,9 +254,9 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[164] = &AGOSEngine::o1_rescan;
- op[176] = &AGOSEngine::oe1_opcode176;
-
- op[178] = &AGOSEngine::oe1_opcode178;
+ op[176] = &AGOSEngine::oe1_setUserItem;
+ op[177] = &AGOSEngine::oe1_getUserItem;
+ op[178] = &AGOSEngine::oe1_clearUserItem;
op[180] = &AGOSEngine::oww_whereTo;
@@ -290,6 +291,8 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[249] = &AGOSEngine::o_setClass;
op[250] = &AGOSEngine::o_unsetClass;
+ op[253] = &AGOSEngine::oe1_bitTest;
+
op[255] = &AGOSEngine::o_waitSync;
op[256] = &AGOSEngine::o_sync;
op[257] = &AGOSEngine::o_defObj;
@@ -1050,8 +1053,8 @@ void AGOSEngine::o_getParent() {
}
void AGOSEngine::o_getNext() {
- // 91: set minusitem to sibling
- Item *item = derefItem(getNextItemPtr()->sibling);
+ // 91: set minusitem to next
+ Item *item = derefItem(getNextItemPtr()->next);
switch (getVarOrByte()) {
case 0:
_objectItem = item;
@@ -1794,17 +1797,53 @@ void AGOSEngine::oe1_score() {
showMessageFormat("Your score is %ld.\n", p->score);
}
-void AGOSEngine::oe1_opcode176() {
- // 176
- getNextItemPtr();
- getVarOrWord();
- getNextItemPtr();
+void AGOSEngine::oe1_doClass() {
+ // 106: do class
+ Item *i = getNextItemPtr();
+ int16 cm = getVarOrWord();
+ int16 num = getVarOrWord();
+
+ _classMask = (cm != -1) ? 1 << cm : 0;
+ //_classLine = (SubroutineLine *)((uint32)_currentLine->next+(uint32)_currentTable);
+
+ 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::oe1_opcode178() {
- // 178
- getNextItemPtr();
- getVarOrWord();
+void AGOSEngine::oe1_setUserItem() {
+ // 176: set user item
+ Item *i = getNextItemPtr();
+ uint tmp = getVarOrWord();
+ setUserItem(i, tmp, getNextItemID());
+}
+
+void AGOSEngine::oe1_getUserItem() {
+ // 177: get user item
+ Item *i = getNextItemPtr();
+ int n = getVarOrWord();
+
+ if (getVarOrWord() == 1)
+ _subjectItem = derefItem(getUserItem(i, n));
+ else
+ _objectItem = derefItem(getUserItem(i, n));
+}
+
+void AGOSEngine::oe1_clearUserItem() {
+ // 178: clear user item
+ Item *i = getNextItemPtr();
+ uint tmp = getVarOrWord();
+ setUserItem(i, tmp, 0);
}
void AGOSEngine::oe1_findMaster() {
@@ -1838,6 +1877,14 @@ void AGOSEngine::oe1_nextMaster() {
_objectItem = nextMaster(levelOf(me()), item, ad, no);
}
+void AGOSEngine::oe1_bitTest() {
+ // 253: bit test
+ int var = getVarOrWord();
+ int bit = getVarOrWord();
+
+ setScriptCondition((_variableArray[var] & (1 << bit)) != 0);
+}
+
void AGOSEngine::oe1_zoneDisk() {
// 267: set disk number of each zone
getVarOrWord();
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 2f6144e30e..4f4b699998 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -267,7 +267,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->noun = in->readUint16BE();
item->state = in->readUint16BE();
in->readUint16BE();
- item->sibling = (uint16)fileReadItemID(in);
+ item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in);
in->readUint16BE();
@@ -280,7 +280,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->adjective = in->readUint16BE();
item->noun = in->readUint16BE();
item->state = in->readUint16BE();
- item->sibling = (uint16)fileReadItemID(in);
+ item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in);
in->readUint16BE();
@@ -290,7 +290,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->adjective = in->readUint16BE();
item->noun = in->readUint16BE();
item->state = in->readUint16BE();
- item->sibling = (uint16)fileReadItemID(in);
+ item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in);
in->readUint16BE();
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 8353d4db69..f486cf381f 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -625,7 +625,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
Item *item = _itemArrayPtr[item_index++];
f->writeUint16BE(item->parent);
- f->writeUint16BE(item->sibling);
+ f->writeUint16BE(item->next);
f->writeUint16BE(item->state);
f->writeUint16BE(item->classFlags);
@@ -751,7 +751,7 @@ bool AGOSEngine::loadGame(uint slot) {
Item *item = _itemArrayPtr[item_index++], *parent_item;
uint parent = f->readUint16BE();
- uint sibling = f->readUint16BE();
+ uint next = f->readUint16BE();
parent_item = derefItem(parent);
@@ -759,7 +759,7 @@ bool AGOSEngine::loadGame(uint slot) {
if (parent_item == NULL) {
item->parent = parent;
- item->sibling = sibling;
+ item->next = next;
}
item->state = f->readUint16BE();