Skip to content

Commit 902a140

Browse files
committed
SCUMM: Add support for Steam versions of Indy 3, Indy 4, Loom and Dig
Many Thanks to Ben Castricum for the original patch
1 parent 5e78bee commit 902a140

File tree

8 files changed

+168
-15
lines changed

8 files changed

+168
-15
lines changed

Diff for: devtools/scumm-md5.txt

+8
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ indy3 Indiana Jones and the Last Crusade
137137
1dd7aa088e09f96d06818aa9a9deabe0 5361 en Mac No AdLib EGA v1.7, 8/17/90 Fingolfin
138138

139139
1875b90fade138c9253a8e967007031a 6295 en DOS VGA VGA IBM 256 color v2.0 from 3 May 90 Peter Eckerlein, Fingolfin
140+
7fbcff27c323499beaedd605e1ebd47d 561152 en Windows Steam Steam Steam Version Ben Castricum, Filippos Karapetis
141+
a15d6e1e2c52bbd0ff7fa6b63ab7f796 680340 en Mac Steam Steam Steam Version Filippos Karapetis
140142
399b217b0c8d65d0398076da486363a9 6295 de DOS VGA VGA VGA v1.02 from 7 Nov 91 Peter Eckerlein, Fingolfin
141143
17b5d5e6af4ae89d62631641d66d5a05 -1 it DOS VGA VGA IBM 256 color v2.1 from 3 May 01 Andrea Petrucci, Peter Eckerlein
142144
3cce1913a3bc586b51a75c3892ff18dd -1 ru DOS VGA VGA VGA
@@ -170,6 +172,8 @@ loom Loom
170172
6f0be328c64d689bb606d22a389e1b0f 5748 en Mac No AdLib EGA v1.2 25 Jan 91 Fingolfin
171173

172174
5d88b9d6a88e6f8e90cded9d01b7f082 8307 en DOS VGA VGA CD Version v1.0 from 10. Feb 92 (Talkie) Peter Eckerlein, Fingolfin
175+
0354ee0d14cde1264ec762261c04c14a 585728 en Windows Steam Steam Steam Version Ben Castricum, Filippos Karapetis
176+
b4a677bf27c010a747975705108ff1e6 393572 en Mac Steam Steam Steam Version Filippos Karapetis
173177

174178
c5d10e190d4b4d59114b824f2fdbd00e 7540 en FM-TOWNS FM-TOWNS - - dhewg, Andrea Petrucci
175179
31b8fda4c8c7413fa6b39997e776eba4 -1 jp FM-TOWNS FM-TOWNS - - khalek, Andrea Petrucci
@@ -279,6 +283,8 @@ atlantis Indiana Jones and the Fate of Atlantis
279283
d6dd0646404768a63e963891a96daadd 12035 en Mac Floppy Floppy two data files Fingolfin
280284

281285
182344899c2e2998fca0bebcd82aa81a 12035 en DOS - CD - Fingolfin
286+
f3c5d9bf3f091bd1f18dc1013fba5396 638976 en Windows Steam Steam Steam Version Ben Castricum, Filippos Karapetis
287+
6a8133b63d46f6663fbcbb49d5a2edb1 520548 en Mac Steam Steam Steam Version Filippos Karapetis
282288
1a6e5ae2777a6a33f06ffc0226210934 -1 en Mac - CD - Scott Summers
283289
2d9d46f23cb07bbc90b8ad464d3e4ff8 -1 en Mac - CD Mac bundle Joachim Eberhard
284290
8e9417564f33790815445b2136efa667 11915 jp Mac - CD - Petr Maruska
@@ -358,6 +364,8 @@ ft Full Throttle
358364

359365
dig The Dig
360366
d8323015ecb8b10bf53474f6e6b0ae33 16304 All All - - - Fingolfin
367+
aad201302286c1cfee92321cd406e427 811008 en Windows Steam Steam Steam Version Ben Castricum, Filippos Karapetis
368+
d93cc8be628ed5d3b3a29188fc7105d3 1061296 en Mac Steam Steam Steam Version Filippos Karapetis
361369
d62047a6729349ab36f7ee065bf26509 -1 ru All - - - sev
362370
35a2d3040fa512f8232d9e443319d84d 659335495 en Mac - - Mac bundle Fingolfin
363371
21a6592322f92550f144f68a8a4e685e -1 fr Mac - - Mac bundle kaminari

