Add more code for Elvira 1
svn-id: r24141
This commit is contained in:
parent
1d310debd9
commit
38195077d4
8 changed files with 143 additions and 42 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -103,7 +103,7 @@ enum {
|
|||
struct Item {
|
||||
uint16 parent;
|
||||
uint16 child;
|
||||
uint16 sibling;
|
||||
uint16 next;
|
||||
int16 noun;
|
||||
int16 adjective;
|
||||
int16 state; /* signed int */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue