diff options
author | Simei Yin | 2018-05-27 23:23:15 +0200 |
---|---|---|
committer | Simei Yin | 2018-05-29 22:37:10 +0200 |
commit | b6c2dc385a2eb186026266c6eb015920b443cf81 (patch) | |
tree | d4a7fccfcff0d8900d2245cdf57c6d1d4061760f /engines/sludge/sludger.cpp | |
parent | a0c3ef5f034bc5db8ad5a90387c7184bca0083e2 (diff) | |
download | scummvm-rg350-b6c2dc385a2eb186026266c6eb015920b443cf81.tar.gz scummvm-rg350-b6c2dc385a2eb186026266c6eb015920b443cf81.tar.bz2 scummvm-rg350-b6c2dc385a2eb186026266c6eb015920b443cf81.zip |
SLUDGE: Split out function.h/cpp for upcoming refactoring
Diffstat (limited to 'engines/sludge/sludger.cpp')
-rw-r--r-- | engines/sludge/sludger.cpp | 737 |
1 files changed, 12 insertions, 725 deletions
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp index 8bbf76e6ef..cab0342c6d 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 |