Diff for: engines/scumm/detection.cpp

+24-5
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,12 @@ Common::String ScummEngine::generateFilename(const int room) const {
7979
} else {
8080
switch (_filenamePattern.genMethod) {
8181
case kGenDiskNum:
82+
case kGenDiskNumSteam:
8283
result = Common::String::format(_filenamePattern.pattern, diskNumber);
8384
break;
8485

8586
case kGenRoomNum:
87+
case kGenRoomNumSteam:
8688
result = Common::String::format(_filenamePattern.pattern, room);
8789
break;
8890

@@ -209,14 +211,30 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
209211
return result;
210212
}
211213

212-
static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod) {
214+
static const char *getSteamExeNameFromPattern(Common::String pattern, Common::Platform platform) {
215+
for (const SteamIndexFile *indexFile = steamIndexFiles; indexFile->len; ++indexFile) {
216+
if (platform == indexFile->platform && pattern.equalsIgnoreCase(indexFile->pattern))
217+
return indexFile->executableName;
218+
}
219+
220+
error("Unable to find Steam executable from detection pattern");
221+
return "";
222+
}
223+
224+
static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod, Common::Platform platform) {
213225
Common::String result;
226+
Common::String patternStr = pattern;
214227

215228
switch (genMethod) {
216229
case kGenDiskNum:
217230
case kGenRoomNum:
218231
result = Common::String::format(pattern, 0);
219232
break;
233+
234+
case kGenDiskNumSteam:
235+
case kGenRoomNumSteam:
236+
result = getSteamExeNameFromPattern(pattern, platform);
237+
break;
220238

221239
case kGenHEPC:
222240
case kGenHEIOS:
@@ -528,7 +546,8 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
528546
DetectorResult dr;
529547

530548
// Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631
531-
composeFileHashMap(fileMD5Map, fslist, 2, directoryGlobs);
549+
// Dive two levels down for Mac Steam games
550+
composeFileHashMap(fileMD5Map, fslist, 3, directoryGlobs);
532551

533552
// Iterate over all filename patterns.
534553
for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) {
@@ -540,7 +559,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
540559
// Generate the detectname corresponding to the gfp. If the file doesn't
541560
// exist in the directory we are looking at, we can skip to the next
542561
// one immediately.
543-
Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod));
562+
Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod, gfp->platform));
544563
if (!fileMD5Map.contains(file))
545564
continue;
546565

@@ -1025,7 +1044,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
10251044
Common::FSNode dir(ConfMan.get("path"));
10261045
if (!dir.isDirectory())
10271046
return Common::kPathNotDirectory;
1028-
if (!dir.getChildren(fslist, Common::FSNode::kListFilesOnly))
1047+
if (!dir.getChildren(fslist, Common::FSNode::kListAll))
10291048
return Common::kNoGameDataFoundError;
10301049

10311050
// Invoke the detector, but fixed to the specified gameid.
@@ -1081,7 +1100,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
10811100

10821101
md5Warning += Common::String::format(" SCUMM gameid '%s', file '%s', MD5 '%s'\n\n",
10831102
res.game.gameid,
1084-
generateFilenameForDetection(res.fp.pattern, res.fp.genMethod).c_str(),
1103+
generateFilenameForDetection(res.fp.pattern, res.fp.genMethod, Common::kPlatformUnknown).c_str(),
10851104
res.md5.c_str());
10861105

10871106
g_system->logMessage(LogMessageType::kWarning, md5Warning.c_str());

Diff for: engines/scumm/detection.h

