mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-22 10:17:22 +00:00
SAGA2: Implement SAGA Threads save/loading
This commit is contained in:
parent
5e5025205c
commit
2b22e64ffd
@ -148,6 +148,9 @@ public:
|
||||
void set(uint32 duration);
|
||||
bool check(void);
|
||||
uint32 elapsed(void); // time elapsed since alarm set
|
||||
|
||||
void write(Common::OutSaveFile *out);
|
||||
void read(Common::InSaveFile *in);
|
||||
};
|
||||
|
||||
/* ===================================================================== *
|
||||
|
@ -1159,6 +1159,8 @@ public:
|
||||
// Reconstruct from archive buffer
|
||||
void *restore(void *buf);
|
||||
|
||||
void read(Common::InSaveFile *in);
|
||||
|
||||
// Return the number of bytes needed to archive this thread list
|
||||
// in an archive buffer
|
||||
int32 archiveSize(void);
|
||||
@ -1166,6 +1168,8 @@ public:
|
||||
// Create an archive of this thread list in an archive buffer
|
||||
void *archive(void *buf);
|
||||
|
||||
void write(Common::OutSaveFile *out);
|
||||
|
||||
// Cleanup the active threads
|
||||
void cleanup(void);
|
||||
|
||||
@ -1223,6 +1227,26 @@ void *ThreadList::restore(void *buf) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
void ThreadList::read(Common::InSaveFile *in) {
|
||||
int16 threadCount;
|
||||
|
||||
// Get the count of threads and increment the buffer pointer
|
||||
threadCount = in->readSint16LE();
|
||||
debugC(3, kDebugSaveload, "... threadCount = %d", threadCount);
|
||||
|
||||
// Iterate through the archive data, reconstructing the Threads
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
debugC(3, kDebugSaveload, "Saving Thread %d", i);
|
||||
ThreadID id;
|
||||
|
||||
// Retreive the Thread's id number
|
||||
id = in->readSint16LE();
|
||||
debugC(4, kDebugSaveload, "...... id = %d", id);
|
||||
|
||||
new Thread(in);
|
||||
}
|
||||
}
|
||||
|
||||
int32 ThreadList::archiveSize(void) {
|
||||
int32 size = sizeof(int16);
|
||||
|
||||
@ -1271,6 +1295,28 @@ void *ThreadList::archive(void *buf) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
void ThreadList::write(Common::OutSaveFile *out) {
|
||||
int16 threadCount = 0;
|
||||
Thread *th;
|
||||
|
||||
// Count the active threads
|
||||
for (th = first(); th; th = next(th))
|
||||
threadCount++;
|
||||
|
||||
// Store the thread count in the archive buffer
|
||||
out->writeSint16LE(threadCount);
|
||||
debugC(3, kDebugSaveload, "... threadCount = %d", threadCount);
|
||||
|
||||
// Iterate through the threads, archiving each
|
||||
for (th = first(); th; th = next(th)) {
|
||||
debugC(3, kDebugSaveload, "Loading ThreadID %d", getThreadID(th));
|
||||
// Store the Thread's id number
|
||||
out->writeSint16LE(getThreadID(th));
|
||||
|
||||
th->write(out);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Cleanup the active threads
|
||||
|
||||
@ -1352,7 +1398,7 @@ static ThreadList &threadList = *((ThreadList *)threadListBuffer);
|
||||
|
||||
void initSAGAThreads(void) {
|
||||
// Simply call the Thread List default constructor
|
||||
new ThreadList;
|
||||
new (&threadList) ThreadList;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@ -1378,13 +1424,25 @@ void saveSAGAThreads(SaveFileConstructor &saveGame) {
|
||||
free(archiveBuffer);
|
||||
}
|
||||
|
||||
void saveSAGAThreads(Common::OutSaveFile *out) {
|
||||
debugC(2, kDebugSaveload, "Saving SAGA Threads");
|
||||
|
||||
int32 archiveBufSize;
|
||||
|
||||
archiveBufSize = threadList.archiveSize();
|
||||
|
||||
out->write("SAGA", 4);
|
||||
out->writeUint32LE(archiveBufSize);
|
||||
threadList.write(out);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Load the active SAGA threads from a save file
|
||||
|
||||
void loadSAGAThreads(SaveFileReader &saveGame) {
|
||||
// If there is no saved data, simply call the default constructor
|
||||
if (saveGame.getChunkSize() == 0) {
|
||||
new ThreadList;
|
||||
new (&threadList) ThreadList;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1401,7 +1459,7 @@ void loadSAGAThreads(SaveFileReader &saveGame) {
|
||||
bufferPtr = archiveBuffer;
|
||||
|
||||
// Reconstruct stackList from archived data
|
||||
new ThreadList;
|
||||
new (&threadList) ThreadList;
|
||||
bufferPtr = threadList.restore(bufferPtr);
|
||||
|
||||
assert((char *)bufferPtr == (char *)archiveBuffer + saveGame.getChunkSize());
|
||||
@ -1409,6 +1467,20 @@ void loadSAGAThreads(SaveFileReader &saveGame) {
|
||||
free(archiveBuffer);
|
||||
}
|
||||
|
||||
void loadSAGAThreads(Common::InSaveFile *in, int32 chunkSize) {
|
||||
debugC(2, kDebugSaveload, "Loading SAGA Threads");
|
||||
|
||||
// If there is no saved data, simply call the default constructor
|
||||
if (chunkSize == 0) {
|
||||
new (&threadList) ThreadList;
|
||||
return;
|
||||
}
|
||||
|
||||
// Reconstruct stackList from archived data
|
||||
new (&threadList) ThreadList;
|
||||
threadList.read(in);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Dispose of the active SAGA threads
|
||||
|
||||
@ -1510,6 +1582,37 @@ Thread::Thread(void **buf) {
|
||||
newThread(this);
|
||||
}
|
||||
|
||||
Thread::Thread(Common::SeekableReadStream *stream) {
|
||||
int16 stackOffset;
|
||||
|
||||
programCounter.segment = stream->readUint16LE();
|
||||
programCounter.offset = stream->readUint16LE();
|
||||
|
||||
stackSize = stream->readSint16LE();
|
||||
flags = stream->readSint16LE();
|
||||
framePtr = stream->readSint16LE();
|
||||
returnVal = stream->readSint16LE();
|
||||
|
||||
waitAlarm.read(stream);
|
||||
|
||||
stackOffset = stream->readSint16LE();
|
||||
|
||||
debugC(4, kDebugSaveload, "...... stackSize = %d", stackSize);
|
||||
debugC(4, kDebugSaveload, "...... flags = %d", flags);
|
||||
debugC(4, kDebugSaveload, "...... framePtr = %d", framePtr);
|
||||
debugC(4, kDebugSaveload, "...... returnVal = %d", returnVal);
|
||||
debugC(4, kDebugSaveload, "...... stackOffset = %d", stackOffset);
|
||||
|
||||
codeSeg = scriptRes->loadIndexResource(programCounter.segment, "saga code segment");
|
||||
|
||||
stackBase = (byte *)malloc(stackSize);
|
||||
stackPtr = stackBase + stackSize - stackOffset;
|
||||
|
||||
stream->read(stackPtr, stackOffset);
|
||||
|
||||
newThread(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Thread destructor
|
||||
|
||||
@ -1569,6 +1672,32 @@ void *Thread::archive(void *buf) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Thread::write(Common::OutSaveFile *out) {
|
||||
int16 stackOffset;
|
||||
|
||||
out->writeUint16LE(programCounter.segment);
|
||||
out->writeUint16LE(programCounter.offset);
|
||||
|
||||
out->writeSint16LE(stackSize);
|
||||
out->writeSint16LE(flags);
|
||||
out->writeSint16LE(framePtr);
|
||||
out->writeSint16LE(returnVal);
|
||||
|
||||
waitAlarm.write(out);
|
||||
|
||||
warning("STUB: Thread::write: Pointer arithmetic");
|
||||
stackOffset = (stackBase + stackSize) - stackPtr;
|
||||
out->writeSint16LE(stackOffset);
|
||||
|
||||
out->write(stackPtr, stackOffset);
|
||||
|
||||
debugC(4, kDebugSaveload, "...... stackSize = %d", stackSize);
|
||||
debugC(4, kDebugSaveload, "...... flags = %d", flags);
|
||||
debugC(4, kDebugSaveload, "...... framePtr = %d", framePtr);
|
||||
debugC(4, kDebugSaveload, "...... returnVal = %d", returnVal);
|
||||
debugC(4, kDebugSaveload, "...... stackOffset = %d", stackOffset);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Thread dispatcher
|
||||
|
||||
|
@ -155,9 +155,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
|
||||
saveActiveItemStates(out);
|
||||
saveTileCyclingStates(out);
|
||||
saveSAGADataSeg(out);
|
||||
saveSAGAThreads(out);
|
||||
|
||||
#if 0
|
||||
saveSAGAThreads(saveGame);
|
||||
saveMotionTasks(saveGame);
|
||||
saveTaskStacks(saveGame);
|
||||
saveTasks(saveGame);
|
||||
@ -301,12 +301,12 @@ void loadSavedGameState(int16 saveNo) {
|
||||
loadSAGADataSeg(in);
|
||||
loadFlags |= loadSAGADataSegFlag;
|
||||
break;
|
||||
#if 0
|
||||
|
||||
case MKTAG('S', 'A', 'G', 'A'):
|
||||
loadSAGAThreads(saveGame);
|
||||
loadSAGAThreads(in, chunkSize);
|
||||
loadFlags |= loadSAGAThreadsFlag;
|
||||
break;
|
||||
#if 0
|
||||
|
||||
case MKTAG('M', 'O', 'T', 'N'):
|
||||
if (!(~loadFlags & (loadActorsFlag | loadObjectsFlag))) {
|
||||
|
@ -146,9 +146,11 @@ void initSAGAThreads(void);
|
||||
|
||||
// Save the active SAGA threads to a save file
|
||||
void saveSAGAThreads(SaveFileConstructor &saveGame);
|
||||
void saveSAGAThreads(Common::OutSaveFile *out);
|
||||
|
||||
// Load the active SAGA threads from a save file
|
||||
void loadSAGAThreads(SaveFileReader &saveGame);
|
||||
void loadSAGAThreads(Common::InSaveFile *in, int32 chunkSize);
|
||||
|
||||
// Dispose of the active SAGA threads
|
||||
void cleanupSAGAThreads(void);
|
||||
@ -250,6 +252,8 @@ public:
|
||||
// Constructor -- reconstruct from archive buffer
|
||||
Thread(void **buf);
|
||||
|
||||
Thread(Common::SeekableReadStream *stream);
|
||||
|
||||
// Destructor
|
||||
~Thread();
|
||||
|
||||
@ -260,6 +264,8 @@ public:
|
||||
// Create an archive of this thread in an archive buffer
|
||||
void *archive(void *buf);
|
||||
|
||||
void write(Common::OutSaveFile *out);
|
||||
|
||||
// Dispatch all asynchronous threads
|
||||
static void dispatch(void);
|
||||
|
||||
|
@ -98,6 +98,16 @@ void loadTimer(Common::InSaveFile *in) {
|
||||
Alarms
|
||||
* ====================================================================== */
|
||||
|
||||
void Alarm::write(Common::OutSaveFile *out) {
|
||||
out->writeUint32LE(basetime);
|
||||
out->writeUint32LE(duration);
|
||||
}
|
||||
|
||||
void Alarm::read(Common::InSaveFile *in) {
|
||||
basetime = in->readUint32LE();
|
||||
duration = in->readUint32LE();
|
||||
}
|
||||
|
||||
void Alarm::set(uint32 dur) {
|
||||
basetime = gameTime;
|
||||
duration = dur;
|
||||
|
Loading…
x
Reference in New Issue
Block a user