Add inital load/save code changes for earlier games and cleanup

svn-id: r24622
This commit is contained in:
Travis Howell 2006-11-05 06:26:45 +00:00
parent ea9baa0347
commit a2abbf919d
10 changed files with 439 additions and 192 deletions

View file

@ -145,7 +145,7 @@ void AGOSEngine::quickLoadOrSave() {
char *filename = genSaveName(_saveLoadSlot);
if (_saveLoadType == 2) {
Subroutine *sub;
success = loadGame(_saveLoadSlot);
success = loadGame(genSaveName(_saveLoadSlot));
if (!success) {
sprintf(buf, "Failed to load game state to file:\n\n%s", filename);
} else {
@ -369,7 +369,7 @@ restart:;
if (!saveGame(_saveLoadRowCurPos + result, buf + result * 18))
fileError(_windowArray[5], true);
} else {
if (!loadGame(_saveLoadRowCurPos + i))
if (!loadGame(genSaveName(_saveLoadRowCurPos + i)))
fileError(_windowArray[5], false);
}
@ -410,7 +410,6 @@ int AGOSEngine::userGameGetKey(bool *b, char *buf) {
} while (_lastHitArea3 == 0);
ha = _lastHitArea;
if (ha == NULL || ha->id < 205) {
} else if (ha->id == 205) {
return ha->id;
@ -581,6 +580,344 @@ loop:;
undefineBox(0x7FFF);
}
bool AGOSEngine::loadGame_e1(const char *filename) {
Common::SeekableReadStream *f = NULL;
uint num, item_index, i;
_lockWord |= 0x100;
// Load restart state
Common::File *file = new Common::File();
file->open(filename, Common::File::kFileReadMode);
if (!file->isOpen()) {
delete file;
f = _saveFileMan->openForLoading(filename);
} else {
f = file;
}
if (f == NULL) {
_lockWord &= ~0x100;
return false;
}
num = f->readUint32BE();
if (f->readUint32BE() != 0xFFFFFFFF || num != _itemArrayInited - 1) {
delete f;
_lockWord &= ~0x100;
return false;
}
f->readUint32BE();
f->readUint32BE();
_noParentNotify = true;
// add all timers
killAllTimers();
for (num = f->readUint32BE(); num; num--) {
uint32 timeout = f->readUint32BE();
uint16 func_to_call = f->readUint16BE();
addTimeEvent(timeout, func_to_call);
}
item_index = 1;
for (num = _itemArrayInited - 1; num; num--) {
Item *item = _itemArrayPtr[item_index++], *parent_item;
uint16 parent = f->readUint32BE();
if (parent == 0xFFFF)
parent_item = 0;
else
parent_item = derefItem(parent);
setItemParent(item, parent_item);
item->state = f->readUint16BE();
item->classFlags = f->readUint16BE();
SubObject *o = (SubObject *)findChildOfType(item, 2);
if (o) {
o->objectSize = f->readUint16BE();
o->objectWeight = f->readUint16BE();
}
SubPlayer *p = (SubPlayer *)findChildOfType(item, 3);
if (p) {
p->score = f->readUint32BE();
p->level = f->readUint16BE();
p->size = f->readUint16BE();
p->weight = f->readUint16BE();
p->strength = f->readUint16BE();
}
SubUserFlag *u = (SubUserFlag *) findChildOfType(item, 9);
if (u) {
for (i = 0; i != 8; i++) {
u->userFlags[i] = f->readUint16BE();
}
uint16 val = f->readUint32BE();
if (val == 0xFFFF)
u->userItems[0] = 0;
else
u->userItems[0] = val;
}
}
// read the variables
for (i = 0; i != _numVars; i++) {
writeVariable(i, f->readUint16BE());
}
debug(0, "Pos %d Size %d\n", f->pos(), f->size());
if (f->ioFailed()) {
error("load failed");
}
delete f;
_noParentNotify = false;
_lockWord &= ~0x100;
return true;
}
bool AGOSEngine::saveGame_e1(const char *filename) {
Common::WriteStream *f;
uint item_index, num_item, i;
TimeEvent *te;
uint32 curTime = 0;
uint32 gsc = _gameStoppedClock;
_lockWord |= 0x100;
f = _saveFileMan->openForSaving(filename);
if (f == NULL) {
warning("saveGame: Failed to save %s", filename);
_lockWord &= ~0x100;
return false;
}
f->writeUint32BE(_itemArrayInited - 1);
f->writeUint32BE(0xFFFFFFFF);
f->writeUint32BE(0);
f->writeUint32BE(0);
i = 0;
for (te = _firstTimeStruct; te; te = te->next)
i++;
f->writeUint32BE(i);
for (te = _firstTimeStruct; te; te = te->next) {
f->writeUint32BE(te->time - curTime + gsc);
f->writeUint16BE(te->subroutine_id);
}
item_index = 1;
for (num_item = _itemArrayInited - 1; num_item; num_item--) {
Item *item = _itemArrayPtr[item_index++];
if (item->parent == 0)
f->writeUint32BE(0xFFFFFFFF);
else
f->writeUint32BE(item->parent);
f->writeUint16BE(item->state);
f->writeUint16BE(item->classFlags);
SubObject *o = (SubObject *)findChildOfType(item, 2);
if (o) {
f->writeUint16BE(o->objectSize);
f->writeUint16BE(o->objectWeight);
}
SubPlayer *p = (SubPlayer *)findChildOfType(item, 3);
if (p) {
f->writeUint32BE(p->score);
f->writeUint16BE(p->level);
f->writeUint16BE(p->size);
f->writeUint16BE(p->weight);
f->writeUint16BE(p->strength);
}
SubUserFlag *u = (SubUserFlag *) findChildOfType(item, 9);
if (u) {
for (i = 0; i != 8; i++) {
f->writeUint16BE(u->userFlags[i]);
}
if (u->userItems[0] == 0)
f->writeUint32BE(0xFFFFFFFF);
else
f->writeUint32BE(u->userItems[0]);
}
}
// write the variables
for (i = 0; i != _numVars; i++) {
f->writeUint16BE(readVariable(i));
}
f->flush();
bool result = !f->ioFailed();
delete f;
_lockWord &= ~0x100;
return result;
}
bool AGOSEngine::loadGame(const char *filename) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
_lockWord |= 0x100;
// Load restart state
Common::File *file = new Common::File();
file->open(filename, Common::File::kFileReadMode);
if (!file->isOpen()) {
delete file;
f = _saveFileMan->openForLoading(filename);
} else {
f = file;
}
if (f == NULL) {
warning("loadGame: Failed to load %s", filename);
_lockWord &= ~0x100;
return false;
}
if (getGameType() == GType_FF) {
f->read(ident, 100);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
f->read(ident, 18);
}
num = f->readUint32BE();
if (f->readUint32BE() != 0xFFFFFFFF || num != _itemArrayInited - 1) {
delete f;
_lockWord &= ~0x100;
return false;
}
f->readUint32BE();
f->readUint32BE();
_noParentNotify = true;
// add all timers
killAllTimers();
for (num = f->readUint32BE(); num; num--) {
uint32 timeout = f->readUint32BE();
uint16 func_to_call = f->readUint16BE();
addTimeEvent(timeout, func_to_call);
}
item_index = 1;
for (num = _itemArrayInited - 1; num; num--) {
Item *item = _itemArrayPtr[item_index++], *parent_item;
uint parent = f->readUint16BE();
uint next = f->readUint16BE();
parent_item = derefItem(parent);
setItemParent(item, parent_item);
if (parent_item == NULL) {
item->parent = parent;
item->next = next;
}
item->state = f->readUint16BE();
item->classFlags = f->readUint16BE();
SubRoom *r = (SubRoom *)findChildOfType(item, 1);
if (r) {
r->roomExitStates = f->readUint16BE();
}
SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(item, 4);
if (sr) {
uint16 n = sr->roomX * sr->roomY * sr->roomZ;
uint16 *c = sr->roomExitStates;
while(n--)
*c++ = f->readUint16BE();
}
SubObject *o = (SubObject *)findChildOfType(item, 2);
if (o) {
o->objectFlags = f->readUint32BE();
i = o->objectFlags & 1;
for (j = 1; j < 16; j++) {
if (o->objectFlags & (1 << j)) {
o->objectFlagValue[i++] = f->readUint16BE();
}
}
}
SubUserFlag *u = (SubUserFlag *) findChildOfType(item, 9);
if (u) {
for (i = 0; i != 4; i++) {
u->userFlags[i] = f->readUint16BE();
}
}
}
// read the variables
for (i = 0; i != _numVars; i++) {
writeVariable(i, f->readUint16BE());
}
// read the items in item store
for (i = 0; i != _numItemStore; i++) {
_itemStore[i] = derefItem(f->readUint16BE());
}
if (getGameType() == GType_PP) {
// Read the bits in array 1
for (i = 0; i != 128; i++)
_bitArray[i] = f->readUint16BE();
} else {
// Read the bits in array 1
for (i = 0; i != 16; i++)
_bitArray[i] = f->readUint16BE();
// Read the bits in array 2
for (i = 0; i != 16; i++)
_bitArrayTwo[i] = f->readUint16BE();
}
// Read the bits in array 3
if (getGameType() == GType_FF) {
for (i = 0; i != 16; i++)
_bitArrayThree[i] = f->readUint16BE();
}
if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
_superRoomNumber = f->readUint16BE();
}
if (f->ioFailed()) {
error("load failed");
}
delete f;
_noParentNotify = false;
_lockWord &= ~0x100;
return true;
}
bool AGOSEngine::saveGame(uint slot, const char *caption) {
Common::WriteStream *f;
uint item_index, num_item, i, j;
@ -600,7 +937,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
if (getGameType() == GType_FF) {
f->write(caption, 100);
curTime = time(NULL);
} else if (getGameType() != GType_PP) {
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
f->write(caption, 18);
}
@ -630,27 +967,35 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
f->writeUint16BE(item->state);
f->writeUint16BE(item->classFlags);
SubRoom *subRoom = (SubRoom *)findChildOfType(item, 1);
if (subRoom) {
f->writeUint16BE(subRoom->roomExitStates);
SubRoom *r = (SubRoom *)findChildOfType(item, 1);
if (r) {
f->writeUint16BE(r->roomExitStates);
}
SubObject *subObject = (SubObject *)findChildOfType(item, 2);
if (subObject) {
f->writeUint32BE(subObject->objectFlags);
i = subObject->objectFlags & 1;
SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(item, 4);
if (sr) {
uint16 n = sr->roomX * sr->roomY * sr->roomZ;
uint16 *c = sr->roomExitStates;
while(n--)
f->writeUint16BE(*c++);
}
SubObject *o = (SubObject *)findChildOfType(item, 2);
if (o) {
f->writeUint32BE(o->objectFlags);
i = o->objectFlags & 1;
for (j = 1; j < 16; j++) {
if (subObject->objectFlags & (1 << j)) {
f->writeUint16BE(subObject->objectFlagValue[i++]);
if (o->objectFlags & (1 << j)) {
f->writeUint16BE(o->objectFlagValue[i++]);
}
}
}
SubUserFlag *subUserFlag = (SubUserFlag *)findChildOfType(item, 9);
if (subUserFlag) {
SubUserFlag *u = (SubUserFlag *)findChildOfType(item, 9);
if (u) {
for (i = 0; i != 4; i++) {
f->writeUint16BE(subUserFlag->userFlags[i]);
f->writeUint16BE(u->userFlags[i]);
}
}
}
@ -660,8 +1005,8 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
f->writeUint16BE(readVariable(i));
}
// write the items in array 6
for (i = 0; i != 10; i++) {
// write the items in item store
for (i = 0; i != _numItemStore; i++) {
f->writeUint16BE(itemPtrToID(_itemStore[i]));
}
@ -685,6 +1030,10 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
f->writeUint16BE(_bitArrayThree[i]);
}
if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
f->writeUint16BE(_superRoomNumber);
}
f->flush();
bool result = !f->ioFailed();
@ -694,145 +1043,4 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
return result;
}
bool AGOSEngine::loadGame(uint slot) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
_lockWord |= 0x100;
if (getGameType() == GType_FF && slot == 999) {
// Load restart state
Common::File *file = new Common::File();
file->open(genSaveName(slot), Common::File::kFileReadMode);
if (!file->isOpen()) {
delete file;
} else {
f = file;
}
} else {
f = _saveFileMan->openForLoading(genSaveName(slot));
}
if (f == NULL) {
warning("loadGame: Failed to load slot %d", slot);
_lockWord &= ~0x100;
return false;
}
if (getGameType() == GType_FF) {
f->read(ident, 100);
} else if (getGameType() != GType_PP) {
f->read(ident, 18);
}
num = f->readUint32BE();
if (f->readUint32BE() != 0xFFFFFFFF || num != _itemArrayInited - 1) {
delete f;
_lockWord &= ~0x100;
return false;
}
f->readUint32BE();
f->readUint32BE();
_noParentNotify = true;
// add all timers
killAllTimers();
for (num = f->readUint32BE(); num; num--) {
uint32 timeout = f->readUint32BE();
uint16 func_to_call = f->readUint16BE();
addTimeEvent(timeout, func_to_call);
}
item_index = 1;
for (num = _itemArrayInited - 1; num; num--) {
Item *item = _itemArrayPtr[item_index++], *parent_item;
uint parent = f->readUint16BE();
uint next = f->readUint16BE();
parent_item = derefItem(parent);
setItemParent(item, parent_item);
if (parent_item == NULL) {
item->parent = parent;
item->next = next;
}
item->state = f->readUint16BE();
item->classFlags = f->readUint16BE();
SubRoom *subRoom = (SubRoom *)findChildOfType(item, 1);
if (subRoom != NULL) {
subRoom->roomExitStates = f->readUint16BE();
}
SubObject *subObject = (SubObject *)findChildOfType(item, 2);
if (subObject != NULL) {
subObject->objectFlags = f->readUint32BE();
i = subObject->objectFlags & 1;
for (j = 1; j < 16; j++) {
if (subObject->objectFlags & (1 << j)) {
subObject->objectFlagValue[i++] = f->readUint16BE();
}
}
}
SubUserFlag *subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
if (subUserFlag) {
for (i = 0; i != 4; i++) {
subUserFlag->userFlags[i] = f->readUint16BE();
}
}
}
// read the variables
for (i = 0; i != _numVars; i++) {
writeVariable(i, f->readUint16BE());
}
// read the items in array 6
for (i = 0; i != 10; i++) {
_itemStore[i] = derefItem(f->readUint16BE());
}
if (getGameType() == GType_PP) {
// Read the bits in array 1
for (i = 0; i != 128; i++)
_bitArray[i] = f->readUint16BE();
} else {
// Read the bits in array 1
for (i = 0; i != 16; i++)
_bitArray[i] = f->readUint16BE();
// Read the bits in array 2
for (i = 0; i != 16; i++)
_bitArrayTwo[i] = f->readUint16BE();
}
// Read the bits in array 3
if (getGameType() == GType_FF) {
for (i = 0; i != 16; i++)
_bitArrayThree[i] = f->readUint16BE();
}
if (f->ioFailed()) {
error("load failed");
}
delete f;
_noParentNotify = false;
_lockWord &= ~0x100;
return true;
}
} // End of namespace AGOS