Add more code for Elvira 1

svn-id: r24141
This commit is contained in:
Travis Howell 2006-10-06 14:44:39 +00:00
parent 1d310debd9
commit 38195077d4
8 changed files with 143 additions and 42 deletions

View file

@ -318,6 +318,9 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_nextVgaTimerToProcess = 0; _nextVgaTimerToProcess = 0;
_classMask = 0;
_classMode1 = 0;
_classMode2 = 0;
_superRoomNumber = 0; _superRoomNumber = 0;
memset(_objectArray, 0, sizeof(_objectArray)); memset(_objectArray, 0, sizeof(_objectArray));
@ -776,6 +779,31 @@ void AGOSEngine::setUserFlag(Item *item, int a, int b) {
subUserFlag->userFlags[a] = 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() { void AGOSEngine::createPlayer() {
SubPlayer *p; SubPlayer *p;
@ -1051,23 +1079,23 @@ void AGOSEngine::unlinkItem(Item *item) {
// the node to remove is first in the parent's children? // the node to remove is first in the parent's children?
if (first == item) { if (first == item) {
parent->child = item->sibling; parent->child = item->next;
item->parent = 0; item->parent = 0;
item->sibling = 0; item->next = 0;
return; return;
} }
for (;;) { for (;;) {
if (!first) if (!first)
error("unlinkItem: parent empty"); error("unlinkItem: parent empty");
if (first->sibling == 0) if (first->next == 0)
error("unlinkItem: parent does not contain child"); error("unlinkItem: parent does not contain child");
next = derefItem(first->sibling); next = derefItem(first->next);
if (next == item) { if (next == item) {
first->sibling = next->sibling; first->next = next->next;
item->parent = 0; item->parent = 0;
item->sibling = 0; item->next = 0;
return; return;
} }
first = next; first = next;
@ -1084,10 +1112,10 @@ void AGOSEngine::linkItem(Item *item, Item *parent) {
item->parent = id; item->parent = id;
if (parent != 0) { if (parent != 0) {
item->sibling = parent->child; item->next = parent->child;
parent->child = itemPtrToID(item); parent->child = itemPtrToID(item);
} else { } else {
item->sibling = 0; item->next = 0;
} }
} }
@ -1837,6 +1865,24 @@ Item *AGOSEngine::derefItem(uint item) {
return _itemArrayPtr[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) { Item *AGOSEngine::findMaster(int16 pe, int16 a, int16 n) {
uint j; uint j;

View file

@ -514,8 +514,6 @@ protected:
uint32 readUint32Wrapper(const void *src); uint32 readUint32Wrapper(const void *src);
int allocGamePcVars(Common::File *in); int allocGamePcVars(Common::File *in);
int getUserFlag(Item *item, int a);
void setUserFlag(Item *item, int a, int b);
void createPlayer(); void createPlayer();
void allocateStringTable(int num); void allocateStringTable(int num);
void setupStringTable(byte *mem, int num); void setupStringTable(byte *mem, int num);
@ -529,6 +527,11 @@ protected:
void loadSound(uint sound, int pan, int vol, uint type); void loadSound(uint sound, int pan, int vol, uint type);
void loadVoice(uint speechId); 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); void paletteFadeOut(byte *palPtr, uint num, uint size);
byte *allocateItem(uint size); byte *allocateItem(uint size);
@ -990,6 +993,7 @@ public:
void o_unloadZone(); void o_unloadZone();
void o_unfreezeZones(); void o_unfreezeZones();
Item *findInByClass(Item *i, int16 m);
Item *findMaster(int16 pe, int16 a, int16 n); Item *findMaster(int16 pe, int16 a, int16 n);
Item *nextMaster(int16 pe, Item *item, int16 a, int16 n); Item *nextMaster(int16 pe, Item *item, int16 a, int16 n);
int16 levelOf(Item *item); int16 levelOf(Item *item);
@ -1004,6 +1008,7 @@ public:
void moveDirn_e2(Item *i, uint x); void moveDirn_e2(Item *i, uint x);
void moveDirn_ww(Item *i, uint x); void moveDirn_ww(Item *i, uint x);
uint _classMask, _classMode1, _classMode2;
uint _superRoomNumber; uint _superRoomNumber;
int sizeContents(Item *x); int sizeContents(Item *x);
@ -1024,10 +1029,13 @@ public:
void oe1_notSibling(); void oe1_notSibling();
void oe1_setFF(); void oe1_setFF();
void oe1_score(); void oe1_score();
void oe1_opcode176(); void oe1_doClass();
void oe1_opcode178(); void oe1_setUserItem();
void oe1_getUserItem();
void oe1_clearUserItem();
void oe1_findMaster(); void oe1_findMaster();
void oe1_nextMaster(); void oe1_nextMaster();
void oe1_bitTest();
void oe1_zoneDisk(); void oe1_zoneDisk();
void oe1_printStats(); void oe1_printStats();

View file

@ -160,7 +160,7 @@ static const char *const elvira1_opcode_name_table[300] = {
/* 104 */ /* 104 */
NULL, NULL,
"W|START_SUB", "W|START_SUB",
NULL, "IWW|DO_CLASS",
NULL, NULL,
/* 108 */ /* 108 */
NULL, NULL,
@ -248,9 +248,9 @@ static const char *const elvira1_opcode_name_table[300] = {
NULL, NULL,
NULL, NULL,
/* 176 */ /* 176 */
"IWI|UNK176", "IWI|SET_USER_ITEM",
NULL, "IWW|GET_USER_ITEM",
"IW|UNK178", "IW|CLEAR_USER_ITEM",
NULL, NULL,
/* 180 */ /* 180 */
"IWW|WHERE_TO", "IWW|WHERE_TO",
@ -344,7 +344,7 @@ static const char *const elvira1_opcode_name_table[300] = {
NULL, NULL,
/* 252 */ /* 252 */
NULL, NULL,
NULL, "WWJ|BIT_TEST",
NULL, NULL,
"W|WAIT_SYNC", "W|WAIT_SYNC",
/* 256 */ /* 256 */

View file

@ -251,7 +251,7 @@ void AGOSEngine::drawIconArray_Simon(uint num, Item *itemRef, int line, int clas
while (itemRef && width > curWidth) { while (itemRef && width > curWidth) {
if ((classMask == 0 || itemRef->classFlags & classMask) && has_item_childflag_0x10(itemRef)) if ((classMask == 0 || itemRef->classFlags & classMask) && has_item_childflag_0x10(itemRef))
curWidth += iconSize; 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; item_again = true;
} }
} }
itemRef = derefItem(itemRef->sibling); itemRef = derefItem(itemRef->next);
} }
window->iconPtr->iconArray[k].item = NULL; window->iconPtr->iconArray[k].item = NULL;
@ -351,7 +351,7 @@ void AGOSEngine::drawIconArray_FF(uint num, Item *itemRef, int line, int classMa
k++; k++;
} }
} }
itemRef = derefItem(itemRef->sibling); itemRef = derefItem(itemRef->next);
} }
line -= 52; line -= 52;
if (k == (flagnumber + 18)) 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 */ idone = 1; /* Note completed screen */
} }
} }
l1:; itemRef = derefItem(itemRef->sibling); l1:; itemRef = derefItem(itemRef->next);
} }
window->iconPtr->iconArray[icount].item = NULL; /* END MARKINGS */ window->iconPtr->iconArray[icount].item = NULL; /* END MARKINGS */
if (_variableArray[30] == 0) { if (_variableArray[30] == 0) {

View file

@ -103,7 +103,7 @@ enum {
struct Item { struct Item {
uint16 parent; uint16 parent;
uint16 child; uint16 child;
uint16 sibling; uint16 next;
int16 noun; int16 noun;
int16 adjective; int16 adjective;
int16 state; /* signed int */ int16 state; /* signed int */

View file

@ -240,6 +240,7 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[98] = &AGOSEngine::o_done; op[98] = &AGOSEngine::o_done;
op[105] = &AGOSEngine::o_process; op[105] = &AGOSEngine::o_process;
op[106] = &AGOSEngine::oe1_doClass;
op[119] = &AGOSEngine::o_when; op[119] = &AGOSEngine::o_when;
@ -253,9 +254,9 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[164] = &AGOSEngine::o1_rescan; op[164] = &AGOSEngine::o1_rescan;
op[176] = &AGOSEngine::oe1_opcode176; op[176] = &AGOSEngine::oe1_setUserItem;
op[177] = &AGOSEngine::oe1_getUserItem;
op[178] = &AGOSEngine::oe1_opcode178; op[178] = &AGOSEngine::oe1_clearUserItem;
op[180] = &AGOSEngine::oww_whereTo; op[180] = &AGOSEngine::oww_whereTo;
@ -290,6 +291,8 @@ void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) {
op[249] = &AGOSEngine::o_setClass; op[249] = &AGOSEngine::o_setClass;
op[250] = &AGOSEngine::o_unsetClass; op[250] = &AGOSEngine::o_unsetClass;
op[253] = &AGOSEngine::oe1_bitTest;
op[255] = &AGOSEngine::o_waitSync; op[255] = &AGOSEngine::o_waitSync;
op[256] = &AGOSEngine::o_sync; op[256] = &AGOSEngine::o_sync;
op[257] = &AGOSEngine::o_defObj; op[257] = &AGOSEngine::o_defObj;
@ -1050,8 +1053,8 @@ void AGOSEngine::o_getParent() {
} }
void AGOSEngine::o_getNext() { void AGOSEngine::o_getNext() {
// 91: set minusitem to sibling // 91: set minusitem to next
Item *item = derefItem(getNextItemPtr()->sibling); Item *item = derefItem(getNextItemPtr()->next);
switch (getVarOrByte()) { switch (getVarOrByte()) {
case 0: case 0:
_objectItem = item; _objectItem = item;
@ -1794,17 +1797,53 @@ void AGOSEngine::oe1_score() {
showMessageFormat("Your score is %ld.\n", p->score); showMessageFormat("Your score is %ld.\n", p->score);
} }
void AGOSEngine::oe1_opcode176() { void AGOSEngine::oe1_doClass() {
// 176 // 106: do class
getNextItemPtr(); Item *i = getNextItemPtr();
getVarOrWord(); int16 cm = getVarOrWord();
getNextItemPtr(); 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() { void AGOSEngine::oe1_setUserItem() {
// 178 // 176: set user item
getNextItemPtr(); Item *i = getNextItemPtr();
getVarOrWord(); 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() { void AGOSEngine::oe1_findMaster() {
@ -1838,6 +1877,14 @@ void AGOSEngine::oe1_nextMaster() {
_objectItem = nextMaster(levelOf(me()), item, ad, no); _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() { void AGOSEngine::oe1_zoneDisk() {
// 267: set disk number of each zone // 267: set disk number of each zone
getVarOrWord(); getVarOrWord();

View file

@ -267,7 +267,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->noun = in->readUint16BE(); item->noun = in->readUint16BE();
item->state = in->readUint16BE(); item->state = in->readUint16BE();
in->readUint16BE(); in->readUint16BE();
item->sibling = (uint16)fileReadItemID(in); item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in);
in->readUint16BE(); in->readUint16BE();
@ -280,7 +280,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->adjective = in->readUint16BE(); item->adjective = in->readUint16BE();
item->noun = in->readUint16BE(); item->noun = in->readUint16BE();
item->state = in->readUint16BE(); item->state = in->readUint16BE();
item->sibling = (uint16)fileReadItemID(in); item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in);
in->readUint16BE(); in->readUint16BE();
@ -290,7 +290,7 @@ void AGOSEngine::readItemFromGamePc(Common::File *in, Item *item) {
item->adjective = in->readUint16BE(); item->adjective = in->readUint16BE();
item->noun = in->readUint16BE(); item->noun = in->readUint16BE();
item->state = in->readUint16BE(); item->state = in->readUint16BE();
item->sibling = (uint16)fileReadItemID(in); item->next = (uint16)fileReadItemID(in);
item->child = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in);
item->parent = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in);
in->readUint16BE(); in->readUint16BE();

View file

@ -625,7 +625,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
Item *item = _itemArrayPtr[item_index++]; Item *item = _itemArrayPtr[item_index++];
f->writeUint16BE(item->parent); f->writeUint16BE(item->parent);
f->writeUint16BE(item->sibling); f->writeUint16BE(item->next);
f->writeUint16BE(item->state); f->writeUint16BE(item->state);
f->writeUint16BE(item->classFlags); f->writeUint16BE(item->classFlags);
@ -751,7 +751,7 @@ bool AGOSEngine::loadGame(uint slot) {
Item *item = _itemArrayPtr[item_index++], *parent_item; Item *item = _itemArrayPtr[item_index++], *parent_item;
uint parent = f->readUint16BE(); uint parent = f->readUint16BE();
uint sibling = f->readUint16BE(); uint next = f->readUint16BE();
parent_item = derefItem(parent); parent_item = derefItem(parent);
@ -759,7 +759,7 @@ bool AGOSEngine::loadGame(uint slot) {
if (parent_item == NULL) { if (parent_item == NULL) {
item->parent = parent; item->parent = parent;
item->sibling = sibling; item->next = next;
} }
item->state = f->readUint16BE(); item->state = f->readUint16BE();