diff options
author | Filippos Karapetis | 2009-07-07 10:28:05 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-07-07 10:28:05 +0000 |
commit | d55f7e72d0af649c472ccc8bb34a408ead3ae7f4 (patch) | |
tree | 3a3517ff44a979c4e8c8c2e3135c9781457bbf42 | |
parent | e4f6330418d0261c5270d178c39412b8a850c6b7 (diff) | |
download | scummvm-rg350-d55f7e72d0af649c472ccc8bb34a408ead3ae7f4.tar.gz scummvm-rg350-d55f7e72d0af649c472ccc8bb34a408ead3ae7f4.tar.bz2 scummvm-rg350-d55f7e72d0af649c472ccc8bb34a408ead3ae7f4.zip |
Added auto-detection for games with older headers for script blocks, and removed game flag GF_SCI0_OLD
svn-id: r42211
-rw-r--r-- | engines/sci/detection.cpp | 9 | ||||
-rw-r--r-- | engines/sci/engine/game.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/kernel.cpp | 47 | ||||
-rw-r--r-- | engines/sci/engine/kernel.h | 24 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 2 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 10 | ||||
-rw-r--r-- | engines/sci/sci.h | 11 |
12 files changed, 84 insertions, 49 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index af03f1269c..a9dac98572 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -31,7 +31,6 @@ namespace Sci { -#define GF_FOR_SCI0_BEFORE_395 (GF_SCI0_OLD | GF_SCI0_OLDGETTIME) #define GF_FOR_SCI0_BEFORE_629 GF_SCI0_OLDGETTIME // Titles of the games @@ -219,7 +218,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, {"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_395, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -1032,7 +1031,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, {"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_395, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -1049,7 +1048,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, {"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_395, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -1616,7 +1615,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "96033f57accfca903750413fd09193c8", 274953}, {"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_395, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index e35fbf99f8..ea03705fc2 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -257,7 +257,7 @@ static int create_class_table_sci0(EngineState *s) { Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scriptnr), 0); if (script) { - if (s->_flags & GF_SCI0_OLD) + if (s->_kernel->hasOldScriptHeader()) magic_offset = seeker = 2; else magic_offset = seeker = 0; @@ -327,6 +327,9 @@ int script_init_engine(EngineState *s) { s->kernel_opt_flags = 0; + s->_kernel = new Kernel(s->resmgr); + s->_vocabulary = new Vocabulary(s->resmgr); + if (s->_version >= SCI_VERSION_1_1) result = create_class_table_sci11(s); else @@ -367,9 +370,6 @@ int script_init_engine(EngineState *s) { s->_executionStack.clear(); // Start without any execution stack s->execution_stack_base = -1; // No vm is running yet - s->_kernel = new Kernel(s->resmgr, (s->_flags & GF_SCI0_OLD)); - s->_vocabulary = new Vocabulary(s->resmgr); - s->restarting_flags = SCI_GAME_IS_NOT_RESTARTING; s->bp_list = NULL; // No breakpoints defined diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index f869a3a9ea..ddcaf53df9 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -367,10 +367,11 @@ static const char *argtype_description[] = { "Arithmetic" }; -Kernel::Kernel(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr) { +Kernel::Kernel(ResourceManager *resmgr) : _resmgr(resmgr) { memset(&_selectorMap, 0, sizeof(_selectorMap)); // FIXME: Remove this once/if we C++ify selector_map_t - loadSelectorNames(isOldSci0); + detectOldScriptHeader(); // must be called before loadSelectorNames() + loadSelectorNames(); mapSelectors(); // Map a few special selectors for later use loadOpcodes(); loadKernelNames(); @@ -390,6 +391,11 @@ Kernel::~Kernel() { } void Kernel::printAutoDetectedFeatures() { + if (_oldScriptHeader) + printf("Kernel auto-detection: game found to have old headers for script blocks\n"); + else + printf("Kernel auto-detection: game found to have newer headers for script blocks\n"); + if (_oldGfxFunctions) printf("Kernel auto-detection: game found to be using old graphics functions\n"); else @@ -411,15 +417,44 @@ void Kernel::printAutoDetectedFeatures() { printf("Kernel auto-detection: found SCI0 game using a SCI1 kernel table\n"); } -void Kernel::loadSelectorNames(bool isOldSci0) { - int count; +void Kernel::detectOldScriptHeader() { + if (_resmgr->_sciVersion != SCI_VERSION_0) { + _oldScriptHeader = false; + return; + } + + Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); + + if (!r) // No such resource? + error("Kernel: Could not retrieve selector names"); + + int count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off + + _oldScriptHeader = true; + + for (int i = 0; i < count; i++) { + int offset = READ_LE_UINT16(r->data + 2 + i * 2); + int len = READ_LE_UINT16(r->data + offset); + + Common::String tmp((const char *)r->data + offset + 2, len); + + // We determine if the game has old script headers by the existence of the + // "setTarget" selector. The "motionInited" selector can also be used for the + // same purpose + if (tmp == "setTarget") { + _oldScriptHeader = false; + break; + } + } +} +void Kernel::loadSelectorNames() { Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); if (!r) // No such resource? error("Kernel: Could not retrieve selector names"); - count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off + int count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off for (int i = 0; i < count; i++) { int offset = READ_LE_UINT16(r->data + 2 + i * 2); @@ -431,7 +466,7 @@ void Kernel::loadSelectorNames(bool isOldSci0) { // Early SCI versions used the LSB in the selector ID as a read/write // toggle. To compensate for that, we add every selector name twice. - if (isOldSci0) + if (_oldScriptHeader) _selectorNames.push_back(tmp); } } diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 9c92519cf0..e73914a7e7 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -57,7 +57,7 @@ struct KernelFuncWithSignature { class Kernel { public: - Kernel(ResourceManager *resmgr, bool isOldSci0); + Kernel(ResourceManager *resmgr); ~Kernel(); uint getOpcodesSize() const { return _opcodes.size(); } @@ -84,6 +84,16 @@ public: bool hasKernelFunction(const char *functionName) const; /** + * Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2). + * Old SCI versions used two word header for script blocks (first word equal + * to 0x82, meaning of the second one unknown). New SCI versions used one + * word header. + * Also, old SCI versions assign 120 degrees to left & right, and 60 to up + * and down. Later versions use an even 90 degree distribution. + */ + bool hasOldScriptHeader() const { return _oldScriptHeader; } + + /** * 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). @@ -127,7 +137,12 @@ private: /** * Loads the kernel selector names. */ - void loadSelectorNames(bool isOldSci0); + void loadSelectorNames(); + + /** + * Maps special selectors + */ + void mapSelectors(); /** * Prints auto-detected features from selectors @@ -135,9 +150,9 @@ private: void printAutoDetectedFeatures(); /** - * Maps special selectors + * Detects if the game is using older script headers */ - void mapSelectors(); + void detectOldScriptHeader(); /** * Maps kernel functions @@ -151,6 +166,7 @@ private: bool loadOpcodes(); ResourceManager *_resmgr; + bool _oldScriptHeader; bool _oldGfxFunctions; bool _hasLofsAbsolute; diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 435dd39d5a..d46ce3b938 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -696,7 +696,7 @@ void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int funct_nr, int argc, angle %= 360; - if (!(s->_flags & GF_SCI0_OLD)) { + if (!s->_kernel->hasOldScriptHeader()) { if (angle < 45) loop = 3; else if (angle < 136) diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index bfff828745..f44af2b1cd 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -497,7 +497,7 @@ static SegmentId find_unique_seg_by_type(SegManager *self, int type) { } static byte *find_unique_script_block(EngineState *s, byte *buf, int type) { - if (s->_flags & GF_SCI0_OLD) + if (s->_kernel->hasOldScriptHeader()) buf += 2; do { diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index a524ddd365..d5f0a21385 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -243,7 +243,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod int stackframe = (scr[pos.offset + 2] >> 1) + (*debugState.p_restadjust); int argc = ((*debugState.p_sp)[- stackframe - 1]).offset; - if (!(s->_flags & GF_SCI0_OLD)) + if (!s->_kernel->hasOldScriptHeader()) argc += (*debugState.p_restadjust); printf(" Kernel params: ("); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index d81768c9c8..74486ef015 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -138,7 +138,7 @@ void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) { if (!script || (s->_version >= SCI_VERSION_1_1 && !heap)) { error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap"); } - if (s->_flags & GF_SCI0_OLD) { + if (s->_kernel->hasOldScriptHeader()) { scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2; //locals_size = READ_LE_UINT16(script->data) * 2; } else if (s->_version < SCI_VERSION_1_1) { diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index b3852f10ef..c6643b8a90 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -961,7 +961,7 @@ void run_vm(EngineState *s, int restoring) { gc_countdown(s); xs->sp -= (opparams[1] >> 1) + 1; - if (!(s->_flags & GF_SCI0_OLD)) { + if (!s->_kernel->hasOldScriptHeader()) { xs->sp -= restadjust; s->r_amp_rest = 0; // We just used up the restadjust, remember? } @@ -971,7 +971,7 @@ void run_vm(EngineState *s, int restoring) { } else { int argc = ASSERT_ARITHMETIC(xs->sp[0]); - if (!(s->_flags & GF_SCI0_OLD)) + if (!s->_kernel->hasOldScriptHeader()) argc += restadjust; if (s->_kernel->_kernelFuncs[opparams[0]].signature @@ -988,7 +988,7 @@ void run_vm(EngineState *s, int restoring) { xs_new = &(s->_executionStack.back()); s->_executionStackPosChanged = true; - if (!(s->_flags & GF_SCI0_OLD)) + if (!s->_kernel->hasOldScriptHeader()) restadjust = s->r_amp_rest; } @@ -1500,7 +1500,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select // Early SCI versions used the LSB in the selector ID as a read/write // toggle, meaning that we must remove it for selector lookup. - if (s->_flags & GF_SCI0_OLD) + if (s->_kernel->hasOldScriptHeader()) selector_id &= ~1; if (!obj) { @@ -1659,7 +1659,7 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { Script *scr = s->seg_manager->getScript(seg_id); - if (s->_flags & GF_SCI0_OLD) { + if (s->_kernel->hasOldScriptHeader()) { // int locals_nr = READ_LE_UINT16(script->data); @@ -1835,7 +1835,7 @@ int script_instantiate(EngineState *s, int script_nr) { } void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { - reg_t reg = make_reg(seg, (s->_flags & GF_SCI0_OLD) ? 2 : 0); + reg_t reg = make_reg(seg, s->_kernel->hasOldScriptHeader() ? 2 : 0); int objtype, objlength; Script *scr = s->seg_manager->getScript(seg); @@ -1879,7 +1879,7 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { } void script_uninstantiate(EngineState *s, int script_nr) { - reg_t reg = make_reg(0, (s->_flags & GF_SCI0_OLD) ? 2 : 0); + reg_t reg = make_reg(0, s->_kernel->hasOldScriptHeader() ? 2 : 0); reg.segment = s->seg_manager->segGet(script_nr); Script *scr = script_locate_by_segment(s, reg.segment); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index adaa064a6c..0536ec32ab 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -203,7 +203,7 @@ struct selector_map_t { Selector printLang; /**< Used for i18n */ Selector subtitleLang; Selector parseLang; - Selector motionCue; // Used to detect newer graphics functions semantics. + Selector motionCue; // Used to detect newer graphics functions semantics Selector sightAngle; // Used to detect some SCI0/SCI01 games which need a SCI1 table Selector setVol; // Used to detect newer sound semantics Selector egoMoveSpeed; // Used to detect SCI1 games which use absolute values in lofs diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 698983acaf..09c433edc2 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -151,19 +151,13 @@ Common::Error SciEngine::run() { if (version < SCI_VERSION_1) { // SCI0/SCI01 } else if (version == SCI_VERSION_1) { - // SCI1 - - if (flags & GF_SCI0_OLD || - flags & GF_SCI0_OLDGETTIME) { + if (flags & GF_SCI0_OLDGETTIME) { error("This game entry is erroneous. It's marked as SCI1, but it has SCI0 flags set"); } } else if (version == SCI_VERSION_1_1 || version == SCI_VERSION_32) { - if (flags & GF_SCI0_OLD || - flags & GF_SCI0_OLDGETTIME) { + if (flags & GF_SCI0_OLDGETTIME) { error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI0 flags set"); } - - // SCI1.1 / SCI32 } else { error ("Unknown SCI version in game entry"); } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 82a0f80b34..a2de5c3136 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -83,19 +83,10 @@ extern const char *versionNames[7]; enum SciGameFlags { // SCI0 flags - /* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2) - * Old SCI versions used two word header for script blocks (first word equal - * to 0x82, meaning of the second one unknown). New SCI versions used one - * word header. - * Also, old SCI versions assign 120 degrees to left & right, and 60 to up - * and down. Later versions use an even 90 degree distribution. - */ - GF_SCI0_OLD = (1 << 0), - /* Applies to all versions before 0.000.629 * Older SCI versions had simpler code for GetTime() */ - GF_SCI0_OLDGETTIME = (1 << 1) + GF_SCI0_OLDGETTIME = (1 << 0) }; class SciEngine : public Engine { |