diff options
author | Martin Kiewitz | 2010-07-23 14:32:24 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-07-23 14:32:24 +0000 |
commit | 20b1d80d598e6f741e28c9a85d186e463d111816 (patch) | |
tree | 673da2b35f29f460937a0af92900d0c9104e96ba /engines/sci/engine/workarounds.cpp | |
parent | 0bcc3af422754525304203edca34a3e6f44f5cfb (diff) | |
download | scummvm-rg350-20b1d80d598e6f741e28c9a85d186e463d111816.tar.gz scummvm-rg350-20b1d80d598e6f741e28c9a85d186e463d111816.tar.bz2 scummvm-rg350-20b1d80d598e6f741e28c9a85d186e463d111816.zip |
SCI: adding table for kDisplay workarounds
and removing hardcoded checks, adding another workaround for kGraph(drawLine) in island of dr. brain (also gene explanation chart)
Moving trackOriginAndFindWorkaround() into workarounds.cpp
svn-id: r51209
Diffstat (limited to 'engines/sci/engine/workarounds.cpp')
-rw-r--r-- | engines/sci/engine/workarounds.cpp | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 3861ad3228..acc977ce6d 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -23,6 +23,9 @@ * */ +#include "sci/engine/kernel.h" +#include "sci/engine/state.h" +#include "sci/engine/vm.h" #include "sci/engine/workarounds.h" #define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, -1, 0, NULL, NULL, -1, 0, { WORKAROUND_NONE, 0 } } @@ -101,6 +104,13 @@ const SciWorkaroundEntry kAbs_workarounds[] = { }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry kDisplay_workarounds[] = { + { GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object + { GID_SQ4, 391, 391, 0, "doCatalog", "mode", 0x84, 0, { WORKAROUND_IGNORE, 0 } }, // clicking on catalog in roboter sale - a parameter is an object + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kDisposeScript_workarounds[] = { { GID_QFG1, 64, 64, 0, "rm64", "dispose", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when leaving graveyard, parameter 0 is an object SCI_WORKAROUNDENTRY_TERMINATOR @@ -115,7 +125,8 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kGraphDrawLine_workarounds[] = { - { GID_SQ1, 43, 43, 0, "someoneDied", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // happens when ordering beer, gets called with 1 extra parameter + { GID_ISLANDBRAIN, 300, 300, 0, "dudeViewer", "show", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter + { GID_SQ1, 43, 43, 0, "someoneDied", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when ordering beer, gets called with 1 extra parameter SCI_WORKAROUNDENTRY_TERMINATOR }; @@ -172,4 +183,79 @@ const SciWorkaroundEntry kStrCpy_workarounds[] = { SCI_WORKAROUNDENTRY_TERMINATOR }; +SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin) { + EngineState *state = g_sci->getEngineState(); + ExecStack *lastCall = state->xs; + Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment); + int curScriptNr = local_script->getScriptNumber(); + + if (lastCall->debugLocalCallOffset != -1) { + // if lastcall was actually a local call search back for a real call + Common::List<ExecStack>::iterator callIterator = state->_executionStack.end(); + while (callIterator != state->_executionStack.begin()) { + callIterator--; + ExecStack loopCall = *callIterator; + if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) { + lastCall->debugSelector = loopCall.debugSelector; + lastCall->debugExportId = loopCall.debugExportId; + break; + } + } + } + + Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp); + Common::String curMethodName; + const SciGameId gameId = g_sci->getGameId(); + const int curRoomNumber = state->currentRoomNumber(); + + if (lastCall->type == EXEC_STACK_TYPE_CALL) { + if (lastCall->debugSelector != -1) { + curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector); + } else if (lastCall->debugExportId != -1) { + curObjectName = ""; + curMethodName = curMethodName.printf("export %d", lastCall->debugExportId); + } + } + + if (workaroundList) { + // Search if there is a workaround for this one + const SciWorkaroundEntry *workaround; + int16 inheritanceLevel = 0; + Common::String searchObjectName = curObjectName; + reg_t searchObject = lastCall->sendp; + do { + workaround = workaroundList; + while (workaround->objectName) { + if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr + && ((workaround->roomNr == -1) || (workaround->roomNr == curRoomNumber)) + && ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel)) + && (workaround->objectName == searchObjectName) + && workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset + && ((workaround->index == -1) || (workaround->index == index))) { + // Workaround found + return workaround->newValue; + } + workaround++; + } + + // Go back to the parent + inheritanceLevel++; + searchObject = state->_segMan->getObject(searchObject)->getSuperClassSelector(); + if (!searchObject.isNull()) + searchObjectName = state->_segMan->getObjectName(searchObject); + } while (!searchObject.isNull()); // no parent left? + } + + // give caller origin data + trackOrigin->objectName = curObjectName; + trackOrigin->methodName = curMethodName; + trackOrigin->scriptNr = curScriptNr; + trackOrigin->localCallOffset = lastCall->debugLocalCallOffset; + + SciWorkaroundSolution noneFound; + noneFound.type = WORKAROUND_NONE; + noneFound.value = 0; + return noneFound; +} + } // End of namespace Sci |