From 3e88827c4cea00dcc9f0fe90fc4a173c2b821b41 Mon Sep 17 00:00:00 2001 From: Simei Yin Date: Tue, 29 May 2018 22:59:52 +0200 Subject: SLUDGE: Move function/variable load/save functions to related files --- engines/sludge/function.cpp | 62 ++++++++++ engines/sludge/function.h | 3 + engines/sludge/loadsave.cpp | 270 -------------------------------------------- engines/sludge/loadsave.h | 15 --- engines/sludge/variable.cpp | 204 +++++++++++++++++++++++++++++++++ engines/sludge/variable.h | 10 ++ 6 files changed, 279 insertions(+), 285 deletions(-) diff --git a/engines/sludge/function.cpp b/engines/sludge/function.cpp index 6905c384bc..0a7a344d84 100644 --- a/engines/sludge/function.cpp +++ b/engines/sludge/function.cpp @@ -735,4 +735,66 @@ bool runAllFunctions() { return true; } +void saveFunction(LoadedFunction *fun, Common::WriteStream *stream) { + int a; + stream->writeUint16BE(fun->originalNumber); + if (fun->calledBy) { + stream->writeByte(1); + saveFunction(fun->calledBy, stream); + } else { + stream->writeByte(0); + } + stream->writeUint32LE(fun->timeLeft); + stream->writeUint16BE(fun->runThisLine); + stream->writeByte(fun->cancelMe); + stream->writeByte(fun->returnSomething); + stream->writeByte(fun->isSpeech); + saveVariable(&(fun->reg), stream); + + if (fun->freezerLevel) { + fatal(ERROR_GAME_SAVE_FROZEN); + } + saveStack(fun->stack, stream); + for (a = 0; a < fun->numLocals; a++) { + saveVariable(&(fun->localVars[a]), stream); + } +} + +LoadedFunction *loadFunction(Common::SeekableReadStream *stream) { + int a; + + // Reserve memory... + + LoadedFunction *buildFunc = new LoadedFunction; + if (!checkNew(buildFunc)) + return NULL; + + // See what it was called by and load if we need to... + + buildFunc->originalNumber = stream->readUint16BE(); + buildFunc->calledBy = NULL; + if (stream->readByte()) { + buildFunc->calledBy = loadFunction(stream); + if (!buildFunc->calledBy) + return NULL; + } + + buildFunc->timeLeft = stream->readUint32LE(); + buildFunc->runThisLine = stream->readUint16BE(); + buildFunc->freezerLevel = 0; + buildFunc->cancelMe = stream->readByte(); + buildFunc->returnSomething = stream->readByte(); + buildFunc->isSpeech = stream->readByte(); + loadVariable(&(buildFunc->reg), stream); + loadFunctionCode(buildFunc); + + buildFunc->stack = loadStack(stream, NULL); + + for (a = 0; a < buildFunc->numLocals; a++) { + loadVariable(&(buildFunc->localVars[a]), stream); + } + + return buildFunc; +} + } // End of namespace Sludge diff --git a/engines/sludge/function.h b/engines/sludge/function.h index 6980d6b10c..005760a960 100644 --- a/engines/sludge/function.h +++ b/engines/sludge/function.h @@ -65,6 +65,9 @@ void completeTimers(); void killSpeechTimers(); int cancelAFunction(int funcNum, LoadedFunction *myself, bool &killedMyself); +LoadedFunction *loadFunction(Common::SeekableReadStream *stream); +void saveFunction(LoadedFunction *fun, Common::WriteStream *stream); + } // End of namespace Sludge #endif diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp index 923c1713e6..4a78b83d29 100644 --- a/engines/sludge/loadsave.cpp +++ b/engines/sludge/loadsave.cpp @@ -58,281 +58,11 @@ namespace Sludge { extern LoadedFunction *saverFunc; // In function.cpp extern LoadedFunction *allRunningFunctions; // In sludger.cpp -extern const char *typeName[]; // In variable.cpp extern int numGlobals; // In sludger.cpp extern Variable *globalVars; // In sludger.cpp extern FILETIME fileTime; // In sludger.cpp extern bool allowAnyFilename; -//---------------------------------------------------------------------- -// Globals (so we know what's saved already and what's a reference -//---------------------------------------------------------------------- - -struct stackLibrary { - StackHandler *stack; - stackLibrary *next; -}; - -int stackLibTotal = 0; -stackLibrary *stackLib = NULL; - -//---------------------------------------------------------------------- -// For saving and loading stacks... -//---------------------------------------------------------------------- -void saveStack(VariableStack *vs, Common::WriteStream *stream) { - int elements = 0; - int a; - - VariableStack *search = vs; - while (search) { - elements++; - search = search->next; - } - - stream->writeUint16BE(elements); - search = vs; - for (a = 0; a < elements; a++) { - saveVariable(&search->thisVar, stream); - search = search->next; - } -} - -VariableStack *loadStack(Common::SeekableReadStream *stream, VariableStack **last) { - int elements = stream->readUint16BE(); - int a; - VariableStack *first = NULL; - VariableStack **changeMe = &first; - - for (a = 0; a < elements; a++) { - VariableStack *nS = new VariableStack; - if (!checkNew(nS)) - return NULL; - loadVariable(&(nS->thisVar), stream); - if (last && a == elements - 1) { - *last = nS; - } - nS->next = NULL; - (*changeMe) = nS; - changeMe = &(nS->next); - } - - return first; -} - -bool saveStackRef(StackHandler *vs, Common::WriteStream *stream) { - stackLibrary *s = stackLib; - int a = 0; - while (s) { - if (s->stack == vs) { - stream->writeByte(1); - stream->writeUint16BE(stackLibTotal - a); - return true; - } - s = s->next; - a++; - } - stream->writeByte(0); - saveStack(vs->first, stream); - s = new stackLibrary; - stackLibTotal++; - if (!checkNew(s)) - return false; - s->next = stackLib; - s->stack = vs; - stackLib = s; - return true; -} - -void clearStackLib() { - stackLibrary *k; - while (stackLib) { - k = stackLib; - stackLib = stackLib->next; - delete k; - } - stackLibTotal = 0; -} - -StackHandler *getStackFromLibrary(int n) { - n = stackLibTotal - n; - while (n) { - stackLib = stackLib->next; - n--; - } - return stackLib->stack; -} - -StackHandler *loadStackRef(Common::SeekableReadStream *stream) { - StackHandler *nsh; - - if (stream->readByte()) { // It's one we've loaded already... - nsh = getStackFromLibrary(stream->readUint16BE()); - nsh->timesUsed++; - } else { - // Load the new stack - - nsh = new StackHandler; - if (!checkNew(nsh)) - return NULL; - nsh->last = NULL; - nsh->first = loadStack(stream, &nsh->last); - nsh->timesUsed = 1; - - // Add it to the library of loaded stacks - - stackLibrary *s = new stackLibrary; - if (!checkNew(s)) - return NULL; - s->stack = nsh; - s->next = stackLib; - stackLib = s; - stackLibTotal++; - } - return nsh; -} - -//---------------------------------------------------------------------- -// For saving and loading variables... -//---------------------------------------------------------------------- -bool saveVariable(Variable *from, Common::WriteStream *stream) { - stream->writeByte(from->varType); - switch (from->varType) { - case SVT_INT: - case SVT_FUNC: - case SVT_BUILT: - case SVT_FILE: - case SVT_OBJTYPE: - stream->writeUint32LE(from->varData.intValue); - return true; - - case SVT_STRING: - writeString(from->varData.theString, stream); - return true; - - case SVT_STACK: - return saveStackRef(from->varData.theStack, stream); - - case SVT_COSTUME: - from->varData.costumeHandler->save(stream); - return false; - - case SVT_ANIM: - from->varData.animHandler->save(stream); - return false; - - case SVT_NULL: - return false; - - default: - fatal("Can't save variables of this type:", (from->varType < SVT_NUM_TYPES) ? typeName[from->varType] : "bad ID"); - } - return true; -} - -bool loadVariable(Variable *to, Common::SeekableReadStream *stream) { - to->varType = (VariableType)stream->readByte(); - switch (to->varType) { - case SVT_INT: - case SVT_FUNC: - case SVT_BUILT: - case SVT_FILE: - case SVT_OBJTYPE: - to->varData.intValue = stream->readUint32LE(); - return true; - - case SVT_STRING: - to->varData.theString = createCString(readString(stream)); - return true; - - case SVT_STACK: - to->varData.theStack = loadStackRef(stream); - return true; - - case SVT_COSTUME: - to->varData.costumeHandler = new Persona; - if (!checkNew(to->varData.costumeHandler)) - return false; - to->varData.costumeHandler->load(stream); - return true; - - case SVT_ANIM: - to->varData.animHandler = new PersonaAnimation; - if (!checkNew(to->varData.animHandler)) - return false; - to->varData.animHandler->load(stream); - return true; - - default: - break; - } - return true; -} - -//---------------------------------------------------------------------- -// For saving and loading functions -//---------------------------------------------------------------------- -void saveFunction(LoadedFunction *fun, Common::WriteStream *stream) { - int a; - stream->writeUint16BE(fun->originalNumber); - if (fun->calledBy) { - stream->writeByte(1); - saveFunction(fun->calledBy, stream); - } else { - stream->writeByte(0); - } - stream->writeUint32LE(fun->timeLeft); - stream->writeUint16BE(fun->runThisLine); - stream->writeByte(fun->cancelMe); - stream->writeByte(fun->returnSomething); - stream->writeByte(fun->isSpeech); - saveVariable(&(fun->reg), stream); - - if (fun->freezerLevel) { - fatal(ERROR_GAME_SAVE_FROZEN); - } - saveStack(fun->stack, stream); - for (a = 0; a < fun->numLocals; a++) { - saveVariable(&(fun->localVars[a]), stream); - } -} - -LoadedFunction *loadFunction(Common::SeekableReadStream *stream) { - int a; - - // Reserve memory... - - LoadedFunction *buildFunc = new LoadedFunction; - if (!checkNew(buildFunc)) - return NULL; - - // See what it was called by and load if we need to... - - buildFunc->originalNumber = stream->readUint16BE(); - buildFunc->calledBy = NULL; - if (stream->readByte()) { - buildFunc->calledBy = loadFunction(stream); - if (!buildFunc->calledBy) - return NULL; - } - - buildFunc->timeLeft = stream->readUint32LE(); - buildFunc->runThisLine = stream->readUint16BE(); - buildFunc->freezerLevel = 0; - buildFunc->cancelMe = stream->readByte(); - buildFunc->returnSomething = stream->readByte(); - buildFunc->isSpeech = stream->readByte(); - loadVariable(&(buildFunc->reg), stream); - loadFunctionCode(buildFunc); - - buildFunc->stack = loadStack(stream, NULL); - - for (a = 0; a < buildFunc->numLocals; a++) { - loadVariable(&(buildFunc->localVars[a]), stream); - } - - return buildFunc; -} - //---------------------------------------------------------------------- // Save everything //---------------------------------------------------------------------- diff --git a/engines/sludge/loadsave.h b/engines/sludge/loadsave.h index 54e0577796..4077950cfb 100644 --- a/engines/sludge/loadsave.h +++ b/engines/sludge/loadsave.h @@ -24,25 +24,10 @@ namespace Sludge { -struct LoadedFunction; -struct Variable; -struct VariableStack; - bool handleSaveLoad(); - bool saveGame(const Common::String &fname); bool loadGame(const Common::String &fname); -bool saveVariable(Variable *from, Common::WriteStream *stream); -bool loadVariable(Variable *to, Common::SeekableReadStream *stream); - -VariableStack *loadStack(Common::SeekableReadStream *stream, VariableStack **last); -bool saveStackRef(StackHandler *vs, Common::WriteStream *stream); -StackHandler *loadStackRef(Common::SeekableReadStream *stream); - -LoadedFunction *loadFunction(Common::SeekableReadStream *stream); -void saveFunction(LoadedFunction *fun, Common::WriteStream *stream); - } // End of namespace Sludge #endif diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp index a663599d5a..35e1036568 100644 --- a/engines/sludge/variable.cpp +++ b/engines/sludge/variable.cpp @@ -537,4 +537,208 @@ void trimStack(VariableStack *&stack) { delete killMe; } +//---------------------------------------------------------------------- +// Globals (so we know what's saved already and what's a reference +//---------------------------------------------------------------------- + +struct stackLibrary { + StackHandler *stack; + stackLibrary *next; +}; + +int stackLibTotal = 0; +stackLibrary *stackLib = NULL; + +//---------------------------------------------------------------------- +// For saving and loading stacks... +//---------------------------------------------------------------------- +void saveStack(VariableStack *vs, Common::WriteStream *stream) { + int elements = 0; + int a; + + VariableStack *search = vs; + while (search) { + elements++; + search = search->next; + } + + stream->writeUint16BE(elements); + search = vs; + for (a = 0; a < elements; a++) { + saveVariable(&search->thisVar, stream); + search = search->next; + } +} + +VariableStack *loadStack(Common::SeekableReadStream *stream, VariableStack **last) { + int elements = stream->readUint16BE(); + int a; + VariableStack *first = NULL; + VariableStack **changeMe = &first; + + for (a = 0; a < elements; a++) { + VariableStack *nS = new VariableStack; + if (!checkNew(nS)) + return NULL; + loadVariable(&(nS->thisVar), stream); + if (last && a == elements - 1) { + *last = nS; + } + nS->next = NULL; + (*changeMe) = nS; + changeMe = &(nS->next); + } + + return first; +} + +bool saveStackRef(StackHandler *vs, Common::WriteStream *stream) { + stackLibrary *s = stackLib; + int a = 0; + while (s) { + if (s->stack == vs) { + stream->writeByte(1); + stream->writeUint16BE(stackLibTotal - a); + return true; + } + s = s->next; + a++; + } + stream->writeByte(0); + saveStack(vs->first, stream); + s = new stackLibrary; + stackLibTotal++; + if (!checkNew(s)) + return false; + s->next = stackLib; + s->stack = vs; + stackLib = s; + return true; +} + +void clearStackLib() { + stackLibrary *k; + while (stackLib) { + k = stackLib; + stackLib = stackLib->next; + delete k; + } + stackLibTotal = 0; +} + +StackHandler *getStackFromLibrary(int n) { + n = stackLibTotal - n; + while (n) { + stackLib = stackLib->next; + n--; + } + return stackLib->stack; +} + +StackHandler *loadStackRef(Common::SeekableReadStream *stream) { + StackHandler *nsh; + + if (stream->readByte()) { // It's one we've loaded already... + nsh = getStackFromLibrary(stream->readUint16BE()); + nsh->timesUsed++; + } else { + // Load the new stack + + nsh = new StackHandler; + if (!checkNew(nsh)) + return NULL; + nsh->last = NULL; + nsh->first = loadStack(stream, &nsh->last); + nsh->timesUsed = 1; + + // Add it to the library of loaded stacks + + stackLibrary *s = new stackLibrary; + if (!checkNew(s)) + return NULL; + s->stack = nsh; + s->next = stackLib; + stackLib = s; + stackLibTotal++; + } + return nsh; +} + +//---------------------------------------------------------------------- +// For saving and loading variables... +//---------------------------------------------------------------------- +bool saveVariable(Variable *from, Common::WriteStream *stream) { + stream->writeByte(from->varType); + switch (from->varType) { + case SVT_INT: + case SVT_FUNC: + case SVT_BUILT: + case SVT_FILE: + case SVT_OBJTYPE: + stream->writeUint32LE(from->varData.intValue); + return true; + + case SVT_STRING: + writeString(from->varData.theString, stream); + return true; + + case SVT_STACK: + return saveStackRef(from->varData.theStack, stream); + + case SVT_COSTUME: + from->varData.costumeHandler->save(stream); + return false; + + case SVT_ANIM: + from->varData.animHandler->save(stream); + return false; + + case SVT_NULL: + return false; + + default: + fatal("Can't save variables of this type:", (from->varType < SVT_NUM_TYPES) ? typeName[from->varType] : "bad ID"); + } + return true; +} + +bool loadVariable(Variable *to, Common::SeekableReadStream *stream) { + to->varType = (VariableType)stream->readByte(); + switch (to->varType) { + case SVT_INT: + case SVT_FUNC: + case SVT_BUILT: + case SVT_FILE: + case SVT_OBJTYPE: + to->varData.intValue = stream->readUint32LE(); + return true; + + case SVT_STRING: + to->varData.theString = createCString(readString(stream)); + return true; + + case SVT_STACK: + to->varData.theStack = loadStackRef(stream); + return true; + + case SVT_COSTUME: + to->varData.costumeHandler = new Persona; + if (!checkNew(to->varData.costumeHandler)) + return false; + to->varData.costumeHandler->load(stream); + return true; + + case SVT_ANIM: + to->varData.animHandler = new PersonaAnimation; + if (!checkNew(to->varData.animHandler)) + return false; + to->varData.animHandler->load(stream); + return true; + + default: + break; + } + return true; +} + } // End of namespace Sludge diff --git a/engines/sludge/variable.h b/engines/sludge/variable.h index 27bf71a689..8f0d394514 100644 --- a/engines/sludge/variable.h +++ b/engines/sludge/variable.h @@ -119,6 +119,16 @@ bool makeFastArrayFromStack(Variable &to, const StackHandler *stacky); bool makeFastArraySize(Variable &to, int size); Variable *fastArrayGetByIndex(FastArrayHandler *vS, uint theIndex); +// load & save +bool saveVariable(Variable *from, Common::WriteStream *stream); +bool loadVariable(Variable *to, Common::SeekableReadStream *stream); + +void saveStack(VariableStack *vs, Common::WriteStream *stream); +VariableStack *loadStack(Common::SeekableReadStream *stream, VariableStack **last); +bool saveStackRef(StackHandler *vs, Common::WriteStream *stream); +StackHandler *loadStackRef(Common::SeekableReadStream *stream); +void clearStackLib(); + } // End of namespace Sludge #endif -- cgit v1.2.3