diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index aa0a0dea14c..ba3e8aef6e8 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -218,7 +218,7 @@ int _reset_graphics_input(EngineState *s) { s->priority_first = 42; // Priority zone 0 ends here - if (s->_kernel->usesOldGfxFunctions()) + if (s->usesOldGfxFunctions()) s->priority_last = 200; else s->priority_last = 190; diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 436abd66d47..81a40b51e16 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -354,9 +354,8 @@ SciKernelFunction kfunct_mappers[] = { Kernel::Kernel(ResourceManager *resMan) : _resMan(resMan) { loadSelectorNames(); - detectSciFeatures(); - mapSelectors(); // Map a few special selectors for later use + loadKernelNames(); mapFunctions(); // Map the kernel functions } @@ -384,30 +383,6 @@ const Common::String &Kernel::getKernelName(uint number) const { return _kernelNames[number]; } -void Kernel::detectSciFeatures() { - SciVersion version = getSciVersion(); - - features = 0; - - // Initialize features based on SCI version - - // Script header and graphics functions - if (version == SCI_VERSION_0_EARLY) { - features |= kFeatureOldScriptHeader | kFeatureOldGfxFunctions; - } else if (version == SCI_VERSION_0_LATE) { - if (_selectorCache.motionCue == -1) - features |= kFeatureOldGfxFunctions; - } - - printf("Kernel auto-detected features:\n"); - - printf("Graphics functions: "); - if (features & kFeatureOldGfxFunctions) - printf("old\n"); - else - printf("new\n"); -} - int Kernel::findSelector(const char *selectorName) const { for (uint pos = 0; pos < _selectorNames.size(); ++pos) { if (_selectorNames[pos] == selectorName) diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index cd2bc97b6ab..e82017e7a3e 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -54,8 +54,7 @@ struct KernelFuncWithSignature { }; enum AutoDetectedFeatures { - kFeatureOldScriptHeader = 1 << 0, - kFeatureOldGfxFunctions = 1 << 1 + kFeatureOldScriptHeader = 1 << 0 }; class Kernel { @@ -79,15 +78,6 @@ public: */ int findSelector(const char *selectorName) const; - /** - * Applies to all versions before 0.000.502 - * Old SCI versions used to interpret the third DrawPic() parameter inversely, - * with the opposite default value (obviously). - * Also, they used 15 priority zones from 42 to 200 instead of 14 priority - * zones from 42 to 190. - */ - bool usesOldGfxFunctions() const { return (features & kFeatureOldGfxFunctions); } - // Script dissection/dumping functions void dissectScript(int scriptNumber, Vocabulary *vocab); void dumpScriptObject(char *data, int seeker, int objsize); @@ -141,11 +131,6 @@ private: */ void mapSelectors(); - /** - * Detects SCI features based on the existence of certain selectors - */ - void detectSciFeatures(); - /** * Maps kernel functions */ diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index c764e09b686..143cf913cba 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -149,7 +149,7 @@ int _find_view_priority(EngineState *s, int y) { return j; return 14; // Maximum } else { - if (!s->_kernel->usesOldGfxFunctions()) + if (!s->usesOldGfxFunctions()) return SCI0_VIEW_PRIORITY_14_ZONES(y); else return SCI0_VIEW_PRIORITY(y) == 15 ? 14 : SCI0_VIEW_PRIORITY(y); @@ -157,7 +157,7 @@ int _find_view_priority(EngineState *s, int y) { } int _find_priority_band(EngineState *s, int nr) { - if (!s->_kernel->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { + if (!s->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { if (nr == 15) return 0xffff; else { @@ -166,7 +166,7 @@ int _find_priority_band(EngineState *s, int nr) { return 0; } - if (s->_kernel->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { + if (s->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { warning("Attempt to get priority band %d", nr); return 0; } @@ -176,7 +176,7 @@ int _find_priority_band(EngineState *s, int nr) { else { int retval; - if (!s->_kernel->usesOldGfxFunctions()) + if (!s->usesOldGfxFunctions()) retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); else retval = SCI0_PRIORITY_BAND_FIRST(nr); @@ -922,9 +922,8 @@ reg_t kDrawPic(EngineState *s, int argc, reg_t *argv) { if (argc >= 3) { if (!argv[2].isNull()) addToFlag = true; - // FIXME: usesOldGfxFunctions() seems to be broken, cause sq3 has it set, but uses bit 0 correctly - if (!s->_kernel->usesOldGfxFunctions()) - addToFlag = !addToFlag; // later engines set the bit, but dont want to add to picture + if (!s->usesOldGfxFunctions()) + addToFlag = !addToFlag; } if (argc >= 4) EGApaletteNo = argv[3].toUint16(); diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 7a4883e15ca..4c1786c7d99 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -239,7 +239,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(printLang); FIND_SELECTOR(subtitleLang); FIND_SELECTOR(parseLang); - FIND_SELECTOR(motionCue); + FIND_SELECTOR(overlay); FIND_SELECTOR(setCursor); FIND_SELECTOR(topString); } diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index b686ff1aabd..097be3bb792 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -111,6 +111,7 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, _setCursorType = SCI_VERSION_AUTODETECT; _doSoundType = SCI_VERSION_AUTODETECT; _lofsType = SCI_VERSION_AUTODETECT; + _gfxFunctionsType = SCI_VERSION_AUTODETECT; } EngineState::~EngineState() { @@ -450,4 +451,49 @@ SciVersion EngineState::detectLofsType() { return _lofsType; } +SciVersion EngineState::detectGfxFunctionsType() { + if (_gfxFunctionsType == SCI_VERSION_AUTODETECT) { + // This detection only works (and is only needed) for SCI0 games + if (getSciVersion() >= SCI_VERSION_01) { + _gfxFunctionsType = SCI_VERSION_0_LATE; + return _gfxFunctionsType; + } + + if (getSciVersion() > SCI_VERSION_0_EARLY) { + if (_kernel->findSelector("shiftParser") != -1) { + // The shiftParser selector was introduced just a bit after the + // changes to the graphics functions, so if it exists, the game is + // definitely using newer graphics functions + _gfxFunctionsType = SCI_VERSION_0_LATE; + } else { + // No shiftparser selector, check if the game is using an overlay + if (_kernel->_selectorCache.overlay == -1) { + // No overlay selector found, therefore the game is definitely + // using old graphics functions + _gfxFunctionsType = SCI_VERSION_0_EARLY; + } else { + // An in-between case: The game does not have a shiftParser + // selector, but it does have an overlay selector. Therefore, + // check it to see how it calls kDisplay to determine the + // graphics functions type used + + // TODO: Finish this! + // For now, we're using the old hack of detecting for the motionCue selector + if (_kernel->findSelector("motionCue") != -1) + _gfxFunctionsType = SCI_VERSION_0_LATE; + else + _gfxFunctionsType = SCI_VERSION_0_EARLY; + } + } + } else { // (getSciVersion() == SCI_VERSION_0_EARLY) + // Old SCI0 games always used old graphics functions + _gfxFunctionsType = SCI_VERSION_0_EARLY; + } + + debugC(1, kDebugLevelVM, "Detected graphics functions type: %s", getSciVersionDesc(_gfxFunctionsType).c_str()); + } + + return _gfxFunctionsType; +} + } // End of namespace Sci diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index a99a417642e..c45df5a2ca3 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -286,6 +286,14 @@ public: */ SciVersion detectLofsType(); + /** + * Autodetects the graphics functions used + * @return Lofs type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE + */ + SciVersion detectGfxFunctionsType(); + + bool usesOldGfxFunctions() { return detectGfxFunctionsType() == SCI_VERSION_0_EARLY; } + /* Debugger data: */ Breakpoint *bp_list; /**< List of breakpoints */ int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */ @@ -309,7 +317,7 @@ public: Common::String getLanguageString(const char *str, kLanguage lang) const; private: - SciVersion _doSoundType, _setCursorType, _lofsType; + SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType; kLanguage charToLanguage(const char c) const; int methodChecksum(reg_t objAddress, Selector sel, int offset, uint size) const; }; diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index 1579ae5656f..09bdec6cace 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -64,8 +64,8 @@ static const char * const sci1Selectors[] = { // Taken from Codename: Iceman (Full Game) static const SelectorRemap sci0SelectorRemap[] = { { "caller", 119 }, { "cue", 121 }, { "owner", 130 }, - { "completed", 159 }, { "motionCue", 162 }, { "cycler", 164 }, - { "moveDone", 170 }, { "distance", 173 }, { "setCursor", 254 }, + { "completed", 159 }, { "cycler", 164 }, { "moveDone", 170 }, + { "distance", 173 }, { "setCursor", 254 }, { "overlay", 302 }, { "points", 316 }, { "flags", 368 }, { 0, 0 } }; diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 530a293081d..e63a09ca161 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -179,7 +179,7 @@ struct SelectorCache { Selector nodePtr; Selector flags; - Selector motionCue; /**< Used to determine if a game is using old gfx functions or not */ + Selector overlay; /**< Used to determine if a game is using old gfx functions or not */ Selector points; /**< Used by AvoidPath() */ diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 4ad63d24f70..aeba088e6c6 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -197,7 +197,7 @@ Common::Error SciEngine::run() { return Common::kUnknownError; } - _gamestate->_gui->init(_kernel->usesOldGfxFunctions()); + _gamestate->_gui->init(_gamestate->usesOldGfxFunctions()); printf("Emulating SCI version %s\n", getSciVersionDesc(getSciVersion()).c_str());