[Scummvm-git-logs] scummvm master -> 3e88827c4cea00dcc9f0fe90fc4a173c2b821b41
yinsimei
roseline.yin at gmail.com
Tue May 29 23:10:17 CEST 2018
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b6c2dc385a SLUDGE: Split out function.h/cpp for upcoming refactoring
0548765479 SLUDGE: Objectify FatalMsgManager
1ec5ef3e4d SLUDGE: Move resource names to ResourceManager
dc320b86bc SLUDGE: Create constructor of Variable instead of initVarNew
87e58a9b7e SLUDGE: Split runSludge() to runAllFunctions() and handleSaveLoad()
3e88827c4c SLUDGE: Move function/variable load/save functions to related files
Commit: b6c2dc385a2eb186026266c6eb015920b443cf81
https://github.com/scummvm/scummvm/commit/b6c2dc385a2eb186026266c6eb015920b443cf81
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:37:10+02:00
Commit Message:
SLUDGE: Split out function.h/cpp for upcoming refactoring
Changed paths:
A engines/sludge/function.cpp
A engines/sludge/function.h
engines/sludge/builtin.cpp
engines/sludge/builtin.h
engines/sludge/csludge.h
engines/sludge/event.cpp
engines/sludge/loadsave.cpp
engines/sludge/main_loop.cpp
engines/sludge/module.mk
engines/sludge/people.cpp
engines/sludge/people.h
engines/sludge/sludger.cpp
engines/sludge/sludger.h
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index 8646dd4..0d1d940 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -32,6 +32,7 @@
#include "sludge/floor.h"
#include "sludge/fonttext.h"
#include "sludge/freeze.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/language.h"
#include "sludge/loadsave.h"
@@ -86,7 +87,7 @@ bool failSecurityCheck(const Common::String &fn) {
return false;
}
-LoadedFunction *saverFunc;
+extern LoadedFunction *saverFunc;
typedef BuiltReturn (*builtInSludgeFunc)(int numParams, LoadedFunction *fun);
struct builtInFunctionData {
diff --git a/engines/sludge/builtin.h b/engines/sludge/builtin.h
index b2274c2..b7fa8b8 100644
--- a/engines/sludge/builtin.h
+++ b/engines/sludge/builtin.h
@@ -23,6 +23,8 @@
#ifndef SLUDGE_BUILTIN_H
#define SLUDGE_BUILTIN_H
+#include "sludge/allfiles.h"
+
namespace Sludge {
struct LoadedFunction;
diff --git a/engines/sludge/csludge.h b/engines/sludge/csludge.h
index 435a220..cf0d6aa 100644
--- a/engines/sludge/csludge.h
+++ b/engines/sludge/csludge.h
@@ -25,7 +25,7 @@
namespace Sludge {
-enum sludgeCommand {
+enum SludgeCommand {
SLU_UNKNOWN,
SLU_RETURN,
SLU_BRANCH,
diff --git a/engines/sludge/event.cpp b/engines/sludge/event.cpp
index b553702..d6afe2f 100644
--- a/engines/sludge/event.cpp
+++ b/engines/sludge/event.cpp
@@ -25,6 +25,7 @@
#include "sludge/event.h"
#include "sludge/freeze.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/newfatal.h"
#include "sludge/region.h"
diff --git a/engines/sludge/function.cpp b/engines/sludge/function.cpp
new file mode 100644
index 0000000..8aa69f0
--- /dev/null
+++ b/engines/sludge/function.cpp
@@ -0,0 +1,753 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sludge/builtin.h"
+#include "sludge/function.h"
+#include "sludge/loadsave.h"
+#include "sludge/newfatal.h"
+#include "sludge/people.h"
+#include "sludge/sludge.h"
+#include "sludge/sound.h"
+#include "sludge/speech.h"
+
+namespace Sludge {
+
+int numBIFNames = 0;
+Common::String *allBIFNames = NULL;
+int numUserFunc = 0;
+Common::String *allUserFunc = NULL;
+
+LoadedFunction *saverFunc;
+LoadedFunction *allRunningFunctions = NULL;
+VariableStack *noStack = NULL;
+Variable *globalVars = NULL;
+
+const char *sludgeText[] = { "?????", "RETURN", "BRANCH", "BR_ZERO",
+ "SET_GLOBAL", "SET_LOCAL", "LOAD_GLOBAL", "LOAD_LOCAL", "PLUS", "MINUS",
+ "MULT", "DIVIDE", "AND", "OR", "EQUALS", "NOT_EQ", "MODULUS",
+ "LOAD_VALUE", "LOAD_BUILT", "LOAD_FUNC", "CALLIT", "LOAD_STRING",
+ "LOAD_FILE", "LOAD_OBJTYPE", "NOT", "LOAD_NULL", "STACK_PUSH",
+ "LESSTHAN", "MORETHAN", "NEGATIVE", "U", "LESS_EQUAL", "MORE_EQUAL",
+ "INC_LOCAL", "DEC_LOCAL", "INC_GLOBAL", "DEC_GLOBAL", "INDEXSET",
+ "INDEXGET", "INC_INDEX", "DEC_INDEX", "QUICK_PUSH" };
+
+void pauseFunction(LoadedFunction *fun) {
+ LoadedFunction **huntAndDestroy = &allRunningFunctions;
+ while (*huntAndDestroy) {
+ if (fun == *huntAndDestroy) {
+ (*huntAndDestroy) = (*huntAndDestroy)->next;
+ fun->next = NULL;
+ } else {
+ huntAndDestroy = &(*huntAndDestroy)->next;
+ }
+ }
+}
+
+void restartFunction(LoadedFunction *fun) {
+ fun->next = allRunningFunctions;
+ allRunningFunctions = fun;
+}
+
+void killSpeechTimers() {
+ LoadedFunction *thisFunction = allRunningFunctions;
+
+ while (thisFunction) {
+ if (thisFunction->freezerLevel == 0 && thisFunction->isSpeech
+ && thisFunction->timeLeft) {
+ thisFunction->timeLeft = 0;
+ thisFunction->isSpeech = false;
+ }
+ thisFunction = thisFunction->next;
+ }
+
+ g_sludge->_speechMan->kill();
+}
+
+void completeTimers() {
+ LoadedFunction *thisFunction = allRunningFunctions;
+
+ while (thisFunction) {
+ if (thisFunction->freezerLevel == 0)
+ thisFunction->timeLeft = 0;
+ thisFunction = thisFunction->next;
+ }
+}
+
+void finishFunction(LoadedFunction *fun) {
+ int a;
+
+ pauseFunction(fun);
+ if (fun->stack)
+ fatal(ERROR_NON_EMPTY_STACK);
+ delete[] fun->compiledLines;
+ for (a = 0; a < fun->numLocals; a++)
+ unlinkVar(fun->localVars[a]);
+ delete[] fun->localVars;
+ unlinkVar(fun->reg);
+ delete fun;
+ fun = NULL;
+}
+
+void abortFunction(LoadedFunction *fun) {
+ int a;
+
+ pauseFunction(fun);
+ while (fun->stack)
+ trimStack(fun->stack);
+ delete []fun->compiledLines;
+ for (a = 0; a < fun->numLocals; a++)
+ unlinkVar(fun->localVars[a]);
+ delete []fun->localVars;
+ unlinkVar(fun->reg);
+ if (fun->calledBy)
+ abortFunction(fun->calledBy);
+ delete fun;
+ fun = NULL;
+}
+
+int cancelAFunction(int funcNum, LoadedFunction *myself, bool &killedMyself) {
+ int n = 0;
+ killedMyself = false;
+
+ LoadedFunction *fun = allRunningFunctions;
+ while (fun) {
+ if (fun->originalNumber == funcNum) {
+ fun->cancelMe = true;
+ n++;
+ if (fun == myself)
+ killedMyself = true;
+ }
+ fun = fun->next;
+ }
+ return n;
+}
+
+void freezeSubs() {
+ LoadedFunction *thisFunction = allRunningFunctions;
+
+ while (thisFunction) {
+ if (thisFunction->unfreezable) {
+ //msgBox ("SLUDGE debugging bollocks!", "Trying to freeze an unfreezable function!");
+ } else {
+ thisFunction->freezerLevel++;
+ }
+ thisFunction = thisFunction->next;
+ }
+}
+
+void unfreezeSubs() {
+ LoadedFunction *thisFunction = allRunningFunctions;
+
+ while (thisFunction) {
+ if (thisFunction->freezerLevel)
+ thisFunction->freezerLevel--;
+ thisFunction = thisFunction->next;
+ }
+}
+
+bool continueFunction(LoadedFunction *fun) {
+ bool keepLooping = true;
+ bool advanceNow;
+ uint param;
+ SludgeCommand com;
+
+ if (fun->cancelMe) {
+ abortFunction(fun);
+ return true;
+ }
+
+ while (keepLooping) {
+ advanceNow = true;
+ debugC(1, kSludgeDebugStackMachine, "Executing command line %i : ", fun->runThisLine);
+ param = fun->compiledLines[fun->runThisLine].param;
+ com = fun->compiledLines[fun->runThisLine].theCommand;
+
+ if (numBIFNames) {
+ setFatalInfo((fun->originalNumber < numUserFunc) ? allUserFunc[fun->originalNumber] : "Unknown user function", (com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE);
+ }
+
+ switch (com) {
+ case SLU_RETURN:
+ if (fun->calledBy) {
+ LoadedFunction *returnTo = fun->calledBy;
+ if (fun->returnSomething)
+ copyVariable(fun->reg, returnTo->reg);
+ finishFunction(fun);
+ fun = returnTo;
+ restartFunction(fun);
+ } else {
+ finishFunction(fun);
+ advanceNow = false; // So we don't do anything else with "fun"
+ keepLooping = false; // So we drop out of the loop
+ }
+ break;
+
+ case SLU_CALLIT:
+ switch (fun->reg.varType) {
+ case SVT_FUNC:
+ pauseFunction(fun);
+ if (numBIFNames)
+ setFatalInfo(
+ (fun->originalNumber < numUserFunc) ?
+ allUserFunc[fun->originalNumber] :
+ "Unknown user function",
+ (fun->reg.varData.intValue < numUserFunc) ?
+ allUserFunc[fun->reg.varData.intValue] :
+ "Unknown user function");
+
+ if (!startNewFunctionNum(fun->reg.varData.intValue, param, fun,
+ fun->stack))
+ return false;
+ fun = allRunningFunctions;
+ advanceNow = false; // So we don't do anything else with "fun"
+ break;
+
+ case SVT_BUILT: {
+ debugC(1, kSludgeDebugStackMachine, "Built-in init value: %i",
+ fun->reg.varData.intValue);
+ BuiltReturn br = callBuiltIn(fun->reg.varData.intValue, param,
+ fun);
+
+ switch (br) {
+ case BR_ERROR:
+ return fatal(
+ "Unknown error. This shouldn't happen. Please notify the SLUDGE developers.");
+
+ case BR_PAUSE:
+ pauseFunction(fun);
+ // fall through
+
+ case BR_KEEP_AND_PAUSE:
+ keepLooping = false;
+ break;
+
+ case BR_ALREADY_GONE:
+ keepLooping = false;
+ advanceNow = false;
+ break;
+
+ case BR_CALLAFUNC: {
+ int i = fun->reg.varData.intValue;
+ setVariable(fun->reg, SVT_INT, 1);
+ pauseFunction(fun);
+ if (numBIFNames)
+ setFatalInfo(
+ (fun->originalNumber < numUserFunc) ?
+ allUserFunc[fun->originalNumber] :
+ "Unknown user function",
+ (i < numUserFunc) ?
+ allUserFunc[i] :
+ "Unknown user function");
+ if (!startNewFunctionNum(i, 0, fun, noStack, false))
+ return false;
+ fun = allRunningFunctions;
+ advanceNow = false; // So we don't do anything else with "fun"
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ return fatal(ERROR_CALL_NONFUNCTION);
+ }
+ break;
+
+ // These all grab things and shove 'em into the register
+
+ case SLU_LOAD_NULL:
+ setVariable(fun->reg, SVT_NULL, 0);
+ break;
+
+ case SLU_LOAD_FILE:
+ setVariable(fun->reg, SVT_FILE, param);
+ break;
+
+ case SLU_LOAD_VALUE:
+ setVariable(fun->reg, SVT_INT, param);
+ break;
+
+ case SLU_LOAD_LOCAL:
+ if (!copyVariable(fun->localVars[param], fun->reg))
+ return false;
+ break;
+
+ case SLU_AND:
+ setVariable(fun->reg, SVT_INT,
+ getBoolean(fun->reg) && getBoolean(fun->stack->thisVar));
+ trimStack(fun->stack);
+ break;
+
+ case SLU_OR:
+ setVariable(fun->reg, SVT_INT,
+ getBoolean(fun->reg) || getBoolean(fun->stack->thisVar));
+ trimStack(fun->stack);
+ break;
+
+ case SLU_LOAD_FUNC:
+ setVariable(fun->reg, SVT_FUNC, param);
+ break;
+
+ case SLU_LOAD_BUILT:
+ setVariable(fun->reg, SVT_BUILT, param);
+ break;
+
+ case SLU_LOAD_OBJTYPE:
+ setVariable(fun->reg, SVT_OBJTYPE, param);
+ break;
+
+ case SLU_UNREG:
+ break;
+
+ case SLU_LOAD_STRING:
+ if (!loadStringToVar(fun->reg, param)) {
+ return false;
+ }
+ break;
+
+ case SLU_INDEXGET:
+ case SLU_INCREMENT_INDEX:
+ case SLU_DECREMENT_INDEX:
+ switch (fun->stack->thisVar.varType) {
+ case SVT_NULL:
+ if (com == SLU_INDEXGET) {
+ setVariable(fun->reg, SVT_NULL, 0);
+ trimStack(fun->stack);
+ } else {
+ return fatal(ERROR_INCDEC_UNKNOWN);
+ }
+ break;
+
+ case SVT_FASTARRAY:
+ case SVT_STACK:
+ if (fun->stack->thisVar.varData.theStack->first == NULL) {
+ return fatal(ERROR_INDEX_EMPTY);
+ } else {
+ int ii;
+ if (!getValueType(ii, SVT_INT, fun->reg))
+ return false;
+ Variable *grab =
+ (fun->stack->thisVar.varType == SVT_FASTARRAY) ?
+ fastArrayGetByIndex(
+ fun->stack->thisVar.varData.fastArray,
+ ii) :
+ stackGetByIndex(
+ fun->stack->thisVar.varData.theStack->first,
+ ii);
+
+ trimStack(fun->stack);
+
+ if (!grab) {
+ setVariable(fun->reg, SVT_NULL, 0);
+ } else {
+ int kk;
+ switch (com) {
+ case SLU_INCREMENT_INDEX:
+ if (!getValueType(kk, SVT_INT, *grab))
+ return false;
+ setVariable(fun->reg, SVT_INT, kk);
+ grab->varData.intValue = kk + 1;
+ break;
+
+ case SLU_DECREMENT_INDEX:
+ if (!getValueType(kk, SVT_INT, *grab))
+ return false;
+ setVariable(fun->reg, SVT_INT, kk);
+ grab->varData.intValue = kk - 1;
+ break;
+
+ default:
+ if (!copyVariable(*grab, fun->reg))
+ return false;
+ }
+ }
+ }
+ break;
+
+ default:
+ return fatal(ERROR_INDEX_NONSTACK);
+ }
+ break;
+
+ case SLU_INDEXSET:
+ switch (fun->stack->thisVar.varType) {
+ case SVT_STACK:
+ if (fun->stack->thisVar.varData.theStack->first == NULL) {
+ return fatal(ERROR_INDEX_EMPTY);
+ } else {
+ int ii;
+ if (!getValueType(ii, SVT_INT, fun->reg))
+ return false;
+ if (!stackSetByIndex(
+ fun->stack->thisVar.varData.theStack->first, ii,
+ fun->stack->next->thisVar)) {
+ return false;
+ }
+ trimStack(fun->stack);
+ trimStack(fun->stack);
+ }
+ break;
+
+ case SVT_FASTARRAY: {
+ int ii;
+ if (!getValueType(ii, SVT_INT, fun->reg))
+ return false;
+ Variable *v = fastArrayGetByIndex(
+ fun->stack->thisVar.varData.fastArray, ii);
+ if (v == NULL)
+ return fatal("Not within bounds of fast array.");
+ if (!copyVariable(fun->stack->next->thisVar, *v))
+ return false;
+ trimStack(fun->stack);
+ trimStack(fun->stack);
+ }
+ break;
+
+ default:
+ return fatal(ERROR_INDEX_NONSTACK);
+ }
+ break;
+
+ // What can we do with the register? Well, we can copy it into a local
+ // variable, a global or onto the stack...
+
+ case SLU_INCREMENT_LOCAL: {
+ int ii;
+ if (!getValueType(ii, SVT_INT, fun->localVars[param]))
+ return false;
+ setVariable(fun->reg, SVT_INT, ii);
+ setVariable(fun->localVars[param], SVT_INT, ii + 1);
+ }
+ break;
+
+ case SLU_INCREMENT_GLOBAL: {
+ int ii;
+ if (!getValueType(ii, SVT_INT, globalVars[param]))
+ return false;
+ setVariable(fun->reg, SVT_INT, ii);
+ setVariable(globalVars[param], SVT_INT, ii + 1);
+ }
+ break;
+
+ case SLU_DECREMENT_LOCAL: {
+ int ii;
+ if (!getValueType(ii, SVT_INT, fun->localVars[param]))
+ return false;
+ setVariable(fun->reg, SVT_INT, ii);
+ setVariable(fun->localVars[param], SVT_INT, ii - 1);
+ }
+ break;
+
+ case SLU_DECREMENT_GLOBAL: {
+ int ii;
+ if (!getValueType(ii, SVT_INT, globalVars[param]))
+ return false;
+ setVariable(fun->reg, SVT_INT, ii);
+ setVariable(globalVars[param], SVT_INT, ii - 1);
+ }
+ break;
+
+ case SLU_SET_LOCAL:
+ if (!copyVariable(fun->reg, fun->localVars[param]))
+ return false;
+ break;
+
+ case SLU_SET_GLOBAL:
+// newDebug (" Copying TO global variable", param);
+// newDebug (" Global type at the moment", globalVars[param].varType);
+ if (!copyVariable(fun->reg, globalVars[param]))
+ return false;
+// newDebug (" New type", globalVars[param].varType);
+ break;
+
+ case SLU_LOAD_GLOBAL:
+// newDebug (" Copying FROM global variable", param);
+// newDebug (" Global type at the moment", globalVars[param].varType);
+ if (!copyVariable(globalVars[param], fun->reg))
+ return false;
+ break;
+
+ case SLU_STACK_PUSH:
+ if (!addVarToStack(fun->reg, fun->stack))
+ return false;
+ break;
+
+ case SLU_QUICK_PUSH:
+ if (!addVarToStackQuick(fun->reg, fun->stack))
+ return false;
+ break;
+
+ case SLU_NOT:
+ setVariable(fun->reg, SVT_INT, !getBoolean(fun->reg));
+ break;
+
+ case SLU_BR_ZERO:
+ if (!getBoolean(fun->reg)) {
+ advanceNow = false;
+ fun->runThisLine = param;
+ }
+ break;
+
+ case SLU_BRANCH:
+ advanceNow = false;
+ fun->runThisLine = param;
+ break;
+
+ case SLU_NEGATIVE: {
+ int i;
+ if (!getValueType(i, SVT_INT, fun->reg))
+ return false;
+ setVariable(fun->reg, SVT_INT, -i);
+ }
+ break;
+
+ // All these things rely on there being somet' on the stack
+
+ case SLU_MULT:
+ case SLU_PLUS:
+ case SLU_MINUS:
+ case SLU_MODULUS:
+ case SLU_DIVIDE:
+ case SLU_EQUALS:
+ case SLU_NOT_EQ:
+ case SLU_LESSTHAN:
+ case SLU_MORETHAN:
+ case SLU_LESS_EQUAL:
+ case SLU_MORE_EQUAL:
+ if (fun->stack) {
+ int firstValue, secondValue;
+
+ switch (com) {
+ case SLU_PLUS:
+ addVariablesInSecond(fun->stack->thisVar, fun->reg);
+ trimStack(fun->stack);
+ break;
+
+ case SLU_EQUALS:
+ compareVariablesInSecond(fun->stack->thisVar, fun->reg);
+ trimStack(fun->stack);
+ break;
+
+ case SLU_NOT_EQ:
+ compareVariablesInSecond(fun->stack->thisVar, fun->reg);
+ trimStack(fun->stack);
+ fun->reg.varData.intValue = !fun->reg.varData.intValue;
+ break;
+
+ default:
+ if (!getValueType(firstValue, SVT_INT, fun->stack->thisVar))
+ return false;
+ if (!getValueType(secondValue, SVT_INT, fun->reg))
+ return false;
+ trimStack(fun->stack);
+
+ switch (com) {
+ case SLU_MULT:
+ setVariable(fun->reg, SVT_INT,
+ firstValue * secondValue);
+ break;
+
+ case SLU_MINUS:
+ setVariable(fun->reg, SVT_INT,
+ firstValue - secondValue);
+ break;
+
+ case SLU_MODULUS:
+ setVariable(fun->reg, SVT_INT,
+ firstValue % secondValue);
+ break;
+
+ case SLU_DIVIDE:
+ setVariable(fun->reg, SVT_INT,
+ firstValue / secondValue);
+ break;
+
+ case SLU_LESSTHAN:
+ setVariable(fun->reg, SVT_INT,
+ firstValue < secondValue);
+ break;
+
+ case SLU_MORETHAN:
+ setVariable(fun->reg, SVT_INT,
+ firstValue > secondValue);
+ break;
+
+ case SLU_LESS_EQUAL:
+ setVariable(fun->reg, SVT_INT,
+ firstValue <= secondValue);
+ break;
+
+ case SLU_MORE_EQUAL:
+ setVariable(fun->reg, SVT_INT,
+ firstValue >= secondValue);
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else {
+ return fatal(ERROR_NOSTACK);
+ }
+ break;
+
+ default:
+ return fatal(ERROR_UNKNOWN_CODE);
+ }
+
+ if (advanceNow)
+ fun->runThisLine++;
+
+ }
+ return true;
+}
+
+void killAllFunctions() {
+ while (allRunningFunctions)
+ finishFunction(allRunningFunctions);
+}
+
+bool loadFunctionCode(LoadedFunction *newFunc) {
+ uint numLines, numLinesRead;
+
+ if (!g_sludge->_resMan->openSubSlice(newFunc->originalNumber))
+ return false;
+
+ debugC(3, kSludgeDebugDataLoad, "Load function code");
+
+ Common::SeekableReadStream *readStream = g_sludge->_resMan->getData();
+ newFunc->unfreezable = readStream->readByte();
+ numLines = readStream->readUint16BE();
+ debugC(3, kSludgeDebugDataLoad, "numLines: %i", numLines);
+ newFunc->numArgs = readStream->readUint16BE();
+ debugC(3, kSludgeDebugDataLoad, "numArgs: %i", newFunc->numArgs);
+ newFunc->numLocals = readStream->readUint16BE();
+ debugC(3, kSludgeDebugDataLoad, "numLocals: %i", newFunc->numLocals);
+ newFunc->compiledLines = new LineOfCode[numLines];
+ if (!checkNew(newFunc->compiledLines))
+ return false;
+
+ for (numLinesRead = 0; numLinesRead < numLines; numLinesRead++) {
+ newFunc->compiledLines[numLinesRead].theCommand = (SludgeCommand)readStream->readByte();
+ newFunc->compiledLines[numLinesRead].param = readStream->readUint16BE();
+ debugC(3, kSludgeDebugDataLoad, "command line %i: %i", numLinesRead,
+ newFunc->compiledLines[numLinesRead].theCommand);
+ }
+ g_sludge->_resMan->finishAccess();
+
+ // Now we need to reserve memory for the local variables
+ newFunc->localVars = new Variable[newFunc->numLocals];
+ if (!checkNew(newFunc->localVars))
+ return false;
+ for (int a = 0; a < newFunc->numLocals; a++) {
+ initVarNew(newFunc->localVars[a]);
+ }
+
+ return true;
+}
+
+int startNewFunctionNum(uint funcNum, uint numParamsExpected,
+ LoadedFunction *calledBy, VariableStack *&vStack, bool returnSommet) {
+ LoadedFunction *newFunc = new LoadedFunction;
+ checkNew(newFunc);
+ newFunc->originalNumber = funcNum;
+
+ loadFunctionCode(newFunc);
+
+ if (newFunc->numArgs != (int) numParamsExpected)
+ return fatal("Wrong number of parameters!");
+ if (newFunc->numArgs > newFunc->numLocals)
+ return fatal("More arguments than local Variable space!");
+
+ // Now, lets copy the parameters from the calling function's stack...
+
+ while (numParamsExpected) {
+ numParamsExpected--;
+ if (vStack == NULL)
+ return fatal(
+ "Corrupted file!The stack's empty and there were still parameters expected");
+ copyVariable(vStack->thisVar, newFunc->localVars[numParamsExpected]);
+ trimStack(vStack);
+ }
+
+ newFunc->cancelMe = false;
+ newFunc->timeLeft = 0;
+ newFunc->returnSomething = returnSommet;
+ newFunc->calledBy = calledBy;
+ newFunc->stack = NULL;
+ newFunc->freezerLevel = 0;
+ newFunc->runThisLine = 0;
+ newFunc->isSpeech = 0;
+ initVarNew(newFunc->reg);
+
+ restartFunction(newFunc);
+ return 1;
+}
+
+bool runSludge() {
+
+ LoadedFunction *thisFunction = allRunningFunctions;
+ LoadedFunction *nextFunction;
+
+ while (thisFunction) {
+ nextFunction = thisFunction->next;
+
+ if (!thisFunction->freezerLevel) {
+ if (thisFunction->timeLeft) {
+ if (thisFunction->timeLeft < 0) {
+ if (!g_sludge->_soundMan->stillPlayingSound(
+ g_sludge->_speechMan->getLastSpeechSound())) {
+ thisFunction->timeLeft = 0;
+ }
+ } else if (!--(thisFunction->timeLeft)) {
+ }
+ } else {
+ if (thisFunction->isSpeech) {
+ thisFunction->isSpeech = false;
+ g_sludge->_speechMan->kill();
+ }
+ if (!continueFunction(thisFunction))
+ return false;
+ }
+ }
+
+ thisFunction = nextFunction;
+ }
+
+ if (!g_sludge->loadNow.empty()) {
+ if (g_sludge->loadNow[0] == ':') {
+ saveGame(g_sludge->loadNow.c_str() + 1);
+ setVariable(saverFunc->reg, SVT_INT, 1);
+ } else {
+ if (!loadGame(g_sludge->loadNow))
+ return false;
+ }
+ g_sludge->loadNow.clear();
+ }
+
+ return true;
+}
+
+} // End of namespace Sludge
diff --git a/engines/sludge/function.h b/engines/sludge/function.h
new file mode 100644
index 0000000..ead2adf
--- /dev/null
+++ b/engines/sludge/function.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef SLUDGE_FUNCTION_H
+#define SLUDGE_FUNCTION_H
+
+#include "sludge/allfiles.h"
+#include "sludge/csludge.h"
+#include "sludge/variable.h"
+
+namespace Sludge {
+
+struct Variable;
+struct VariableStack;
+
+struct LineOfCode {
+ SludgeCommand theCommand;
+ int32 param;
+};
+
+struct LoadedFunction {
+ int originalNumber;
+ LineOfCode *compiledLines;
+ int numLocals, timeLeft, numArgs;
+ Variable *localVars;
+ VariableStack *stack;
+ Variable reg;
+ uint runThisLine;
+ LoadedFunction *calledBy;
+ LoadedFunction *next;
+ bool returnSomething, isSpeech, unfreezable, cancelMe;
+ byte freezerLevel;
+};
+
+bool runSludge();
+
+int startNewFunctionNum(uint, uint, LoadedFunction *, VariableStack*&, bool = true);
+void restartFunction(LoadedFunction *fun);
+bool loadFunctionCode(LoadedFunction *newFunc);
+void killAllFunctions();
+
+void finishFunction(LoadedFunction *fun);
+void abortFunction(LoadedFunction *fun);
+
+void freezeSubs();
+void unfreezeSubs();
+void completeTimers();
+void killSpeechTimers();
+int cancelAFunction(int funcNum, LoadedFunction *myself, bool &killedMyself);
+
+} // End of namespace Sludge
+
+#endif
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index 8706f7f..2d29645 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -29,6 +29,7 @@
#include "sludge/event.h"
#include "sludge/floor.h"
#include "sludge/fonttext.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/language.h"
#include "sludge/loadsave.h"
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index 10f54d4..ee0bae1 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -28,6 +28,7 @@
#include "sludge/backdrop.h"
#include "sludge/event.h"
#include "sludge/floor.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/language.h"
#include "sludge/newfatal.h"
diff --git a/engines/sludge/module.mk b/engines/sludge/module.mk
index a083ec4..d904e6c 100644
--- a/engines/sludge/module.mk
+++ b/engines/sludge/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
floor.o \
freeze.o \
fonttext.o \
+ function.o \
graphics.o \
hsi.o \
imgloader.o \
diff --git a/engines/sludge/people.cpp b/engines/sludge/people.cpp
index 3624950..658954a 100644
--- a/engines/sludge/people.cpp
+++ b/engines/sludge/people.cpp
@@ -22,6 +22,7 @@
#include "sludge/allfiles.h"
#include "sludge/floor.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/loadsave.h"
#include "sludge/moreio.h"
diff --git a/engines/sludge/people.h b/engines/sludge/people.h
index 2d19a14..db22d19 100644
--- a/engines/sludge/people.h
+++ b/engines/sludge/people.h
@@ -30,6 +30,8 @@ struct FrozenStuffStruct;
struct LoadedSpriteBank;
struct ScreenRegion;
+class SludgeEngine;
+
struct AnimFrame {
int frameNum, howMany;
int noise;
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index 8bbf76e..cab0342 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -32,9 +32,9 @@
#include "sludge/freeze.h"
#include "sludge/floor.h"
#include "sludge/fileset.h"
+#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/imgloader.h"
-#include "sludge/loadsave.h"
#include "sludge/language.h"
#include "sludge/moreio.h"
#include "sludge/newfatal.h"
@@ -42,23 +42,24 @@
#include "sludge/people.h"
#include "sludge/region.h"
#include "sludge/savedata.h"
-#include "sludge/statusba.h"
-#include "sludge/sprites.h"
-#include "sludge/sprbanks.h"
-#include "sludge/sound.h"
#include "sludge/sludge.h"
#include "sludge/sludger.h"
+#include "sludge/sound.h"
#include "sludge/speech.h"
+#include "sludge/sprites.h"
+#include "sludge/sprbanks.h"
+#include "sludge/statusba.h"
#include "sludge/variable.h"
#include "sludge/version.h"
#include "sludge/zbuffer.h"
namespace Sludge {
-int numBIFNames = 0;
-Common::String *allBIFNames;
-int numUserFunc = 0;
-Common::String *allUserFunc = NULL;
+extern int numBIFNames;
+extern Common::String *allBIFNames;
+extern int numUserFunc;
+extern Common::String *allUserFunc;
+
int numResourceNames = 0;
Common::String *allResourceNames = NULL;
int selectedLanguage = 0;
@@ -66,28 +67,14 @@ int selectedLanguage = 0;
int gameVersion;
FILETIME fileTime;
-extern LoadedFunction *saverFunc;
-
-LoadedFunction *allRunningFunctions = NULL;
-VariableStack *noStack = NULL;
-Variable *globalVars;
-
int numGlobals = 0;
extern Variable *launchResult;
-extern int lastFramesPerSecond;
+extern Variable *globalVars;
+extern VariableStack *noStack;
extern bool allowAnyFilename;
-const char *sludgeText[] = { "?????", "RETURN", "BRANCH", "BR_ZERO",
- "SET_GLOBAL", "SET_LOCAL", "LOAD_GLOBAL", "LOAD_LOCAL", "PLUS", "MINUS",
- "MULT", "DIVIDE", "AND", "OR", "EQUALS", "NOT_EQ", "MODULUS",
- "LOAD_VALUE", "LOAD_BUILT", "LOAD_FUNC", "CALLIT", "LOAD_STRING",
- "LOAD_FILE", "LOAD_OBJTYPE", "NOT", "LOAD_NULL", "STACK_PUSH",
- "LESSTHAN", "MORETHAN", "NEGATIVE", "U", "LESS_EQUAL", "MORE_EQUAL",
- "INC_LOCAL", "DEC_LOCAL", "INC_GLOBAL", "DEC_GLOBAL", "INDEXSET",
- "INDEXGET", "INC_INDEX", "DEC_INDEX", "QUICK_PUSH" };
-
Common::File *openAndVerify(const Common::String &filename, char extra1, char extra2,
const char *er, int &fileVersion) {
Common::File *fp = new Common::File();
@@ -333,704 +320,4 @@ void sludgeDisplay() {
g_sludge->_gfxMan->display();
}
-void pauseFunction(LoadedFunction *fun) {
- LoadedFunction **huntAndDestroy = &allRunningFunctions;
- while (*huntAndDestroy) {
- if (fun == *huntAndDestroy) {
- (*huntAndDestroy) = (*huntAndDestroy)->next;
- fun->next = NULL;
- } else {
- huntAndDestroy = &(*huntAndDestroy)->next;
- }
- }
-}
-
-void restartFunction(LoadedFunction *fun) {
- fun->next = allRunningFunctions;
- allRunningFunctions = fun;
-}
-
-void killSpeechTimers() {
- LoadedFunction *thisFunction = allRunningFunctions;
-
- while (thisFunction) {
- if (thisFunction->freezerLevel == 0 && thisFunction->isSpeech
- && thisFunction->timeLeft) {
- thisFunction->timeLeft = 0;
- thisFunction->isSpeech = false;
- }
- thisFunction = thisFunction->next;
- }
-
- g_sludge->_speechMan->kill();
-}
-
-void completeTimers() {
- LoadedFunction *thisFunction = allRunningFunctions;
-
- while (thisFunction) {
- if (thisFunction->freezerLevel == 0)
- thisFunction->timeLeft = 0;
- thisFunction = thisFunction->next;
- }
-}
-
-void finishFunction(LoadedFunction *fun) {
- int a;
-
- pauseFunction(fun);
- if (fun->stack)
- fatal(ERROR_NON_EMPTY_STACK);
- delete[] fun->compiledLines;
- for (a = 0; a < fun->numLocals; a++)
- unlinkVar(fun->localVars[a]);
- delete[] fun->localVars;
- unlinkVar(fun->reg);
- delete fun;
- fun = NULL;
-}
-
-void abortFunction(LoadedFunction *fun) {
- int a;
-
- pauseFunction(fun);
- while (fun->stack)
- trimStack(fun->stack);
- delete []fun->compiledLines;
- for (a = 0; a < fun->numLocals; a++)
- unlinkVar(fun->localVars[a]);
- delete []fun->localVars;
- unlinkVar(fun->reg);
- if (fun->calledBy)
- abortFunction(fun->calledBy);
- delete fun;
- fun = NULL;
-}
-
-int cancelAFunction(int funcNum, LoadedFunction *myself, bool &killedMyself) {
- int n = 0;
- killedMyself = false;
-
- LoadedFunction *fun = allRunningFunctions;
- while (fun) {
- if (fun->originalNumber == funcNum) {
- fun->cancelMe = true;
- n++;
- if (fun == myself)
- killedMyself = true;
- }
- fun = fun->next;
- }
- return n;
-}
-
-void freezeSubs() {
- LoadedFunction *thisFunction = allRunningFunctions;
-
- while (thisFunction) {
- if (thisFunction->unfreezable) {
- //msgBox ("SLUDGE debugging bollocks!", "Trying to freeze an unfreezable function!");
- } else {
- thisFunction->freezerLevel++;
- }
- thisFunction = thisFunction->next;
- }
-}
-
-void unfreezeSubs() {
- LoadedFunction *thisFunction = allRunningFunctions;
-
- while (thisFunction) {
- if (thisFunction->freezerLevel)
- thisFunction->freezerLevel--;
- thisFunction = thisFunction->next;
- }
-}
-
-bool continueFunction(LoadedFunction *fun) {
- bool keepLooping = true;
- bool advanceNow;
- uint param;
- sludgeCommand com;
-
- if (fun->cancelMe) {
- abortFunction(fun);
- return true;
- }
-
- while (keepLooping) {
- advanceNow = true;
- debugC(1, kSludgeDebugStackMachine, "Executing command line %i : ", fun->runThisLine);
- param = fun->compiledLines[fun->runThisLine].param;
- com = fun->compiledLines[fun->runThisLine].theCommand;
-
- if (numBIFNames) {
- setFatalInfo((fun->originalNumber < numUserFunc) ? allUserFunc[fun->originalNumber] : "Unknown user function", (com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE);
- }
-
- switch (com) {
- case SLU_RETURN:
- if (fun->calledBy) {
- LoadedFunction *returnTo = fun->calledBy;
- if (fun->returnSomething)
- copyVariable(fun->reg, returnTo->reg);
- finishFunction(fun);
- fun = returnTo;
- restartFunction(fun);
- } else {
- finishFunction(fun);
- advanceNow = false; // So we don't do anything else with "fun"
- keepLooping = false; // So we drop out of the loop
- }
- break;
-
- case SLU_CALLIT:
- switch (fun->reg.varType) {
- case SVT_FUNC:
- pauseFunction(fun);
- if (numBIFNames)
- setFatalInfo(
- (fun->originalNumber < numUserFunc) ?
- allUserFunc[fun->originalNumber] :
- "Unknown user function",
- (fun->reg.varData.intValue < numUserFunc) ?
- allUserFunc[fun->reg.varData.intValue] :
- "Unknown user function");
-
- if (!startNewFunctionNum(fun->reg.varData.intValue, param, fun,
- fun->stack))
- return false;
- fun = allRunningFunctions;
- advanceNow = false; // So we don't do anything else with "fun"
- break;
-
- case SVT_BUILT: {
- debugC(1, kSludgeDebugStackMachine, "Built-in init value: %i",
- fun->reg.varData.intValue);
- BuiltReturn br = callBuiltIn(fun->reg.varData.intValue, param,
- fun);
-
- switch (br) {
- case BR_ERROR:
- return fatal(
- "Unknown error. This shouldn't happen. Please notify the SLUDGE developers.");
-
- case BR_PAUSE:
- pauseFunction(fun);
- // fall through
-
- case BR_KEEP_AND_PAUSE:
- keepLooping = false;
- break;
-
- case BR_ALREADY_GONE:
- keepLooping = false;
- advanceNow = false;
- break;
-
- case BR_CALLAFUNC: {
- int i = fun->reg.varData.intValue;
- setVariable(fun->reg, SVT_INT, 1);
- pauseFunction(fun);
- if (numBIFNames)
- setFatalInfo(
- (fun->originalNumber < numUserFunc) ?
- allUserFunc[fun->originalNumber] :
- "Unknown user function",
- (i < numUserFunc) ?
- allUserFunc[i] :
- "Unknown user function");
- if (!startNewFunctionNum(i, 0, fun, noStack, false))
- return false;
- fun = allRunningFunctions;
- advanceNow = false; // So we don't do anything else with "fun"
- }
- break;
-
- default:
- break;
- }
- }
- break;
-
- default:
- return fatal(ERROR_CALL_NONFUNCTION);
- }
- break;
-
- // These all grab things and shove 'em into the register
-
- case SLU_LOAD_NULL:
- setVariable(fun->reg, SVT_NULL, 0);
- break;
-
- case SLU_LOAD_FILE:
- setVariable(fun->reg, SVT_FILE, param);
- break;
-
- case SLU_LOAD_VALUE:
- setVariable(fun->reg, SVT_INT, param);
- break;
-
- case SLU_LOAD_LOCAL:
- if (!copyVariable(fun->localVars[param], fun->reg))
- return false;
- break;
-
- case SLU_AND:
- setVariable(fun->reg, SVT_INT,
- getBoolean(fun->reg) && getBoolean(fun->stack->thisVar));
- trimStack(fun->stack);
- break;
-
- case SLU_OR:
- setVariable(fun->reg, SVT_INT,
- getBoolean(fun->reg) || getBoolean(fun->stack->thisVar));
- trimStack(fun->stack);
- break;
-
- case SLU_LOAD_FUNC:
- setVariable(fun->reg, SVT_FUNC, param);
- break;
-
- case SLU_LOAD_BUILT:
- setVariable(fun->reg, SVT_BUILT, param);
- break;
-
- case SLU_LOAD_OBJTYPE:
- setVariable(fun->reg, SVT_OBJTYPE, param);
- break;
-
- case SLU_UNREG:
- break;
-
- case SLU_LOAD_STRING:
- if (!loadStringToVar(fun->reg, param)) {
- return false;
- }
- break;
-
- case SLU_INDEXGET:
- case SLU_INCREMENT_INDEX:
- case SLU_DECREMENT_INDEX:
- switch (fun->stack->thisVar.varType) {
- case SVT_NULL:
- if (com == SLU_INDEXGET) {
- setVariable(fun->reg, SVT_NULL, 0);
- trimStack(fun->stack);
- } else {
- return fatal(ERROR_INCDEC_UNKNOWN);
- }
- break;
-
- case SVT_FASTARRAY:
- case SVT_STACK:
- if (fun->stack->thisVar.varData.theStack->first == NULL) {
- return fatal(ERROR_INDEX_EMPTY);
- } else {
- int ii;
- if (!getValueType(ii, SVT_INT, fun->reg))
- return false;
- Variable *grab =
- (fun->stack->thisVar.varType == SVT_FASTARRAY) ?
- fastArrayGetByIndex(
- fun->stack->thisVar.varData.fastArray,
- ii) :
- stackGetByIndex(
- fun->stack->thisVar.varData.theStack->first,
- ii);
-
- trimStack(fun->stack);
-
- if (!grab) {
- setVariable(fun->reg, SVT_NULL, 0);
- } else {
- int kk;
- switch (com) {
- case SLU_INCREMENT_INDEX:
- if (!getValueType(kk, SVT_INT, *grab))
- return false;
- setVariable(fun->reg, SVT_INT, kk);
- grab->varData.intValue = kk + 1;
- break;
-
- case SLU_DECREMENT_INDEX:
- if (!getValueType(kk, SVT_INT, *grab))
- return false;
- setVariable(fun->reg, SVT_INT, kk);
- grab->varData.intValue = kk - 1;
- break;
-
- default:
- if (!copyVariable(*grab, fun->reg))
- return false;
- }
- }
- }
- break;
-
- default:
- return fatal(ERROR_INDEX_NONSTACK);
- }
- break;
-
- case SLU_INDEXSET:
- switch (fun->stack->thisVar.varType) {
- case SVT_STACK:
- if (fun->stack->thisVar.varData.theStack->first == NULL) {
- return fatal(ERROR_INDEX_EMPTY);
- } else {
- int ii;
- if (!getValueType(ii, SVT_INT, fun->reg))
- return false;
- if (!stackSetByIndex(
- fun->stack->thisVar.varData.theStack->first, ii,
- fun->stack->next->thisVar)) {
- return false;
- }
- trimStack(fun->stack);
- trimStack(fun->stack);
- }
- break;
-
- case SVT_FASTARRAY: {
- int ii;
- if (!getValueType(ii, SVT_INT, fun->reg))
- return false;
- Variable *v = fastArrayGetByIndex(
- fun->stack->thisVar.varData.fastArray, ii);
- if (v == NULL)
- return fatal("Not within bounds of fast array.");
- if (!copyVariable(fun->stack->next->thisVar, *v))
- return false;
- trimStack(fun->stack);
- trimStack(fun->stack);
- }
- break;
-
- default:
- return fatal(ERROR_INDEX_NONSTACK);
- }
- break;
-
- // What can we do with the register? Well, we can copy it into a local
- // variable, a global or onto the stack...
-
- case SLU_INCREMENT_LOCAL: {
- int ii;
- if (!getValueType(ii, SVT_INT, fun->localVars[param]))
- return false;
- setVariable(fun->reg, SVT_INT, ii);
- setVariable(fun->localVars[param], SVT_INT, ii + 1);
- }
- break;
-
- case SLU_INCREMENT_GLOBAL: {
- int ii;
- if (!getValueType(ii, SVT_INT, globalVars[param]))
- return false;
- setVariable(fun->reg, SVT_INT, ii);
- setVariable(globalVars[param], SVT_INT, ii + 1);
- }
- break;
-
- case SLU_DECREMENT_LOCAL: {
- int ii;
- if (!getValueType(ii, SVT_INT, fun->localVars[param]))
- return false;
- setVariable(fun->reg, SVT_INT, ii);
- setVariable(fun->localVars[param], SVT_INT, ii - 1);
- }
- break;
-
- case SLU_DECREMENT_GLOBAL: {
- int ii;
- if (!getValueType(ii, SVT_INT, globalVars[param]))
- return false;
- setVariable(fun->reg, SVT_INT, ii);
- setVariable(globalVars[param], SVT_INT, ii - 1);
- }
- break;
-
- case SLU_SET_LOCAL:
- if (!copyVariable(fun->reg, fun->localVars[param]))
- return false;
- break;
-
- case SLU_SET_GLOBAL:
-// newDebug (" Copying TO global variable", param);
-// newDebug (" Global type at the moment", globalVars[param].varType);
- if (!copyVariable(fun->reg, globalVars[param]))
- return false;
-// newDebug (" New type", globalVars[param].varType);
- break;
-
- case SLU_LOAD_GLOBAL:
-// newDebug (" Copying FROM global variable", param);
-// newDebug (" Global type at the moment", globalVars[param].varType);
- if (!copyVariable(globalVars[param], fun->reg))
- return false;
- break;
-
- case SLU_STACK_PUSH:
- if (!addVarToStack(fun->reg, fun->stack))
- return false;
- break;
-
- case SLU_QUICK_PUSH:
- if (!addVarToStackQuick(fun->reg, fun->stack))
- return false;
- break;
-
- case SLU_NOT:
- setVariable(fun->reg, SVT_INT, !getBoolean(fun->reg));
- break;
-
- case SLU_BR_ZERO:
- if (!getBoolean(fun->reg)) {
- advanceNow = false;
- fun->runThisLine = param;
- }
- break;
-
- case SLU_BRANCH:
- advanceNow = false;
- fun->runThisLine = param;
- break;
-
- case SLU_NEGATIVE: {
- int i;
- if (!getValueType(i, SVT_INT, fun->reg))
- return false;
- setVariable(fun->reg, SVT_INT, -i);
- }
- break;
-
- // All these things rely on there being somet' on the stack
-
- case SLU_MULT:
- case SLU_PLUS:
- case SLU_MINUS:
- case SLU_MODULUS:
- case SLU_DIVIDE:
- case SLU_EQUALS:
- case SLU_NOT_EQ:
- case SLU_LESSTHAN:
- case SLU_MORETHAN:
- case SLU_LESS_EQUAL:
- case SLU_MORE_EQUAL:
- if (fun->stack) {
- int firstValue, secondValue;
-
- switch (com) {
- case SLU_PLUS:
- addVariablesInSecond(fun->stack->thisVar, fun->reg);
- trimStack(fun->stack);
- break;
-
- case SLU_EQUALS:
- compareVariablesInSecond(fun->stack->thisVar, fun->reg);
- trimStack(fun->stack);
- break;
-
- case SLU_NOT_EQ:
- compareVariablesInSecond(fun->stack->thisVar, fun->reg);
- trimStack(fun->stack);
- fun->reg.varData.intValue = !fun->reg.varData.intValue;
- break;
-
- default:
- if (!getValueType(firstValue, SVT_INT, fun->stack->thisVar))
- return false;
- if (!getValueType(secondValue, SVT_INT, fun->reg))
- return false;
- trimStack(fun->stack);
-
- switch (com) {
- case SLU_MULT:
- setVariable(fun->reg, SVT_INT,
- firstValue * secondValue);
- break;
-
- case SLU_MINUS:
- setVariable(fun->reg, SVT_INT,
- firstValue - secondValue);
- break;
-
- case SLU_MODULUS:
- setVariable(fun->reg, SVT_INT,
- firstValue % secondValue);
- break;
-
- case SLU_DIVIDE:
- setVariable(fun->reg, SVT_INT,
- firstValue / secondValue);
- break;
-
- case SLU_LESSTHAN:
- setVariable(fun->reg, SVT_INT,
- firstValue < secondValue);
- break;
-
- case SLU_MORETHAN:
- setVariable(fun->reg, SVT_INT,
- firstValue > secondValue);
- break;
-
- case SLU_LESS_EQUAL:
- setVariable(fun->reg, SVT_INT,
- firstValue <= secondValue);
- break;
-
- case SLU_MORE_EQUAL:
- setVariable(fun->reg, SVT_INT,
- firstValue >= secondValue);
- break;
-
- default:
- break;
- }
- }
- } else {
- return fatal(ERROR_NOSTACK);
- }
- break;
-
- default:
- return fatal(ERROR_UNKNOWN_CODE);
- }
-
- if (advanceNow)
- fun->runThisLine++;
-
- }
- return true;
-}
-
-bool runSludge() {
-
- LoadedFunction *thisFunction = allRunningFunctions;
- LoadedFunction *nextFunction;
-
- while (thisFunction) {
- nextFunction = thisFunction->next;
-
- if (!thisFunction->freezerLevel) {
- if (thisFunction->timeLeft) {
- if (thisFunction->timeLeft < 0) {
- if (!g_sludge->_soundMan->stillPlayingSound(
- g_sludge->_speechMan->getLastSpeechSound())) {
- thisFunction->timeLeft = 0;
- }
- } else if (!--(thisFunction->timeLeft)) {
- }
- } else {
- if (thisFunction->isSpeech) {
- thisFunction->isSpeech = false;
- g_sludge->_speechMan->kill();
- }
- if (!continueFunction(thisFunction))
- return false;
- }
- }
-
- thisFunction = nextFunction;
- }
-
- if (!g_sludge->loadNow.empty()) {
- if (g_sludge->loadNow[0] == ':') {
- saveGame(g_sludge->loadNow.c_str() + 1);
- setVariable(saverFunc->reg, SVT_INT, 1);
- } else {
- if (!loadGame(g_sludge->loadNow))
- return false;
- }
- g_sludge->loadNow.clear();
- }
-
- return true;
-}
-
-void killAllFunctions() {
- while (allRunningFunctions)
- finishFunction(allRunningFunctions);
-}
-
-bool loadFunctionCode(LoadedFunction *newFunc) {
- uint numLines, numLinesRead;
-
- if (!g_sludge->_resMan->openSubSlice(newFunc->originalNumber))
- return false;
-
- debugC(3, kSludgeDebugDataLoad, "Load function code");
-
- Common::SeekableReadStream *readStream = g_sludge->_resMan->getData();
- newFunc->unfreezable = readStream->readByte();
- numLines = readStream->readUint16BE();
- debugC(3, kSludgeDebugDataLoad, "numLines: %i", numLines);
- newFunc->numArgs = readStream->readUint16BE();
- debugC(3, kSludgeDebugDataLoad, "numArgs: %i", newFunc->numArgs);
- newFunc->numLocals = readStream->readUint16BE();
- debugC(3, kSludgeDebugDataLoad, "numLocals: %i", newFunc->numLocals);
- newFunc->compiledLines = new LineOfCode[numLines];
- if (!checkNew(newFunc->compiledLines))
- return false;
-
- for (numLinesRead = 0; numLinesRead < numLines; numLinesRead++) {
- newFunc->compiledLines[numLinesRead].theCommand = (sludgeCommand)readStream->readByte();
- newFunc->compiledLines[numLinesRead].param = readStream->readUint16BE();
- debugC(3, kSludgeDebugDataLoad, "command line %i: %i", numLinesRead,
- newFunc->compiledLines[numLinesRead].theCommand);
- }
- g_sludge->_resMan->finishAccess();
-
- // Now we need to reserve memory for the local variables
- newFunc->localVars = new Variable[newFunc->numLocals];
- if (!checkNew(newFunc->localVars))
- return false;
- for (int a = 0; a < newFunc->numLocals; a++) {
- initVarNew(newFunc->localVars[a]);
- }
-
- return true;
-}
-
-int startNewFunctionNum(uint funcNum, uint numParamsExpected,
- LoadedFunction *calledBy, VariableStack *&vStack, bool returnSommet) {
- LoadedFunction *newFunc = new LoadedFunction;
- checkNew(newFunc);
- newFunc->originalNumber = funcNum;
-
- loadFunctionCode(newFunc);
-
- if (newFunc->numArgs != (int) numParamsExpected)
- return fatal("Wrong number of parameters!");
- if (newFunc->numArgs > newFunc->numLocals)
- return fatal("More arguments than local Variable space!");
-
- // Now, lets copy the parameters from the calling function's stack...
-
- while (numParamsExpected) {
- numParamsExpected--;
- if (vStack == NULL)
- return fatal(
- "Corrupted file!The stack's empty and there were still parameters expected");
- copyVariable(vStack->thisVar, newFunc->localVars[numParamsExpected]);
- trimStack(vStack);
- }
-
- newFunc->cancelMe = false;
- newFunc->timeLeft = 0;
- newFunc->returnSomething = returnSommet;
- newFunc->calledBy = calledBy;
- newFunc->stack = NULL;
- newFunc->freezerLevel = 0;
- newFunc->runThisLine = 0;
- newFunc->isSpeech = 0;
- initVarNew(newFunc->reg);
-
- restartFunction(newFunc);
- return 1;
-}
-
} // End of namespace Sludge
diff --git a/engines/sludge/sludger.h b/engines/sludge/sludger.h
index 2351cb9..8efdfa6 100644
--- a/engines/sludge/sludger.h
+++ b/engines/sludge/sludger.h
@@ -22,12 +22,7 @@
#ifndef SLUDGER_H
#define SLUDGER_H
-#include "common/file.h"
-
#include "sludge/allfiles.h"
-#include "sludge/variable.h"
-#include "sludge/csludge.h"
-#include "sludge/language.h"
namespace Sludge {
@@ -36,51 +31,15 @@ typedef struct _FILETIME {
uint32 dwHighDateTime;
} FILETIME;
-struct Variable;
-struct VariableStack;
-
-struct LineOfCode {
- sludgeCommand theCommand;
- int32 param;
-};
-
-struct LoadedFunction {
- int originalNumber;
- LineOfCode *compiledLines;
- int numLocals, timeLeft, numArgs;
- Variable *localVars;
- VariableStack *stack;
- Variable reg;
- uint runThisLine;
- LoadedFunction *calledBy;
- LoadedFunction *next;
- bool returnSomething, isSpeech, unfreezable, cancelMe;
- byte freezerLevel;
-};
-
bool initSludge(const Common::String &);
-bool runSludge();
-
void initSludge();
void killSludge();
void displayBase();
void sludgeDisplay();
-int startNewFunctionNum(uint, uint, LoadedFunction *, VariableStack*&, bool = true);
-void restartFunction(LoadedFunction *fun);
-bool loadFunctionCode(LoadedFunction *newFunc);
-void killAllFunctions();
-void finishFunction(LoadedFunction *fun);
-void abortFunction(LoadedFunction *fun);
Common::File *openAndVerify(const Common::String &filename, char extra1, char extra2, const char *er, int &fileVersion);
-void freezeSubs();
-void unfreezeSubs();
-void completeTimers();
-void killSpeechTimers();
-int cancelAFunction(int funcNum, LoadedFunction *myself, bool &killedMyself);
-
} // End of namespace Sludge
#endif
Commit: 0548765479b69f2aaaf153e6370ed262a80c1d2d
https://github.com/scummvm/scummvm/commit/0548765479b69f2aaaf153e6370ed262a80c1d2d
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:37:10+02:00
Commit Message:
SLUDGE: Objectify FatalMsgManager
Changed paths:
engines/sludge/newfatal.cpp
engines/sludge/newfatal.h
engines/sludge/sludge.cpp
engines/sludge/sludge.h
diff --git a/engines/sludge/newfatal.cpp b/engines/sludge/newfatal.cpp
index edd4a88..820b497 100644
--- a/engines/sludge/newfatal.cpp
+++ b/engines/sludge/newfatal.cpp
@@ -24,74 +24,88 @@
#include "sludge/allfiles.h"
#include "sludge/errors.h"
+#include "sludge/newfatal.h"
#include "sludge/sludge.h"
#include "sludge/sound.h"
#include "sludge/version.h"
-namespace Sludge {
+namespace Common {
+DECLARE_SINGLETON(Sludge::FatalMsgManager);
+}
-const char emergencyMemoryMessage[] = "Out of memory displaying error message!";
+namespace Sludge {
extern int numResourceNames /* = 0*/;
extern Common::String *allResourceNames /*= ""*/;
-int resourceForFatal = -1;
+int inFatal(const Common::String &str) {
+ g_sludge->_soundMan->killSoundStuff();
+ error("%s", str.c_str());
+ return true;
+}
-const Common::String resourceNameFromNum(int i) {
- if (i == -1)
- return NULL;
- if (numResourceNames == 0)
- return "RESOURCE";
- if (i < numResourceNames)
- return allResourceNames[i];
- return "Unknown resource";
+FatalMsgManager::FatalMsgManager() {
+ reset();
}
-bool hasFatal() {
- if (!g_sludge->fatalMessage.empty())
- return true;
- return false;
+FatalMsgManager::~FatalMsgManager() {
}
-int inFatal(const Common::String &str) {
- g_sludge->_soundMan->killSoundStuff();
- error("%s", str.c_str());
- return true;
+void FatalMsgManager::reset() {
+ _fatalMessage = "";
+ _fatalInfo = "Initialisation error! Something went wrong before we even got started!";
+ _resourceForFatal = -1;
}
-int checkNew(const void *mem) {
- if (mem == NULL) {
- inFatal(ERROR_OUT_OF_MEMORY);
- return 0;
- }
- return 1;
+bool FatalMsgManager::hasFatal() {
+ if (!_fatalMessage.empty())
+ return true;
+ return false;
}
-void setFatalInfo(const Common::String &userFunc, const Common::String &BIF) {
- g_sludge->fatalInfo = "Currently in this sub: " + userFunc + "\nCalling: " + BIF;
- debugC(0, kSludgeDebugFatal, "%s", g_sludge->fatalInfo.c_str());
+void FatalMsgManager::setFatalInfo(const Common::String &userFunc, const Common::String &BIF) {
+ _fatalInfo = "Currently in this sub: " + userFunc + "\nCalling: " + BIF;
+ debugC(0, kSludgeDebugFatal, "%s", _fatalInfo.c_str());
}
-void setResourceForFatal(int n) {
- resourceForFatal = n;
+void FatalMsgManager::setResourceForFatal(int n) {
+ _resourceForFatal = n;
}
-int fatal(const Common::String &str1) {
- if (numResourceNames && resourceForFatal != -1) {
- Common::String r = resourceNameFromNum(resourceForFatal);
- Common::String newStr = g_sludge->fatalInfo + "\nResource: " + r + "\n\n" + str1;
+int FatalMsgManager::fatal(const Common::String &str1) {
+ if (numResourceNames && _resourceForFatal != -1) {
+ Common::String r = resourceNameFromNum(_resourceForFatal);
+ Common::String newStr = _fatalInfo + "\nResource: " + r + "\n\n" + str1;
inFatal(newStr);
} else {
- Common::String newStr = g_sludge->fatalInfo + "\n\n" + str1;
+ Common::String newStr = _fatalInfo + "\n\n" + str1;
inFatal(newStr);
}
return 0;
}
+int checkNew(const void *mem) {
+ if (mem == NULL) {
+ inFatal(ERROR_OUT_OF_MEMORY);
+ return 0;
+ }
+ return 1;
+}
+
int fatal(const Common::String &str1, const Common::String &str2) {
Common::String newStr = str1 + " " + str2;
fatal(newStr);
return 0;
}
+const Common::String resourceNameFromNum(int i) {
+ if (i == -1)
+ return NULL;
+ if (numResourceNames == 0)
+ return "RESOURCE";
+ if (i < numResourceNames)
+ return allResourceNames[i];
+ return "Unknown resource";
+}
+
} // End of namespace Sludge
diff --git a/engines/sludge/newfatal.h b/engines/sludge/newfatal.h
index fc91110..08a26db 100644
--- a/engines/sludge/newfatal.h
+++ b/engines/sludge/newfatal.h
@@ -23,18 +23,49 @@
#define SLUDGE_NEWFATAL_H
#include "common/str.h"
+#include "common/singleton.h"
#include "sludge/errors.h"
namespace Sludge {
-bool hasFatal();
+class FatalMsgManager : public Common::Singleton<Sludge::FatalMsgManager>{
+public:
+ FatalMsgManager();
+ ~FatalMsgManager();
+
+ void reset();
+
+ bool hasFatal();
+ int fatal(const Common::String &str);
+ void setFatalInfo(const Common::String &userFunc, const Common::String &BIF);
+ void setResourceForFatal(int n);
+
+private:
+ Common::String _fatalMessage;
+ Common::String _fatalInfo;
+
+ int _resourceForFatal;
+};
+
+inline bool hasFatal() {
+ return FatalMsgManager::instance().hasFatal();
+}
+
+inline int fatal(const Common::String &str) {
+ return FatalMsgManager::instance().fatal(str);
+}
+
+inline void setFatalInfo(const Common::String &userFunc, const Common::String &BIF) {
+ FatalMsgManager::instance().setFatalInfo(userFunc, BIF);
+}
+
+inline void setResourceForFatal(int n) {
+ FatalMsgManager::instance().setResourceForFatal(n);
+}
-int fatal(const Common::String &str);
-int fatal(const Common::String &str1, const Common::String &str2);
int checkNew(const void *mem);
-void setFatalInfo(const Common::String &userFunc, const Common::String &BIF);
-void setResourceForFatal(int n);
+int fatal(const Common::String &str1, const Common::String &str2);
const Common::String resourceNameFromNum(int i);
} // End of namespace Sludge
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index a864a61..821539d 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -30,12 +30,13 @@
#include "sludge/fonttext.h"
#include "sludge/floor.h"
#include "sludge/graphics.h"
+#include "sludge/main_loop.h"
+#include "sludge/newfatal.h"
#include "sludge/people.h"
#include "sludge/region.h"
#include "sludge/sludge.h"
#include "sludge/sound.h"
#include "sludge/speech.h"
-#include "sludge/main_loop.h"
namespace Sludge {
@@ -71,11 +72,9 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
launchNext = "";
loadNow = "";
gamePath = "";
- bundleFolder = "";
- fatalMessage = "";
- fatalInfo = "Initialisation error! Something went wrong before we even got started!";
// Init managers
+ _fatalMan = new FatalMsgManager();
_peopleMan = new PeopleManager(this);
_resMan = new ResourceManager();
_languageMan = new LanguageManager();
@@ -134,6 +133,8 @@ SludgeEngine::~SludgeEngine() {
_peopleMan = nullptr;
delete _floorMan;
_floorMan = nullptr;
+ delete _fatalMan;
+ _fatalMan = nullptr;
}
Common::Error SludgeEngine::run() {
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index 6a0848a..692af64 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -40,6 +40,7 @@ extern SludgeEngine *g_sludge;
class CursorManager;
class EventManager;
+class FatalMsgManager;
class FloorManager;
class GraphicsManager;
class PeopleManager;
@@ -74,9 +75,6 @@ public:
Common::String launchNext;
Common::String loadNow;
Common::String gamePath;
- Common::String bundleFolder;
- Common::String fatalMessage;
- Common::String fatalInfo;
// timer
Timer _timer;
@@ -94,6 +92,7 @@ public:
RegionManager *_regionMan;
PeopleManager *_peopleMan;
FloorManager *_floorMan;
+ FatalMsgManager *_fatalMan;
SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc);
virtual ~SludgeEngine();
Commit: 1ec5ef3e4df9ee3606bb4b3092fcf0d6f515563e
https://github.com/scummvm/scummvm/commit/1ec5ef3e4df9ee3606bb4b3092fcf0d6f515563e
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:37:10+02:00
Commit Message:
SLUDGE: Move resource names to ResourceManager
Changed paths:
engines/sludge/fileset.cpp
engines/sludge/fileset.h
engines/sludge/newfatal.cpp
engines/sludge/newfatal.h
engines/sludge/sludger.cpp
engines/sludge/variable.cpp
diff --git a/engines/sludge/fileset.cpp b/engines/sludge/fileset.cpp
index fcdec32..c9c3e7a 100644
--- a/engines/sludge/fileset.cpp
+++ b/engines/sludge/fileset.cpp
@@ -48,12 +48,14 @@ void ResourceManager::init() {
_startOfSubIndex = 0;
_startOfObjectIndex = 0;
_startIndex = 0;
+ _allResourceNames.clear();
}
void ResourceManager::kill() {
if (_bigDataFile) {
delete _bigDataFile;
_bigDataFile = nullptr;
}
+ _allResourceNames.clear();
}
bool ResourceManager::openSubSlice(int num) {
@@ -216,6 +218,31 @@ void ResourceManager::finishAccess() {
_sliceBusy = false;
}
+void ResourceManager::readResourceNames(Common::SeekableReadStream *readStream) {
+ int numResourceNames = readStream->readUint16BE();
+ debugC(2, kSludgeDebugDataLoad, "numResourceNames %i", numResourceNames);
+ _allResourceNames.reserve(numResourceNames);
+
+ for (int fn = 0; fn < numResourceNames; fn++) {
+ _allResourceNames[fn].clear();
+ _allResourceNames[fn] = readString(readStream);
+ debugC(2, kSludgeDebugDataLoad, "Resource %i: %s", fn, _allResourceNames[fn].c_str());
+ }
+}
+
+const Common::String ResourceManager::resourceNameFromNum(int i) {
+ if (i == -1)
+ return "";
+
+ if (_allResourceNames.empty())
+ return "RESOURCE";
+
+ if (i < (int)_allResourceNames.size())
+ return _allResourceNames[i];
+
+ return "Unknown resource";
+}
+
void ResourceManager::setData(Common::File *fp) {
_bigDataFile = fp;
_startIndex = fp->pos();
diff --git a/engines/sludge/fileset.h b/engines/sludge/fileset.h
index 83200ce..fb6a696 100644
--- a/engines/sludge/fileset.h
+++ b/engines/sludge/fileset.h
@@ -44,15 +44,23 @@ public:
bool openObjectSlice(int num);
Common::String getNumberedString(int value);
+ // Access control flag
bool startAccess();
void finishAccess();
+ // Resource names
+ void readResourceNames(Common::SeekableReadStream *readStream);
+ const Common::String resourceNameFromNum(int i);
+ bool hasResourceNames() { return !_allResourceNames.empty(); }
+
private:
bool _sliceBusy;
Common::File *_bigDataFile;
uint32 _startOfDataIndex, _startOfTextIndex, _startOfSubIndex, _startOfObjectIndex;
int32 _startIndex;
+ Common::Array<Common::String> _allResourceNames;
+
private:
static uint32 _cp1250ToUTF32[128];
Common::String convertString(const Common::String &s);
diff --git a/engines/sludge/newfatal.cpp b/engines/sludge/newfatal.cpp
index 820b497..a5069ae 100644
--- a/engines/sludge/newfatal.cpp
+++ b/engines/sludge/newfatal.cpp
@@ -24,6 +24,7 @@
#include "sludge/allfiles.h"
#include "sludge/errors.h"
+#include "sludge/fileset.h"
#include "sludge/newfatal.h"
#include "sludge/sludge.h"
#include "sludge/sound.h"
@@ -35,9 +36,6 @@ DECLARE_SINGLETON(Sludge::FatalMsgManager);
namespace Sludge {
-extern int numResourceNames /* = 0*/;
-extern Common::String *allResourceNames /*= ""*/;
-
int inFatal(const Common::String &str) {
g_sludge->_soundMan->killSoundStuff();
error("%s", str.c_str());
@@ -73,8 +71,9 @@ void FatalMsgManager::setResourceForFatal(int n) {
}
int FatalMsgManager::fatal(const Common::String &str1) {
- if (numResourceNames && _resourceForFatal != -1) {
- Common::String r = resourceNameFromNum(_resourceForFatal);
+ ResourceManager *resMan = g_sludge->_resMan;
+ if (resMan->hasResourceNames() && _resourceForFatal != -1) {
+ Common::String r = resMan->resourceNameFromNum(_resourceForFatal);
Common::String newStr = _fatalInfo + "\nResource: " + r + "\n\n" + str1;
inFatal(newStr);
} else {
@@ -98,14 +97,4 @@ int fatal(const Common::String &str1, const Common::String &str2) {
return 0;
}
-const Common::String resourceNameFromNum(int i) {
- if (i == -1)
- return NULL;
- if (numResourceNames == 0)
- return "RESOURCE";
- if (i < numResourceNames)
- return allResourceNames[i];
- return "Unknown resource";
-}
-
} // End of namespace Sludge
diff --git a/engines/sludge/newfatal.h b/engines/sludge/newfatal.h
index 08a26db..81ca4b7 100644
--- a/engines/sludge/newfatal.h
+++ b/engines/sludge/newfatal.h
@@ -66,7 +66,6 @@ inline void setResourceForFatal(int n) {
int checkNew(const void *mem);
int fatal(const Common::String &str1, const Common::String &str2);
-const Common::String resourceNameFromNum(int i);
} // End of namespace Sludge
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index cab0342..f297ff1 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -60,8 +60,6 @@ extern Common::String *allBIFNames;
extern int numUserFunc;
extern Common::String *allUserFunc;
-int numResourceNames = 0;
-Common::String *allResourceNames = NULL;
int selectedLanguage = 0;
int gameVersion;
@@ -206,19 +204,9 @@ bool initSludge(const Common::String &filename) {
allUserFunc[fn].clear();
allUserFunc[fn] = readString(fp);
}
+
if (gameVersion >= VERSION(1, 3)) {
- numResourceNames = fp->readUint16BE();
- debugC(2, kSludgeDebugDataLoad, "numResourceNames %i",
- numResourceNames);
- allResourceNames = new Common::String[numResourceNames];
- if (!checkNew(allResourceNames))
- return false;
-
- for (int fn = 0; fn < numResourceNames; fn++) {
- allResourceNames[fn].clear();
- allResourceNames[fn] = readString(fp);
- debugC(2, kSludgeDebugDataLoad, "Resource %i: %s", fn, allResourceNames[fn].c_str());
- }
+ g_sludge->_resMan->readResourceNames(fp);
}
}
diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp
index 5537377..8ed2297 100644
--- a/engines/sludge/variable.cpp
+++ b/engines/sludge/variable.cpp
@@ -303,7 +303,7 @@ Common::String getTextFromAnyVar(const Variable &from) {
}
case SVT_FILE: {
- return resourceNameFromNum(from.varData.intValue);
+ return g_sludge->_resMan->resourceNameFromNum(from.varData.intValue);
}
case SVT_OBJTYPE: {
Commit: dc320b86bc0da7026bfd650be6a8450684b54fa9
https://github.com/scummvm/scummvm/commit/dc320b86bc0da7026bfd650be6a8450684b54fa9
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:37:10+02:00
Commit Message:
SLUDGE: Create constructor of Variable instead of initVarNew
Changed paths:
engines/sludge/event.cpp
engines/sludge/function.cpp
engines/sludge/sludger.cpp
engines/sludge/variable.cpp
engines/sludge/variable.h
diff --git a/engines/sludge/event.cpp b/engines/sludge/event.cpp
index d6afe2f..acccd7f 100644
--- a/engines/sludge/event.cpp
+++ b/engines/sludge/event.cpp
@@ -182,7 +182,6 @@ bool EventManager::handleInput() {
if (!checkNew(tempStack))
return false;
- initVarNew(tempStack->thisVar);
ScreenRegion *overRegion = _vm->_regionMan->getOverRegion();
if (overRegion) {
setVariable(tempStack->thisVar, SVT_OBJTYPE, overRegion->thisType->objectNum);
@@ -321,7 +320,6 @@ bool EventManager::handleInput() {
VariableStack *tempStack = new VariableStack;
if (!checkNew(tempStack))
return false;
- initVarNew(tempStack->thisVar);
makeTextVar(tempStack->thisVar, tempString);
tempStack->next = nullptr;
if (!startNewFunctionNum(_currentEvents->func[kSpace], 1, nullptr, tempStack))
diff --git a/engines/sludge/function.cpp b/engines/sludge/function.cpp
index 8aa69f0..98f7bf7 100644
--- a/engines/sludge/function.cpp
+++ b/engines/sludge/function.cpp
@@ -661,9 +661,6 @@ bool loadFunctionCode(LoadedFunction *newFunc) {
newFunc->localVars = new Variable[newFunc->numLocals];
if (!checkNew(newFunc->localVars))
return false;
- for (int a = 0; a < newFunc->numLocals; a++) {
- initVarNew(newFunc->localVars[a]);
- }
return true;
}
@@ -700,7 +697,6 @@ int startNewFunctionNum(uint funcNum, uint numParamsExpected,
newFunc->freezerLevel = 0;
newFunc->runThisLine = 0;
newFunc->isSpeech = 0;
- initVarNew(newFunc->reg);
restartFunction(newFunc);
return 1;
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index f297ff1..f9dedf2 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -177,7 +177,6 @@ void killSludge() {
bool initSludge(const Common::String &filename) {
initSludge();
- int a = 0;
Common::File *fp = openAndVerify(filename, 'G', 'E', ERROR_BAD_HEADER, gameVersion);
if (!fp)
return false;
@@ -276,8 +275,6 @@ bool initSludge(const Common::String &filename) {
globalVars = new Variable[numGlobals];
if (!checkNew(globalVars))
return false;
- for (a = 0; a < numGlobals; a++)
- initVarNew(globalVars[a]);
// Get language selected by user
g_sludge->_resMan->setData(fp);
diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp
index 8ed2297..a663599 100644
--- a/engines/sludge/variable.cpp
+++ b/engines/sludge/variable.cpp
@@ -408,9 +408,6 @@ bool makeFastArraySize(Variable &to, int size) {
to.varData.fastArray->fastVariables = new Variable[size];
if (!checkNew(to.varData.fastArray->fastVariables))
return false;
- for (int i = 0; i < size; i++) {
- initVarNew(to.varData.fastArray->fastVariables[i]);
- }
to.varData.fastArray->size = size;
to.varData.fastArray->timesUsed = 1;
return true;
diff --git a/engines/sludge/variable.h b/engines/sludge/variable.h
index a3cc57d..27bf71a 100644
--- a/engines/sludge/variable.h
+++ b/engines/sludge/variable.h
@@ -68,6 +68,11 @@ union VariableData {
struct Variable {
VariableType varType;
VariableData varData;
+
+ Variable() {
+ varType = SVT_NULL;
+ varData.intValue = 0;
+ }
};
struct VariableStack {
@@ -75,10 +80,6 @@ struct VariableStack {
VariableStack *next;
};
-// Initialisation
-
-#define initVarNew(thisVar) thisVar.varType = SVT_NULL
-
// Setting variables
void setVariable(Variable &thisVar, VariableType vT, int value);
@@ -94,7 +95,6 @@ char *createCString(const Common::String &s);
// Misc.
void unlinkVar(Variable &thisVar);
-Common::String getNumberedString(int value);
Common::String getTextFromAnyVar(const Variable &from);
struct Persona *getCostumeFromVar(Variable &thisVar);
struct PersonaAnimation *getAnimationFromVar(Variable &thisVar);
Commit: 87e58a9b7e26986c8d396d836a97ad01a5f74c52
https://github.com/scummvm/scummvm/commit/87e58a9b7e26986c8d396d836a97ad01a5f74c52
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:37:10+02:00
Commit Message:
SLUDGE: Split runSludge() to runAllFunctions() and handleSaveLoad()
Changed paths:
engines/sludge/function.cpp
engines/sludge/function.h
engines/sludge/loadsave.cpp
engines/sludge/loadsave.h
engines/sludge/main_loop.cpp
diff --git a/engines/sludge/function.cpp b/engines/sludge/function.cpp
index 98f7bf7..6905c38 100644
--- a/engines/sludge/function.cpp
+++ b/engines/sludge/function.cpp
@@ -702,7 +702,7 @@ int startNewFunctionNum(uint funcNum, uint numParamsExpected,
return 1;
}
-bool runSludge() {
+bool runAllFunctions() {
LoadedFunction *thisFunction = allRunningFunctions;
LoadedFunction *nextFunction;
@@ -732,17 +732,6 @@ bool runSludge() {
thisFunction = nextFunction;
}
- if (!g_sludge->loadNow.empty()) {
- if (g_sludge->loadNow[0] == ':') {
- saveGame(g_sludge->loadNow.c_str() + 1);
- setVariable(saverFunc->reg, SVT_INT, 1);
- } else {
- if (!loadGame(g_sludge->loadNow))
- return false;
- }
- g_sludge->loadNow.clear();
- }
-
return true;
}
diff --git a/engines/sludge/function.h b/engines/sludge/function.h
index ead2adf..6980d6b 100644
--- a/engines/sludge/function.h
+++ b/engines/sludge/function.h
@@ -50,8 +50,7 @@ struct LoadedFunction {
byte freezerLevel;
};
-bool runSludge();
-
+bool runAllFunctions();
int startNewFunctionNum(uint, uint, LoadedFunction *, VariableStack*&, bool = true);
void restartFunction(LoadedFunction *fun);
bool loadFunctionCode(LoadedFunction *newFunc);
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index 2d29645..923c171 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -56,6 +56,7 @@ namespace Sludge {
// From elsewhere
//----------------------------------------------------------------------
+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
@@ -336,6 +337,20 @@ LoadedFunction *loadFunction(Common::SeekableReadStream *stream) {
// Save everything
//----------------------------------------------------------------------
+bool handleSaveLoad() {
+ if (!g_sludge->loadNow.empty()) {
+ if (g_sludge->loadNow[0] == ':') {
+ saveGame(g_sludge->loadNow.c_str() + 1);
+ setVariable(saverFunc->reg, SVT_INT, 1);
+ } else {
+ if (!loadGame(g_sludge->loadNow))
+ return false;
+ }
+ g_sludge->loadNow.clear();
+ }
+ return true;
+}
+
bool saveGame(const Common::String &fname) {
Common::OutSaveFile *fp = g_system->getSavefileManager()->openForSaving(fname);
diff --git a/engines/sludge/loadsave.h b/engines/sludge/loadsave.h
index 269fadb..54e0577 100644
--- a/engines/sludge/loadsave.h
+++ b/engines/sludge/loadsave.h
@@ -28,6 +28,8 @@ struct LoadedFunction;
struct Variable;
struct VariableStack;
+bool handleSaveLoad();
+
bool saveGame(const Common::String &fname);
bool loadGame(const Common::String &fname);
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index ee0bae1..8f6e1f9 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -31,6 +31,7 @@
#include "sludge/function.h"
#include "sludge/graphics.h"
#include "sludge/language.h"
+#include "sludge/loadsave.h"
#include "sludge/newfatal.h"
#include "sludge/objtypes.h"
#include "sludge/people.h"
@@ -63,7 +64,8 @@ int main_loop(Common::String filename) {
g_sludge->_evtMan->checkInput();
g_sludge->_peopleMan->walkAllPeople();
if (g_sludge->_evtMan->handleInput()) {
- runSludge();
+ runAllFunctions();
+ handleSaveLoad();
}
sludgeDisplay();
g_sludge->_soundMan->handleSoundLists();
Commit: 3e88827c4cea00dcc9f0fe90fc4a173c2b821b41
https://github.com/scummvm/scummvm/commit/3e88827c4cea00dcc9f0fe90fc4a173c2b821b41
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-29T22:59:52+02:00
Commit Message:
SLUDGE: Move function/variable load/save functions to related files
Changed paths:
engines/sludge/function.cpp
engines/sludge/function.h
engines/sludge/loadsave.cpp
engines/sludge/loadsave.h
engines/sludge/variable.cpp
engines/sludge/variable.h
diff --git a/engines/sludge/function.cpp b/engines/sludge/function.cpp
index 6905c38..0a7a344 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 6980d6b..005760a 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 923c171..4a78b83 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -58,282 +58,12 @@ 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 54e0577..4077950 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 a663599..35e1036 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 27bf71a..8f0d394 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
More information about the Scummvm-git-logs
mailing list