aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFilippos Karapetis2010-05-23 10:28:03 +0000
committerFilippos Karapetis2010-05-23 10:28:03 +0000
commitc874ff15a8e95acb85940ba5de0243b93077cc9d (patch)
tree7d3f79b70d745d775af70d665c10fabf28870dae /engines
parentdd9bf70761f2de9771912984209422f1f63bd3e8 (diff)
downloadscummvm-rg350-c874ff15a8e95acb85940ba5de0243b93077cc9d.tar.gz
scummvm-rg350-c874ff15a8e95acb85940ba5de0243b93077cc9d.tar.bz2
scummvm-rg350-c874ff15a8e95acb85940ba5de0243b93077cc9d.zip
Cleaned up the game ID code:
- The game ID is now obtained from ScummVM ID directly, not by converting Sierra's internal ID - Moved the code which reads the internal Sierra ID inside the resource manager - Moved the code which converts the internal Sierra ID to ScummVM's IDs together with the rest of the detection code svn-id: r49152
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/console.cpp3
-rw-r--r--engines/sci/detection.cpp172
-rw-r--r--engines/sci/engine/game.cpp139
-rw-r--r--engines/sci/engine/kgraphics.cpp8
-rw-r--r--engines/sci/engine/kmisc.cpp4
-rw-r--r--engines/sci/engine/kmovement.cpp2
-rw-r--r--engines/sci/engine/kpathing.cpp4
-rw-r--r--engines/sci/engine/savegame.cpp1
-rw-r--r--engines/sci/engine/state.h2
-rw-r--r--engines/sci/engine/vm.cpp2
-rw-r--r--engines/sci/graphics/gui.cpp2
-rw-r--r--engines/sci/graphics/ports.cpp3
-rw-r--r--engines/sci/graphics/ports.h2
-rw-r--r--engines/sci/resource.cpp35
-rw-r--r--engines/sci/resource.h5
-rw-r--r--engines/sci/sci.cpp2
16 files changed, 191 insertions, 195 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 540b7c84d8..f73932bcb1 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -421,10 +421,9 @@ const char *selector_name(EngineState *s, int selector) {
bool Console::cmdGetVersion(int argc, const char **argv) {
const char *viewTypeDesc[] = { "Unknown", "EGA", "VGA", "VGA SCI1.1", "Amiga" };
- EngineState *s = _engine->_gamestate;
bool hasVocab997 = g_sci->getResMan()->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS)) ? true : false;
- DebugPrintf("Game ID: %s\n", s->_gameId.c_str());
+ DebugPrintf("Game ID: %s\n", _engine->getGameID());
DebugPrintf("Emulated interpreter version: %s\n", getSciVersionDesc(getSciVersion()));
DebugPrintf("\n");
DebugPrintf("Detected features:\n");
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index beea025aea..fc81a4671d 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -120,6 +120,140 @@ static const PlainGameDescriptor SciGameTitles[] = {
{0, 0}
};
+struct OldNewIdTableEntry {
+ const char *oldId;
+ const char *newId;
+ SciVersion version;
+};
+
+static const OldNewIdTableEntry s_oldNewTable[] = {
+ { "arthur", "camelot", SCI_VERSION_NONE },
+ { "brain", "castlebrain", SCI_VERSION_1_MIDDLE }, // Amiga
+ { "brain", "castlebrain", SCI_VERSION_1_LATE },
+ { "demo", "christmas1988", SCI_VERSION_NONE },
+ { "card", "christmas1990", SCI_VERSION_1_EARLY, },
+ { "card", "christmas1992", SCI_VERSION_1_1 },
+ { "RH Budget", "cnick-longbow", SCI_VERSION_NONE },
+ // iceman is the same
+ { "icedemo", "iceman", SCI_VERSION_NONE },
+ // longbow is the same
+ { "eco", "ecoquest", SCI_VERSION_NONE },
+ { "eco2", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 demo
+ { "rain", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 full
+ { "fp", "freddypharkas", SCI_VERSION_NONE },
+ { "emc", "funseeker", SCI_VERSION_NONE },
+ { "gk", "gk1", SCI_VERSION_NONE },
+ { "hoyledemo", "hoyle1", SCI_VERSION_NONE },
+ { "cardgames", "hoyle1", SCI_VERSION_NONE },
+ { "solitare", "hoyle2", SCI_VERSION_NONE },
+ // hoyle3 is the same
+ // hoyle4 is the same
+ { "brain", "islandbrain", SCI_VERSION_1_1 },
+ { "demo000", "kq1sci", SCI_VERSION_NONE },
+ { "kq1", "kq1sci", SCI_VERSION_NONE },
+ { "kq4", "kq4sci", SCI_VERSION_NONE },
+ { "mm1", "laurabow", SCI_VERSION_NONE },
+ { "cb1", "laurabow", SCI_VERSION_NONE },
+ { "lb2", "laurabow2", SCI_VERSION_NONE },
+ { "rh", "longbow", SCI_VERSION_NONE },
+ { "ll1", "lsl1sci", SCI_VERSION_NONE },
+ { "lsl1", "lsl1sci", SCI_VERSION_NONE },
+ // lsl2 is the same
+ { "lsl3", "lsl3", SCI_VERSION_NONE },
+ { "ll5", "lsl5", SCI_VERSION_NONE },
+ // lsl5 is the same
+ // lsl6 is the same
+ { "mg", "mothergoose", SCI_VERSION_NONE },
+ { "twisty", "pepper", SCI_VERSION_NONE },
+ { "pq1", "pq1sci", SCI_VERSION_NONE },
+ { "pq", "pq2", SCI_VERSION_NONE },
+ // pq3 is the same
+ // pq4 is the same
+ { "tales", "fairytales", SCI_VERSION_NONE },
+ { "hq", "qfg1", SCI_VERSION_NONE }, // QFG1 SCI0/EGA
+ { "glory", "qfg1", SCI_VERSION_0_LATE }, // QFG1 SCI0/EGA
+ { "trial", "qfg2", SCI_VERSION_NONE },
+ { "hq2demo", "qfg2", SCI_VERSION_NONE },
+ { "thegame", "slater", SCI_VERSION_NONE },
+ { "sq1demo", "sq1sci", SCI_VERSION_NONE },
+ { "sq1", "sq1sci", SCI_VERSION_NONE },
+ // sq3 is the same
+ // sq4 is the same
+ // sq5 is the same
+ // torin is the same
+
+ // TODO: SCI2.1, SCI3 IDs
+
+ { "", "", SCI_VERSION_NONE }
+};
+
+Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, ResourceManager *resMan) {
+ // Convert the id to lower case, so that we match all upper/lower case variants.
+ sierraId.toLowercase();
+
+ // If the game has less than the expected scripts, it's a demo
+ uint32 demoThreshold = 100;
+ // ...but there are some exceptions
+ if (sierraId == "brain" || sierraId == "lsl1" ||
+ sierraId == "mg" || sierraId == "pq" ||
+ sierraId == "jones" ||
+ sierraId == "cardgames" || sierraId == "solitare" ||
+ sierraId == "hoyle3" || sierraId == "hoyle4")
+ demoThreshold = 40;
+ if (sierraId == "fp" || sierraId == "gk" || sierraId == "pq4")
+ demoThreshold = 150;
+
+ Common::List<ResourceId> *resources = resMan->listResources(kResourceTypeScript, -1);
+ if (resources->size() < demoThreshold) {
+ *gameFlags |= ADGF_DEMO;
+
+ // Crazy Nick's Picks
+ if (sierraId == "lsl1" && resources->size() == 34)
+ return "cnick-lsl";
+ if (sierraId == "sq4" && resources->size() == 34)
+ return "cnick-sq";
+
+ // TODO: cnick-kq, cnick-laurabow and cnick-longbow (their resources can't be read)
+
+ // Handle Astrochicken 1 (SQ3) and 2 (SQ4)
+ if (sierraId == "sq3" && resources->size() == 20)
+ return "astrochicken";
+ if (sierraId == "sq4")
+ return "msastrochicken";
+ }
+
+ for (const OldNewIdTableEntry *cur = s_oldNewTable; cur->oldId[0]; ++cur) {
+ if (sierraId == cur->oldId) {
+ // Distinguish same IDs from the SCI version
+ if (cur->version != SCI_VERSION_NONE && cur->version != getSciVersion())
+ continue;
+
+ return cur->newId;
+ }
+ }
+
+ if (sierraId == "glory") {
+ // This could either be qfg1 VGA, qfg3 or qfg4 demo (all SCI1.1),
+ // or qfg4 full (SCI2)
+ // qfg1 VGA doesn't have view 1
+ if (!resMan->testResource(ResourceId(kResourceTypeView, 1)))
+ return "qfg1";
+
+ // qfg4 full is SCI2
+ if (getSciVersion() == SCI_VERSION_2)
+ return "qfg4";
+
+ // qfg4 demo has less than 50 scripts
+ if (resources->size() < 50)
+ return "qfg4";
+
+ // Otherwise it's qfg3
+ return "qfg3";
+ }
+
+ return sierraId;
+}
+
#include "sci/detection_tables.h"
/**
@@ -205,42 +339,6 @@ Common::Language charToScummVMLanguage(const char c) {
}
}
-#define READ_UINT16(ptr) (!resMan->isSci11Mac() ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr))
-
-// Finds the internal ID of the current game from script 0
-Common::String getSierraGameId(ResourceManager *resMan) {
- Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, 0), false);
- // In SCI0-SCI1, the heap is embedded in the script. In SCI1.1+, it's separated
- Resource *heap = 0;
- byte *seeker = 0;
-
- // Seek to the name selector of the first export
- if (getSciVersion() < SCI_VERSION_1_1) {
- const int nameSelector = 3;
- int extraSci0EarlyBytes = (getSciVersion() == SCI_VERSION_0_EARLY) ? 2 : 0;
- byte *exportPtr = script->data + extraSci0EarlyBytes + 4 + 2;
- seeker = script->data + READ_UINT16(script->data + READ_UINT16(exportPtr) + nameSelector * 2);
- } else {
- const int nameSelector = 5 + 3;
- heap = resMan->findResource(ResourceId(kResourceTypeHeap, 0), false);
- byte *exportPtr = script->data + 4 + 2 + 2;
- seeker = heap->data + READ_UINT16(heap->data + READ_UINT16(exportPtr) + nameSelector * 2);
- }
-
- char sierraId[20];
- int i = 0;
- byte curChar = 0;
-
- do {
- curChar = *(seeker + i);
- sierraId[i++] = curChar;
- } while (curChar != 0);
-
- return sierraId;
-}
-
-#undef READ_UINT16
-
const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
bool foundResMap = false;
bool foundRes000 = false;
@@ -352,7 +450,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
s_fallbackDesc.platform = Common::kPlatformAmiga;
// Determine the game id
- Common::String gameId = convertSierraGameId(getSierraGameId(resMan).c_str(), &s_fallbackDesc.flags, resMan);
+ Common::String gameId = convertSierraGameId(resMan->findSierraGameId(), &s_fallbackDesc.flags, resMan);
strncpy(s_fallbackGameIdBuf, gameId.c_str(), sizeof(s_fallbackGameIdBuf) - 1);
s_fallbackGameIdBuf[sizeof(s_fallbackGameIdBuf) - 1] = 0; // Make sure string is NULL terminated
s_fallbackDesc.gameid = s_fallbackGameIdBuf;
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 4ac2a22531..d7fdd9be6e 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -41,141 +41,6 @@
namespace Sci {
-struct OldNewIdTableEntry {
- const char *oldId;
- const char *newId;
- SciVersion version;
-};
-
-static const OldNewIdTableEntry s_oldNewTable[] = {
- { "arthur", "camelot", SCI_VERSION_NONE },
- { "brain", "castlebrain", SCI_VERSION_1_MIDDLE }, // Amiga
- { "brain", "castlebrain", SCI_VERSION_1_LATE },
- { "demo", "christmas1988", SCI_VERSION_NONE },
- { "card", "christmas1990", SCI_VERSION_1_EARLY, },
- { "card", "christmas1992", SCI_VERSION_1_1 },
- { "RH Budget", "cnick-longbow", SCI_VERSION_NONE },
- // iceman is the same
- { "icedemo", "iceman", SCI_VERSION_NONE },
- // longbow is the same
- { "eco", "ecoquest", SCI_VERSION_NONE },
- { "eco2", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 demo
- { "rain", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 full
- { "fp", "freddypharkas", SCI_VERSION_NONE },
- { "emc", "funseeker", SCI_VERSION_NONE },
- { "gk", "gk1", SCI_VERSION_NONE },
- { "hoyledemo", "hoyle1", SCI_VERSION_NONE },
- { "cardgames", "hoyle1", SCI_VERSION_NONE },
- { "solitare", "hoyle2", SCI_VERSION_NONE },
- // hoyle3 is the same
- // hoyle4 is the same
- { "brain", "islandbrain", SCI_VERSION_1_1 },
- { "demo000", "kq1sci", SCI_VERSION_NONE },
- { "kq1", "kq1sci", SCI_VERSION_NONE },
- { "kq4", "kq4sci", SCI_VERSION_NONE },
- { "mm1", "laurabow", SCI_VERSION_NONE },
- { "cb1", "laurabow", SCI_VERSION_NONE },
- { "lb2", "laurabow2", SCI_VERSION_NONE },
- { "rh", "longbow", SCI_VERSION_NONE },
- { "ll1", "lsl1sci", SCI_VERSION_NONE },
- { "lsl1", "lsl1sci", SCI_VERSION_NONE },
- // lsl2 is the same
- { "lsl3", "lsl3", SCI_VERSION_NONE },
- { "ll5", "lsl5", SCI_VERSION_NONE },
- // lsl5 is the same
- // lsl6 is the same
- { "mg", "mothergoose", SCI_VERSION_NONE },
- { "twisty", "pepper", SCI_VERSION_NONE },
- { "pq1", "pq1sci", SCI_VERSION_NONE },
- { "pq", "pq2", SCI_VERSION_NONE },
- // pq3 is the same
- // pq4 is the same
- { "tales", "fairytales", SCI_VERSION_NONE },
- { "hq", "qfg1", SCI_VERSION_NONE }, // QFG1 SCI0/EGA
- { "glory", "qfg1", SCI_VERSION_0_LATE }, // QFG1 SCI0/EGA
- { "trial", "qfg2", SCI_VERSION_NONE },
- { "hq2demo", "qfg2", SCI_VERSION_NONE },
- { "thegame", "slater", SCI_VERSION_NONE },
- { "sq1demo", "sq1sci", SCI_VERSION_NONE },
- { "sq1", "sq1sci", SCI_VERSION_NONE },
- // sq3 is the same
- // sq4 is the same
- // sq5 is the same
- // torin is the same
-
- // TODO: SCI2.1, SCI3 IDs
-
- { "", "", SCI_VERSION_NONE }
-};
-
-Common::String convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceManager *resMan) {
- // Convert the id to lower case, so that we match all upper/lower case variants.
- Common::String sierraId = gameId;
- sierraId.toLowercase();
-
- // If the game has less than the expected scripts, it's a demo
- uint32 demoThreshold = 100;
- // ...but there are some exceptions
- if (sierraId == "brain" || sierraId == "lsl1" ||
- sierraId == "mg" || sierraId == "pq" ||
- sierraId == "jones" ||
- sierraId == "cardgames" || sierraId == "solitare" ||
- sierraId == "hoyle3" || sierraId == "hoyle4")
- demoThreshold = 40;
- if (sierraId == "fp" || sierraId == "gk" || sierraId == "pq4")
- demoThreshold = 150;
-
- Common::List<ResourceId> *resources = resMan->listResources(kResourceTypeScript, -1);
- if (resources->size() < demoThreshold) {
- *gameFlags |= ADGF_DEMO;
-
- // Crazy Nick's Picks
- if (sierraId == "lsl1" && resources->size() == 34)
- return "cnick-lsl";
- if (sierraId == "sq4" && resources->size() == 34)
- return "cnick-sq";
-
- // TODO: cnick-kq, cnick-laurabow and cnick-longbow (their resources can't be read)
-
- // Handle Astrochicken 1 (SQ3) and 2 (SQ4)
- if (sierraId == "sq3" && resources->size() == 20)
- return "astrochicken";
- if (sierraId == "sq4")
- return "msastrochicken";
- }
-
- for (const OldNewIdTableEntry *cur = s_oldNewTable; cur->oldId[0]; ++cur) {
- if (sierraId == cur->oldId) {
- // Distinguish same IDs from the SCI version
- if (cur->version != SCI_VERSION_NONE && cur->version != getSciVersion())
- continue;
-
- return cur->newId;
- }
- }
-
- if (sierraId == "glory") {
- // This could either be qfg1 VGA, qfg3 or qfg4 demo (all SCI1.1),
- // or qfg4 full (SCI2)
- // qfg1 VGA doesn't have view 1
- if (!resMan->testResource(ResourceId(kResourceTypeView, 1)))
- return "qfg1";
-
- // qfg4 full is SCI2
- if (getSciVersion() == SCI_VERSION_2)
- return "qfg4";
-
- // qfg4 demo has less than 50 scripts
- if (resources->size() < 50)
- return "qfg4";
-
- // Otherwise it's qfg3
- return "qfg3";
- }
-
- return sierraId;
-}
-
#ifdef USE_OLD_MUSIC_FUNCTIONS
int game_init_sound(EngineState *s, int sound_flags, SciVersion soundVersion) {
if (getSciVersion() > SCI_VERSION_0_LATE)
@@ -265,10 +130,6 @@ int game_init(EngineState *s) {
// script_dissect(0, s->_selectorNames);
// The first entry in the export table of script 0 points to the game object
s->_gameObj = s->_segMan->lookupScriptExport(0, 0);
- uint32 gameFlags = 0; // unused
- s->_gameId = convertSierraGameId(s->_segMan->getObjectName(s->_gameObj), &gameFlags, g_sci->getResMan());
-
- debug(2, " \"%s\" at %04x:%04x", s->_gameId.c_str(), PRINT_REG(s->_gameObj));
#ifdef USE_OLD_MUSIC_FUNCTIONS
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index d587790b6c..abc7efd743 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -525,7 +525,7 @@ reg_t kBaseSetter(EngineState *s, int argc, reg_t *argv) {
// WORKAROUND for a problem in LSL1VGA. This allows the casino door to be opened,
// till the actual problem is found
- if (s->_gameId == "lsl1sci" && s->currentRoomNumber() == 300) {
+ if (!strcmp(g_sci->getGameID(), "lsl1sci") && s->currentRoomNumber() == 300) {
int top = GET_SEL32V(s->_segMan, object, SELECTOR(brTop));
PUT_SEL32V(s->_segMan, object, SELECTOR(brTop), top + 2);
}
@@ -799,7 +799,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
// ALL other games use a hardcoded -1 (madness!)
// We are detecting jones/talkie as "jones" as well, but the sierra interpreter of talkie doesnt have this
// "hack". Hopefully it wont cause regressions (the code causes regressions if used against kq5/floppy)
- if (s->_gameId == "jones")
+ if (!strcmp(g_sci->getGameID(), "jones"))
priority = GET_SEL32V(s->_segMan, controlObject, SELECTOR(priority));
else
priority = -1;
@@ -983,7 +983,7 @@ reg_t kDrawCel(EngineState *s, int argc, reg_t *argv) {
bool hiresMode = (argc > 7) ? true : false;
reg_t upscaledHiresHandle = (argc > 7) ? argv[7] : NULL_REG;
- if ((s->_gameId == "freddypharkas") || (s->_gameId == "freddypharkas-demo")) {
+ if (!strcmp(g_sci->getGameID(), "freddypharkas") || !strcmp(g_sci->getGameID(), "freddypharkas-demo")) {
// WORKAROUND
// Script 24 contains code that draws the game menu on screen. It uses a temp variable for setting priority that
// is not set. in Sierra sci this happens to be 8250h. In our sci temporary variables are initialized thus we would
@@ -994,7 +994,7 @@ reg_t kDrawCel(EngineState *s, int argc, reg_t *argv) {
priority = 15;
}
- if (s->_gameId == "laurabow2") {
+ if (!strcmp(g_sci->getGameID(), "laurabow2")) {
// WORKAROUND
// see the one above
if ((viewId == 995) && (priority == 0))
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 450dca3770..74368b8c71 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -62,9 +62,9 @@ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) {
// LSL3 calculates a machinespeed variable during game startup (right after the filthy questions)
// This one would go through w/o throttling resulting in having to do 1000 pushups or something
// Another way of handling this would be delaying incrementing of "machineSpeed" selector
- if (s->_gameId == "lsl3" && s->currentRoomNumber() == 290)
+ if (!strcmp(g_sci->getGameID(), "lsl3") && s->currentRoomNumber() == 290)
s->_throttleTrigger = true;
- if (s->_gameId == "iceman" && s->currentRoomNumber() == 27) {
+ if (!strcmp(g_sci->getGameID(), "iceman") && s->currentRoomNumber() == 27) {
s->_throttleTrigger = true;
neededSleep = 60;
}
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index fcaf0d7ea0..5acda3a325 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -334,7 +334,7 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
}
// FIXME: find out why iceman needs this and we ask for version > SCI01
- if ((getSciVersion() > SCI_VERSION_01) || (s->_gameId == "iceman"))
+ if ((getSciVersion() > SCI_VERSION_01) || !strcmp(g_sci->getGameID(), "iceman"))
if (completed)
invoke_selector(INV_SEL(s, mover, moveDone, kStopOnInvalidSelector), 0);
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index 25d967c247..1152addeba 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -1056,7 +1056,7 @@ static Polygon *convert_polygon(EngineState *s, reg_t polygon) {
// WORKAROUND: broken polygon in lsl1sci, room 350, after opening elevator
// Polygon has 17 points but size is set to 19
- if ((size == 19) && (s->_gameId == "lsl1sci")) {
+ if ((size == 19) && !strcmp(g_sci->getGameID(), "lsl1sci")) {
if ((s->currentRoomNumber() == 350)
&& (read_point(segMan, points, 18) == Common::Point(108, 137))) {
debug(1, "Applying fix for broken polygon in lsl1sci, room 350");
@@ -1174,7 +1174,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co
// WORKAROUND LSL5 room 660. Priority glitch due to us choosing a different path
// than SSCI. Happens when Patti walks to the control room.
- if ((s->_gameId == "lsl5") && (s->currentRoomNumber() == 660) && (Common::Point(67, 131) == *new_start) && (Common::Point(229, 101) == *new_end)) {
+ if (!strcmp(g_sci->getGameID(), "lsl5") && (s->currentRoomNumber() == 660) && (Common::Point(67, 131) == *new_start) && (Common::Point(229, 101) == *new_end)) {
debug(1, "[avoidpath] Applying fix for priority problem in LSL5, room 660");
pf_s->_prependPoint = new_start;
new_start = new Common::Point(77, 107);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index fef2b9a19e..2532d174a1 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -997,7 +997,6 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->_voc->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE);
retval->successor = NULL;
- retval->_gameId = s->_gameId;
#ifdef USE_OLD_MUSIC_FUNCTIONS
retval->_sound._it = NULL;
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index c4b995806f..ad2b0f7058 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -105,8 +105,6 @@ public:
SegManager *_segMan; /**< The segment manager */
Vocabulary *_voc;
- Common::String _gameId; /**< Designation of the primary object (which inherits from Game) */
-
/* Non-VM information */
SciEvent *_event; // Event handling
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index e2ee2e1971..bf447419e8 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1732,7 +1732,7 @@ static EngineState *_game_run(EngineState *&s) {
int game_run(EngineState **_s) {
EngineState *s = *_s;
- debugC(2, kDebugLevelVM, "Calling %s::play()", s->_gameId.c_str());
+ debugC(2, kDebugLevelVM, "Calling %s::play()", g_sci->getGameID());
_init_stack_base_with_selector(s, g_sci->getKernel()->_selectorCache.play); // Call the play selector
// Now: Register the first element on the execution stack-
diff --git a/engines/sci/graphics/gui.cpp b/engines/sci/graphics/gui.cpp
index 46f7fcd689..29ab64ddb2 100644
--- a/engines/sci/graphics/gui.cpp
+++ b/engines/sci/graphics/gui.cpp
@@ -92,7 +92,7 @@ void SciGui::resetEngineState(EngineState *s) {
}
void SciGui::init(bool usesOldGfxFunctions) {
- _ports->init(usesOldGfxFunctions, this, _paint16, _text16, _s->_gameId);
+ _ports->init(usesOldGfxFunctions, this, _paint16, _text16);
_paint16->init(_animate, _text16);
}
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index ab3291dd79..cdb6fe4ae1 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -54,7 +54,7 @@ GfxPorts::~GfxPorts() {
delete _menuPort;
}
-void GfxPorts::init(bool usesOldGfxFunctions, SciGui *gui, GfxPaint16 *paint16, GfxText16 *text16, Common::String gameId) {
+void GfxPorts::init(bool usesOldGfxFunctions, SciGui *gui, GfxPaint16 *paint16, GfxText16 *text16) {
int16 offTop = 10;
_usesOldGfxFunctions = usesOldGfxFunctions;
@@ -88,6 +88,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, SciGui *gui, GfxPaint16 *paint16,
// Jones, Slater and Hoyle 3 were called with parameter -Nw 0 0 200 320.
// Mother Goose (SCI1) uses -Nw 0 0 159 262. The game will later use SetPort so we don't need to set the other fields.
// This actually meant not skipping the first 10 pixellines in windowMgrPort
+ Common::String gameId = g_sci->getGameID();
if (gameId == "jones" || gameId == "slater" || gameId == "hoyle3" || (gameId == "mothergoose" && getSciVersion() == SCI_VERSION_1_EARLY))
offTop = 0;
diff --git a/engines/sci/graphics/ports.h b/engines/sci/graphics/ports.h
index 0876d9e442..c8ce6b3470 100644
--- a/engines/sci/graphics/ports.h
+++ b/engines/sci/graphics/ports.h
@@ -45,7 +45,7 @@ public:
GfxPorts(SegManager *segMan, GfxScreen *screen);
~GfxPorts();
- void init(bool usesOldGfxFunctions, SciGui *gui, GfxPaint16 *paint16, GfxText16 *text16, Common::String gameId);
+ void init(bool usesOldGfxFunctions, SciGui *gui, GfxPaint16 *paint16, GfxText16 *text16);
void kernelSetActive(uint16 portId);
Common::Rect kernelGetPicWindow(int16 &picTop, int16 &picLeft);
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 4888dbd4cb..aa3b8019de 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -2329,6 +2329,41 @@ bool ResourceManager::hasSci1Voc900() {
return offset == res->size;
}
+#define READ_UINT16(ptr) (!isSci11Mac() ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr))
+
+Common::String ResourceManager::findSierraGameId() {
+ Resource *script = findResource(ResourceId(kResourceTypeScript, 0), false);
+ // In SCI0-SCI1, the heap is embedded in the script. In SCI1.1+, it's separated
+ Resource *heap = 0;
+ byte *seeker = 0;
+
+ // Seek to the name selector of the first export
+ if (getSciVersion() < SCI_VERSION_1_1) {
+ const int nameSelector = 3;
+ int extraSci0EarlyBytes = (getSciVersion() == SCI_VERSION_0_EARLY) ? 2 : 0;
+ byte *exportPtr = script->data + extraSci0EarlyBytes + 4 + 2;
+ seeker = script->data + READ_UINT16(script->data + READ_UINT16(exportPtr) + nameSelector * 2);
+ } else {
+ const int nameSelector = 5 + 3;
+ heap = findResource(ResourceId(kResourceTypeHeap, 0), false);
+ byte *exportPtr = script->data + 4 + 2 + 2;
+ seeker = heap->data + READ_UINT16(heap->data + READ_UINT16(exportPtr) + nameSelector * 2);
+ }
+
+ char sierraId[20];
+ int i = 0;
+ byte curChar = 0;
+
+ do {
+ curChar = *(seeker + i);
+ sierraId[i++] = curChar;
+ } while (curChar != 0);
+
+ return sierraId;
+}
+
+#undef READ_UINT16
+
SoundResource::SoundResource(uint32 resNumber, ResourceManager *resMan, SciVersion soundVersion) : _resMan(resMan), _soundVersion(soundVersion) {
Resource *resource = _resMan->findResource(ResourceId(kResourceTypeSound, resNumber), true);
int trackNr, channelNr;
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 48b5f095b1..befda072e0 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -273,6 +273,11 @@ public:
// Detects, if standard font of current game includes extended characters (>0x80)
bool detectFontExtended();
+ /**
+ * Finds the internal Sierra ID of the current game from script 0
+ */
+ Common::String findSierraGameId();
+
protected:
// Maximum number of bytes to allow being allocated for resources
// Note: maxMemory will not be interpreted as a hard limit, only as a restriction
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 4862d0579a..bb5124b88b 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -222,7 +222,7 @@ Common::Error SciEngine::run() {
}
// Add the after market GM patches for the specified game, if they exist
- _resMan->addNewGMPatch(_gamestate->_gameId);
+ _resMan->addNewGMPatch(getGameID());
script_adjust_opcode_formats(_gamestate);
_kernel->loadKernelNames(getGameID());