+2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ struct GameSettings {
9595

9696
enum FilenameGenMethod {
9797
kGenDiskNum,
98+
kGenDiskNumSteam,
9899
kGenRoomNum,
100+
kGenRoomNumSteam,
99101
kGenHEMac,
100102
kGenHEMacNoParens,
101103
kGenHEPC,

Diff for: engines/scumm/detection_tables.h

+17-3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ namespace Scumm {
5252
*/
5353
static const char *const directoryGlobs[] = {
5454
"rooms *", // Mac version of indy3/loom
55+
"Contents", // Mac Steam versions
56+
"MacOS", // Mac Steam versions
5557
0
5658
};
5759

@@ -221,6 +223,7 @@ static const GameSettings gameVariantsTable[] = {
221223
{"indy3", "EGA", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
222224
{"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
223225
{"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
226+
{"indy3", "Steam", "steam", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
224227
{"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
225228

226229
{"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
@@ -230,6 +233,7 @@ static const GameSettings gameVariantsTable[] = {
230233
#endif
231234
{"loom", "FM-TOWNS", 0, GID_LOOM, 3, 0, MDT_TOWNS, GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
232235
{"loom", "VGA", "vga", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
236+
{"loom", "Steam", "steam", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
233237

234238
{"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
235239

@@ -245,6 +249,7 @@ static const GameSettings gameVariantsTable[] = {
245249
{"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
246250

247251
{"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
252+
{"atlantis", "Steam", "steam", GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
248253
{"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
249254
{"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
250255

@@ -257,7 +262,8 @@ static const GameSettings gameVariantsTable[] = {
257262
#ifdef ENABLE_SCUMM_7_8
258263
{"ft", 0, 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
259264

260-
{"dig", 0, 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
265+
{"dig", "", 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
266+
{"dig", "Steam", "steam", GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
261267

262268
{"comi", 0, 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)},
263269
#endif
@@ -422,10 +428,10 @@ static const GameSettings gameVariantsTable[] = {
422428
using Common::UNK_LANG;
423429

424430
// The following describes how Fingolfin thinks this table might be used one day;
425-
// this is work in progress, so read this with a salt of grain...
431+
// this is work in progress, so read this with a grain of salt...
426432
//
427433
// The following table maps gameids to possible filename variants for that game.
428-
// This information is used by the detector to determin possible "detect files".
434+
// This information is used by the detector to determine possible "detect files".
429435
// It is also later used by the engine creation code to verify the game to be
430436
// launched is present. Finally, the correct GameFilenamePattern entry is passed on
431437
// to the engine which uses it to locate the files for the game.
@@ -451,13 +457,17 @@ static const GameFilenamePattern gameFilenamesTable[] = {
451457
{ "zak", "zak1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "V1" }, // ... and zak2.d64
452458

453459
{ "indy3", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
460+
{ "indy3", "%02d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
461+
{ "indy3", "%02d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
454462

455463
{ "indyloom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
456464
{ "indyzak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
457465
{ "zakloom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
458466

459467
{ "loom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
460468
{ "loom", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, "VGA" }, // Loom CD
469+
{ "loom", "%03d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
470+
{ "loom", "%03d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
461471

462472
{ "pass", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
463473

@@ -471,6 +481,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
471481
{ "monkey2", "mi2demo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
472482

473483
{ "atlantis", "atlantis.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
484+
{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
485+
{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
474486
{ "atlantis", "fate.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
475487
{ "atlantis", "playfate.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
476488
{ "atlantis", "indy4.%03d", kGenDiskNum, Common::JA_JPN, Common::kPlatformFMTowns, "FM-TOWNS" },
@@ -494,6 +506,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
494506

495507
#ifdef ENABLE_SCUMM_7_8
496508
{ "dig", "dig.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
509+
{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
510+
{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
497511
{ "dig", "thedig.la%d", kGenDiskNum, UNK_LANG, UNK, "Demo" }, // Used by an alternate version of the demo
498512
{ "dig", "The Dig Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
499513
{ "dig", "The Dig Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, "Demo" },

Diff for: engines/scumm/file.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929

3030
namespace Scumm {
3131

32+
// The following table includes all the index files, which are embedded in the
33+
// main game executables in Steam versions.
34+
const SteamIndexFile steamIndexFiles[] = {
35+
{ GID_INDY3, Common::kPlatformWindows, "%02d.LFL", "00.LFL", "Indiana Jones and the Last Crusade.exe", 162056, 6295 },
36+
{ GID_INDY3, Common::kPlatformMacintosh, "%02d.LFL", "00.LFL", "The Last Crusade", 150368, 6295 },
37+
{ GID_INDY4, Common::kPlatformWindows, "atlantis.%03d", "ATLANTIS.000", "Indiana Jones and the Fate of Atlantis.exe", 224336, 12035 },
38+
{ GID_INDY4, Common::kPlatformMacintosh, "atlantis.%03d", "ATLANTIS.000", "The Fate of Atlantis", 260224, 12035 },
39+
{ GID_LOOM, Common::kPlatformWindows, "%03d.LFL", "000.LFL", "Loom.exe", 187248, 8307 },
40+
{ GID_LOOM, Common::kPlatformMacintosh, "%03d.LFL", "000.LFL", "Loom", 170464, 8307 },
41+
#ifdef ENABLE_SCUMM_7_8
42+
{ GID_DIG, Common::kPlatformWindows, "dig.la%d", "DIG.LA0", "The Dig.exe", 340632, 16304 },
43+
{ GID_DIG, Common::kPlatformMacintosh, "dig.la%d", "DIG.LA0", "The Dig", 339744, 16304 },
44+
#endif
45+
{ 0, Common::kPlatformUnknown, "", "", "", 0, 0 }
46+
};
47+
3248
#pragma mark -
3349
#pragma mark --- ScummFile ---
3450
#pragma mark -
@@ -184,6 +200,29 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
184200
return realLen;
185201
}
186202

203+
#pragma mark -
204+
#pragma mark --- ScummSteamFile ---
205+
#pragma mark -
206+
bool ScummSteamFile::open(const Common::String &filename) {
207+
for (const SteamIndexFile *indexFile = steamIndexFiles; indexFile->len; ++indexFile) {
208+
if (indexFile->id == _steamGame.id && indexFile->platform == _steamGame.platform && filename.equalsIgnoreCase(indexFile->indexFileName))
209+
return openWithSubRange(indexFile->executableName, indexFile->start, indexFile->len);
210+
}
211+
212+
// Regular non-bundled file
213+
return ScummFile::open(filename);
214+
}
215+
216+
bool ScummSteamFile::openWithSubRange(const Common::String &filename, int32 subFileStart, int32 subFileLen) {
217+
if (ScummFile::open(filename)) {
218+
_subFileStart = subFileStart;
219+
_subFileLen = subFileLen;
220+
seek(0, SEEK_SET);
221+
return true;
222+
} else
223+
return false;
224+
}
225+
187226
#pragma mark -
188227
#pragma mark --- ScummDiskImage ---
189228
#pragma mark -

Diff for: engines/scumm/file.h

+26-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class BaseScummFile : public Common::File {
5353
};
5454

5555
class ScummFile : public BaseScummFile {
56-
private:
56+
protected:
5757
int32 _subFileStart;
5858
int32 _subFileLen;
5959
bool _myEos; // Have we read past the end of the subfile?
@@ -64,7 +64,7 @@ class ScummFile : public BaseScummFile {
6464
public:
6565
ScummFile();
6666

67-
bool open(const Common::String &filename);
67+
virtual bool open(const Common::String &filename);
6868
bool openSubFile(const Common::String &filename);
6969

7070
void clearErr() { _myEos = false; BaseScummFile::clearErr(); }
@@ -76,6 +76,18 @@ class ScummFile : public BaseScummFile {
7676
uint32 read(void *dataPtr, uint32 dataSize);
7777
};
7878

79+
class ScummSteamFile : public ScummFile {
80+
private:
81+
GameSettings _steamGame;
82+
83+
bool openWithSubRange(const Common::String &filename, int32 subFileStart, int32 subFileLen);
84+
85+
public:
86+
ScummSteamFile(GameSettings game) : ScummFile(), _steamGame(game) {}
87+
88+
bool open(const Common::String &filename);
89+
};
90+
7991
class ScummDiskImage : public BaseScummFile {
8092
private:
8193
Common::SeekableReadStream *_stream;
@@ -120,6 +132,18 @@ class ScummDiskImage : public BaseScummFile {
120132
uint32 read(void *dataPtr, uint32 dataSize);
121133
};
122134

135+
struct SteamIndexFile {
136+
byte id;
137+
Common::Platform platform;
138+
const char *pattern;
139+
const char *indexFileName;
140+
const char *executableName;
141+
int32 start;
142+
int32 len;
143+
};
144+
145+
extern const SteamIndexFile steamIndexFiles[];
146+
123147
} // End of namespace Scumm
124148

125149
#endif

0 commit comments

Comments
 (0)