[Scummvm-cvs-logs] scummvm master -> b77412a9a07e58a21dd430e28cf34210d4648fd0

lordhoto lordhoto at gmail.com
Sat Jul 5 13:36:13 CEST 2014


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
902a140f3e SCUMM: Add support for Steam versions of Indy 3, Indy 4, Loom and Dig
53d3ee07df SCUMM: Add support for CD audio tracks in the Steam versions of Loom
b77412a9a0 Merge pull request #470 from bluegr/Lucasarts_Steam


Commit: 902a140f3e8058c582496296c7c1e0c55b243dda
    https://github.com/scummvm/scummvm/commit/902a140f3e8058c582496296c7c1e0c55b243dda
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2014-07-03T00:13:33+03:00

Commit Message:
SCUMM: Add support for Steam versions of Indy 3, Indy 4, Loom and Dig

Many Thanks to Ben Castricum for the original patch

Changed paths:
    devtools/scumm-md5.txt
    engines/scumm/detection.cpp
    engines/scumm/detection.h
    engines/scumm/detection_tables.h
    engines/scumm/file.cpp
    engines/scumm/file.h
    engines/scumm/scumm-md5.h
    engines/scumm/scumm.cpp



diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index e458689..f0cb577 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -137,6 +137,8 @@ indy3	Indiana Jones and the Last Crusade
 	1dd7aa088e09f96d06818aa9a9deabe0	5361	en	Mac	No AdLib	EGA	v1.7, 8/17/90	Fingolfin
 
 	1875b90fade138c9253a8e967007031a	6295	en	DOS	VGA	VGA	IBM 256 color v2.0 from 3 May 90	Peter Eckerlein, Fingolfin
+	7fbcff27c323499beaedd605e1ebd47d	561152	en	Windows	Steam	Steam	Steam Version	Ben Castricum, Filippos Karapetis
+	a15d6e1e2c52bbd0ff7fa6b63ab7f796	680340	en	Mac	Steam	Steam	Steam Version	Filippos Karapetis
 	399b217b0c8d65d0398076da486363a9	6295	de	DOS	VGA	VGA	VGA v1.02 from 7 Nov 91	Peter Eckerlein, Fingolfin
 	17b5d5e6af4ae89d62631641d66d5a05	-1	it	DOS	VGA	VGA	IBM 256 color v2.1 from 3 May 01	Andrea Petrucci, Peter Eckerlein
 	3cce1913a3bc586b51a75c3892ff18dd	-1	ru	DOS	VGA	VGA	VGA	
@@ -170,6 +172,8 @@ loom	Loom
 	6f0be328c64d689bb606d22a389e1b0f	5748	en	Mac	No AdLib	EGA	v1.2 25 Jan 91	Fingolfin
 
 	5d88b9d6a88e6f8e90cded9d01b7f082	8307	en	DOS	VGA	VGA	CD Version v1.0 from 10. Feb 92 (Talkie)	Peter Eckerlein, Fingolfin
+	0354ee0d14cde1264ec762261c04c14a	585728	en	Windows	Steam	Steam	Steam Version	Ben Castricum, Filippos Karapetis
+	b4a677bf27c010a747975705108ff1e6	393572	en	Mac	Steam	Steam	Steam Version	Filippos Karapetis
 
 	c5d10e190d4b4d59114b824f2fdbd00e	7540	en	FM-TOWNS	FM-TOWNS	-	-	dhewg, Andrea Petrucci
 	31b8fda4c8c7413fa6b39997e776eba4	-1	jp	FM-TOWNS	FM-TOWNS	-	-	khalek, Andrea Petrucci
@@ -279,6 +283,8 @@ atlantis	Indiana Jones and the Fate of Atlantis
 	d6dd0646404768a63e963891a96daadd	12035	en	Mac	Floppy	Floppy	two data files	Fingolfin
 
 	182344899c2e2998fca0bebcd82aa81a	12035	en	DOS	-	CD	-	Fingolfin
+	f3c5d9bf3f091bd1f18dc1013fba5396	638976	en	Windows	Steam	Steam	Steam Version	Ben Castricum, Filippos Karapetis
+	6a8133b63d46f6663fbcbb49d5a2edb1	520548	en	Mac	Steam	Steam	Steam Version	Filippos Karapetis
 	1a6e5ae2777a6a33f06ffc0226210934	-1	en	Mac	-	CD	-	Scott Summers
 	2d9d46f23cb07bbc90b8ad464d3e4ff8	-1	en	Mac	-	CD	Mac bundle	Joachim Eberhard
 	8e9417564f33790815445b2136efa667	11915	jp	Mac	-	CD	-	Petr Maruska
@@ -358,6 +364,8 @@ ft	Full Throttle
 
 dig	The Dig
 	d8323015ecb8b10bf53474f6e6b0ae33	16304	All	All	-	-	-	Fingolfin
+	aad201302286c1cfee92321cd406e427	811008	en	Windows	Steam	Steam	Steam Version	Ben Castricum, Filippos Karapetis
+	d93cc8be628ed5d3b3a29188fc7105d3	1061296	en	Mac	Steam	Steam	Steam Version	Filippos Karapetis
 	d62047a6729349ab36f7ee065bf26509	-1	ru	All	-	-	-	sev
 	35a2d3040fa512f8232d9e443319d84d	659335495	en	Mac	-	-	Mac bundle	Fingolfin
 	21a6592322f92550f144f68a8a4e685e	-1	fr	Mac	-	-	Mac bundle	kaminari
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index b7a2580..55df592 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -79,10 +79,12 @@ Common::String ScummEngine::generateFilename(const int room) const {
 	} else {
 		switch (_filenamePattern.genMethod) {
 		case kGenDiskNum:
+		case kGenDiskNumSteam:
 			result = Common::String::format(_filenamePattern.pattern, diskNumber);
 			break;
 
 		case kGenRoomNum:
+		case kGenRoomNumSteam:
 			result = Common::String::format(_filenamePattern.pattern, room);
 			break;
 
@@ -209,14 +211,30 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
 	return result;
 }
 
-static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod) {
+static const char *getSteamExeNameFromPattern(Common::String pattern, Common::Platform platform) {
+	for (const SteamIndexFile *indexFile = steamIndexFiles; indexFile->len; ++indexFile) {
+		if (platform == indexFile->platform && pattern.equalsIgnoreCase(indexFile->pattern))
+			return indexFile->executableName;
+	}
+
+	error("Unable to find Steam executable from detection pattern");
+	return "";
+}
+
+static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod, Common::Platform platform) {
 	Common::String result;
+	Common::String patternStr = pattern;
 
 	switch (genMethod) {
 	case kGenDiskNum:
 	case kGenRoomNum:
 		result = Common::String::format(pattern, 0);
 		break;
+	
+	case kGenDiskNumSteam:
+	case kGenRoomNumSteam:
+		result = getSteamExeNameFromPattern(pattern, platform);
+		break;
 
 	case kGenHEPC:
 	case kGenHEIOS:
@@ -528,7 +546,8 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
 	DetectorResult dr;
 
 	// Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631
-	composeFileHashMap(fileMD5Map, fslist, 2, directoryGlobs);
+	// Dive two levels down for Mac Steam games
+	composeFileHashMap(fileMD5Map, fslist, 3, directoryGlobs);
 
 	// Iterate over all filename patterns.
 	for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) {
@@ -540,7 +559,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
 		// Generate the detectname corresponding to the gfp. If the file doesn't
 		// exist in the directory we are looking at, we can skip to the next
 		// one immediately.
-		Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod));
+		Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod, gfp->platform));
 		if (!fileMD5Map.contains(file))
 			continue;
 
@@ -1025,7 +1044,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
 	Common::FSNode dir(ConfMan.get("path"));
 	if (!dir.isDirectory())
 		return Common::kPathNotDirectory;
-	if (!dir.getChildren(fslist, Common::FSNode::kListFilesOnly))
+	if (!dir.getChildren(fslist, Common::FSNode::kListAll))
 		return Common::kNoGameDataFoundError;
 
 	// Invoke the detector, but fixed to the specified gameid.
@@ -1081,7 +1100,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
 
 		md5Warning += Common::String::format("  SCUMM gameid '%s', file '%s', MD5 '%s'\n\n",
 				res.game.gameid,
-				generateFilenameForDetection(res.fp.pattern, res.fp.genMethod).c_str(),
+				generateFilenameForDetection(res.fp.pattern, res.fp.genMethod, Common::kPlatformUnknown).c_str(),
 				res.md5.c_str());
 
 		g_system->logMessage(LogMessageType::kWarning, md5Warning.c_str());
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index f714812..0587c3f 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -95,7 +95,9 @@ struct GameSettings {
 
 enum FilenameGenMethod {
 	kGenDiskNum,
+	kGenDiskNumSteam,
 	kGenRoomNum,
+	kGenRoomNumSteam,
 	kGenHEMac,
 	kGenHEMacNoParens,
 	kGenHEPC,
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index c876af1..1dccbd3 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -52,6 +52,8 @@ namespace Scumm {
  */
 static const char *const directoryGlobs[] = {
 	"rooms *",  // Mac version of indy3/loom
+	"Contents", // Mac Steam versions
+	"MacOS",    // Mac Steam versions
 	0
 };
 
@@ -221,6 +223,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"indy3", "EGA",      "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
 	{"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR,             0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
 	{"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)},
+	{"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)},
 	{"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)},
 
 	{"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[] = {
 #endif
 	{"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)},
 	{"loom", "VGA",      "vga", GID_LOOM, 4, 0, MDT_NONE,                         GF_AUDIOTRACKS,             Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
+	{"loom", "Steam",  "steam", GID_LOOM, 4, 0, MDT_NONE,                         GF_AUDIOTRACKS,  UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
 
 	{"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
 
@@ -245,6 +249,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"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)},
 
 	{"atlantis", "", 0, GID_INDY4,    5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
+	{"atlantis", "Steam", "steam", GID_INDY4,    5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
 	{"atlantis", "Floppy", 0, GID_INDY4,    5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
 	{"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)},
 
@@ -257,7 +262,8 @@ static const GameSettings gameVariantsTable[] = {
 #ifdef ENABLE_SCUMM_7_8
 	{"ft",       0, 0, GID_FT,  7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
 
-	{"dig",      0, 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
+	{"dig",       "",       0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
+	{"dig",  "Steam", "steam", GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
 
 	{"comi",     0, 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)},
 #endif
@@ -422,10 +428,10 @@ static const GameSettings gameVariantsTable[] = {
 using Common::UNK_LANG;
 
 // The following describes how Fingolfin thinks this table might be used one day;
-// this is work in progress, so read this with a salt of grain...
+// this is work in progress, so read this with a grain of salt...
 //
 // The following table maps gameids to possible filename variants for that game.
-// This information is used by the detector to determin possible "detect files".
+// This information is used by the detector to determine possible "detect files".
 // It is also later used by the engine creation code to verify the game to be
 // launched is present. Finally, the correct GameFilenamePattern entry is passed on
 // to the engine which uses it to locate the files for the game.
@@ -451,6 +457,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
 	{ "zak", "zak1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "V1" },         // ... and zak2.d64
 
 	{ "indy3", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
+	{ "indy3", "%02d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
+	{ "indy3", "%02d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
 
 	{ "indyloom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
 	{ "indyzak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
@@ -458,6 +466,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
 
 	{ "loom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
 	{ "loom", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, "VGA" },	// Loom CD
+	{ "loom", "%03d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
+	{ "loom", "%03d.LFL", kGenRoomNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
 
 	{ "pass", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
 
@@ -471,6 +481,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
 	{ "monkey2", "mi2demo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
 
 	{ "atlantis", "atlantis.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
+	{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
+	{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
 	{ "atlantis", "fate.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
 	{ "atlantis", "playfate.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
 	{ "atlantis", "indy4.%03d", kGenDiskNum, Common::JA_JPN, Common::kPlatformFMTowns, "FM-TOWNS" },
@@ -494,6 +506,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
 
 #ifdef ENABLE_SCUMM_7_8
 	{ "dig", "dig.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
+	{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformWindows, "Steam" },
+	{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
 	{ "dig", "thedig.la%d", kGenDiskNum, UNK_LANG, UNK, "Demo" }, // Used by an alternate version of the demo
 	{ "dig", "The Dig Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
 	{ "dig", "The Dig Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, "Demo" },
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 9c161ff..21b0e59 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -29,6 +29,22 @@
 
 namespace Scumm {
 
+// The following table includes all the index files, which are embedded in the
+// main game executables in Steam versions.
+const SteamIndexFile steamIndexFiles[] = {
+	{ GID_INDY3, Common::kPlatformWindows,   "%02d.LFL",      "00.LFL",       "Indiana Jones and the Last Crusade.exe",     162056,  6295 },
+	{ GID_INDY3, Common::kPlatformMacintosh, "%02d.LFL",      "00.LFL",       "The Last Crusade",                           150368,  6295 },
+	{ GID_INDY4, Common::kPlatformWindows,   "atlantis.%03d", "ATLANTIS.000",  "Indiana Jones and the Fate of Atlantis.exe", 224336, 12035 },
+	{ GID_INDY4, Common::kPlatformMacintosh, "atlantis.%03d", "ATLANTIS.000",  "The Fate of Atlantis",                       260224, 12035 },
+	{ GID_LOOM,  Common::kPlatformWindows,   "%03d.LFL",      "000.LFL",       "Loom.exe",                                   187248,  8307 },
+	{ GID_LOOM,  Common::kPlatformMacintosh, "%03d.LFL",      "000.LFL",       "Loom",                                       170464,  8307 },
+#ifdef ENABLE_SCUMM_7_8
+	{ GID_DIG,   Common::kPlatformWindows,   "dig.la%d",      "DIG.LA0",       "The Dig.exe",                                340632, 16304 },
+	{ GID_DIG,   Common::kPlatformMacintosh, "dig.la%d",      "DIG.LA0",       "The Dig",                                    339744, 16304 },
+#endif
+	{ 0,         Common::kPlatformUnknown,   "",              "",              "",                                                0,     0 }
+};
+
 #pragma mark -
 #pragma mark --- ScummFile ---
 #pragma mark -
@@ -185,6 +201,29 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
 }
 
 #pragma mark -
+#pragma mark --- ScummSteamFile ---
+#pragma mark -
+bool ScummSteamFile::open(const Common::String &filename) {
+	for (const SteamIndexFile *indexFile = steamIndexFiles; indexFile->len; ++indexFile) {
+		if (indexFile->id == _steamGame.id && indexFile->platform == _steamGame.platform && filename.equalsIgnoreCase(indexFile->indexFileName))
+			return openWithSubRange(indexFile->executableName, indexFile->start, indexFile->len);
+	}
+
+	// Regular non-bundled file
+	return ScummFile::open(filename);
+}
+
+bool ScummSteamFile::openWithSubRange(const Common::String &filename, int32 subFileStart, int32 subFileLen) {
+	if (ScummFile::open(filename)) {
+		_subFileStart = subFileStart;
+		_subFileLen = subFileLen;
+		seek(0, SEEK_SET);
+		return true;
+	} else
+		return false;
+}
+
+#pragma mark -
 #pragma mark --- ScummDiskImage ---
 #pragma mark -
 
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index d6dbc06..f3eaac5 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -53,7 +53,7 @@ public:
 };
 
 class ScummFile : public BaseScummFile {
-private:
+protected:
 	int32	_subFileStart;
 	int32	_subFileLen;
 	bool	_myEos; // Have we read past the end of the subfile?
@@ -64,7 +64,7 @@ private:
 public:
 	ScummFile();
 
-	bool open(const Common::String &filename);
+	virtual bool open(const Common::String &filename);
 	bool openSubFile(const Common::String &filename);
 
 	void clearErr() { _myEos = false; BaseScummFile::clearErr(); }
@@ -76,6 +76,18 @@ public:
 	uint32 read(void *dataPtr, uint32 dataSize);
 };
 
+class ScummSteamFile : public ScummFile {
+private:
+	GameSettings _steamGame;
+
+	bool openWithSubRange(const Common::String &filename, int32 subFileStart, int32 subFileLen);
+
+public:
+	ScummSteamFile(GameSettings game) : ScummFile(), _steamGame(game) {}
+
+	bool open(const Common::String &filename);
+};
+
 class ScummDiskImage : public BaseScummFile {
 private:
 	Common::SeekableReadStream *_stream;
@@ -120,6 +132,18 @@ public:
 	uint32 read(void *dataPtr, uint32 dataSize);
 };
 
+struct SteamIndexFile {
+	byte id;
+	Common::Platform platform;
+	const char *pattern;
+	const char *indexFileName;
+	const char *executableName;
+	int32 start;
+	int32 len;
+};
+
+extern const SteamIndexFile steamIndexFiles[];
+
 } // End of namespace Scumm
 
 #endif
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 8accf39..0eeff57 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
 /*
-  This file was generated by the md5table tool on Wed Jun 25 09:07:50 2014
+  This file was generated by the md5table tool on Wed Jun 25 10:34:07 2014
   DO NOT EDIT MANUALLY!
  */
 
@@ -17,6 +17,7 @@ static const MD5Table md5table[] = {
 	{ "008e76ec3ae58d0add637ea7aa299a2c", "freddi3", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
 	{ "02cae0e7ff8504f73618391873d5781a", "freddi3", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
 	{ "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
+	{ "0354ee0d14cde1264ec762261c04c14a", "loom", "Steam", "Steam", 585728, Common::EN_ANY, Common::kPlatformWindows },
 	{ "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS },
 	{ "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
 	{ "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows },
@@ -299,6 +300,7 @@ static const MD5Table md5table[] = {
 	{ "69ffe29185b8d71f09f6199f8b2a87cb", "lost", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
 	{ "6a30a07f353a75cdc602db27d73e1b42", "puttputt", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows },
 	{ "6a60d395b78b205c93a956100b1bf5ae", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
+	{ "6a8133b63d46f6663fbcbb49d5a2edb1", "atlantis", "Steam", "Steam", 520548, Common::EN_ANY, Common::kPlatformMacintosh },
 	{ "6af2419fe3db5c2fdb091ae4e5833770", "puttrace", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
 	{ "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
 	{ "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", "HE 100", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
@@ -357,6 +359,7 @@ static const MD5Table md5table[] = {
 	{ "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
 	{ "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformDOS },
 	{ "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
+	{ "7fbcff27c323499beaedd605e1ebd47d", "indy3", "Steam", "Steam", 561152, Common::EN_ANY, Common::kPlatformWindows },
 	{ "7fc6cdb46b4c9d384c52327f4bca6416", "football", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "810a9da887aefa597b0cf3c77d262897", "BluesABCTime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "822807c3cd3b43a925cab2767ca6b453", "BluesTreasureHunt", "", "Disc 1", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -439,6 +442,7 @@ static const MD5Table md5table[] = {
 	{ "a095616d2d23ccf43b8e257711202cba", "football2002", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "a095e33061606d231ff37dca4c64c8ac", "pajama", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
 	{ "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
+	{ "a15d6e1e2c52bbd0ff7fa6b63ab7f796", "indy3", "Steam", "Steam", 680340, Common::EN_ANY, Common::kPlatformMacintosh },
 	{ "a194f15f51ee62badab74b9e7da97693", "baseball2001", "", "Demo", 20507, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "a197a87ae77f3b3333f09a7a2c448fe2", "freddi", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
 	{ "a22af0ad0e3126d19d22707b0267a37d", "balloon", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
@@ -467,6 +471,7 @@ static const MD5Table md5table[] = {
 	{ "aa8a0cb65f3afbbe2c14c3f9f92775a3", "monkey", "CD", "CD", 8955, Common::FR_FRA, Common::kPlatformDOS },
 	{ "aaa587701cde7e74692c68c1024b85eb", "puttrace", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
 	{ "aaa7f36a253f277dd29dd1c051b0e4b9", "indy3", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
+	{ "aad201302286c1cfee92321cd406e427", "dig", "Steam", "Steam", 811008, Common::EN_ANY, Common::kPlatformWindows },
 	{ "ab0693e9324cfcf498fdcbb12acf8bb4", "puttcircus", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "ac1642b6edfb8521ca03760126f1c250", "tentacle", "", "Demo", -1, Common::DE_DEU, Common::kPlatformDOS },
 	{ "ac62d50e39492ee3738b4e83a5ac780f", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
@@ -480,6 +485,7 @@ static const MD5Table md5table[] = {
 	{ "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformDOS },
 	{ "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS },
 	{ "b47be81e39a9710f6f595f7b527b60f8", "puttrace", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
+	{ "b4a677bf27c010a747975705108ff1e6", "loom", "Steam", "Steam", 393572, Common::EN_ANY, Common::kPlatformMacintosh },
 	{ "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
 	{ "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformDOS },
 	{ "b628506f7def772e40de0aa5440fb8e1", "activity", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -569,6 +575,7 @@ static const MD5Table md5table[] = {
 	{ "d7b247c26bf1f01f8f7daf142be84de3", "balloon", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
 	{ "d8323015ecb8b10bf53474f6e6b0ae33", "dig", "", "", 16304, Common::UNK_LANG, Common::kPlatformUnknown },
 	{ "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown },
+	{ "d93cc8be628ed5d3b3a29188fc7105d3", "dig", "Steam", "Steam", 1061296, Common::EN_ANY, Common::kPlatformMacintosh },
 	{ "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformDOS },
 	{ "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "FM-TOWNS", "", 11135, Common::EN_ANY, Common::kPlatformFMTowns },
 	{ "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformDOS },
@@ -629,6 +636,7 @@ static const MD5Table md5table[] = {
 	{ "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown },
 	{ "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformDOS },
 	{ "f2ec78e50bdc63b70044e9758be10914", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformMacintosh },
+	{ "f3c5d9bf3f091bd1f18dc1013fba5396", "atlantis", "Steam", "Steam", 638976, Common::EN_ANY, Common::kPlatformWindows },
 	{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
 	{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
 	{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 34c231e..8c03259 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1026,6 +1026,35 @@ Common::Error ScummEngine::init() {
 	}
 #endif
 
+	// Extra directories needed for the Steam versions
+	if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam) {
+		if (_game.platform == Common::kPlatformWindows) {
+			switch (_game.id) {
+			case GID_INDY3 :
+				SearchMan.addSubDirectoryMatching(gameDataDir, "indy3");
+				break;
+			case GID_INDY4 :
+				SearchMan.addSubDirectoryMatching(gameDataDir, "atlantis");
+				break;
+			case GID_LOOM :
+				SearchMan.addSubDirectoryMatching(gameDataDir, "loom");
+				break;
+#ifdef ENABLE_SCUMM_7_8
+			case GID_DIG :
+				SearchMan.addSubDirectoryMatching(gameDataDir, "dig");
+				SearchMan.addSubDirectoryMatching(gameDataDir, "dig/video");
+				break;
+#endif
+			default:
+				break;
+			}
+		} else {
+			SearchMan.addSubDirectoryMatching(gameDataDir, "Contents");
+			SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/MacOS");
+			SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/Resources");
+			SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/Resources/video");
+		}
+	}
 
 	// The	kGenUnchanged method is only used for 'container files', i.e. files
 	// that contain the real game files bundled together in an archive format.
@@ -1126,15 +1155,25 @@ Common::Error ScummEngine::init() {
 				error("Couldn't find known subfile inside container file '%s'", _containerFile.c_str());
 
 			_fileHandle->close();
-
 		} else {
 			error("kGenUnchanged used with unsupported platform");
 		}
 	} else {
-		// Regular access, no container file involved
-		_fileHandle = new ScummFile();
+		if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam) {
+			// Steam game versions have the index file embedded in the main executable
+			_fileHandle = new ScummSteamFile(_game);
+		} else {
+			// Regular access, no container file involved
+			_fileHandle = new ScummFile();
+		}
 	}
 
+	// Steam Win and Mac versions share the same DOS data files. We show Windows or Mac
+	// for the platform the detector, but internally we force the platform to DOS, so that
+	// the code for handling the original DOS data files is used.
+	if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam)
+		_game.platform = Common::kPlatformDOS;
+
 	// Load CJK font, if present
 	// Load it earlier so _useCJKMode variable could be set
 	loadCJKFont();
@@ -1218,7 +1257,7 @@ Common::Error ScummEngine::init() {
 
 void ScummEngine::setupScumm() {
 	// On some systems it's not safe to run CD audio games from the CD.
-	if (_game.features & GF_AUDIOTRACKS) {
+	if (_game.features & GF_AUDIOTRACKS && !Common::File::exists("CDDA.SOU")) {
 		checkCD();
 
 		int cd_num = ConfMan.getInt("cdrom");


Commit: 53d3ee07df6eea863e93620ab4a406eb24fbfef1
    https://github.com/scummvm/scummvm/commit/53d3ee07df6eea863e93620ab4a406eb24fbfef1
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2014-07-04T23:33:43+03:00

Commit Message:
SCUMM: Add support for CD audio tracks in the Steam versions of Loom

Many Thanks to Ben Castricum for the original patch

Changed paths:
  A engines/scumm/cdda.cpp
  A engines/scumm/cdda.h
    engines/scumm/module.mk
    engines/scumm/saveload.cpp
    engines/scumm/sound.cpp
    engines/scumm/sound.h



diff --git a/engines/scumm/cdda.cpp b/engines/scumm/cdda.cpp
new file mode 100644
index 0000000..adb414e
--- /dev/null
+++ b/engines/scumm/cdda.cpp
@@ -0,0 +1,120 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/cdda.h"
+#include "common/stream.h"
+#include "audio/audiostream.h"
+
+namespace Scumm {
+
+
+#pragma mark -
+#pragma mark --- CDDA stream ---
+#pragma mark -
+
+#define START_OF_CDDA_DATA 800
+#define BLOCK_SIZE 1177
+
+class CDDAStream : public Audio::SeekableAudioStream {
+private:
+	Common::SeekableReadStream *_stream;
+	DisposeAfterUse::Flag _disposeAfterUse;
+	byte _shiftLeft;
+	byte _shiftRight;
+	uint32 _pos;
+	Audio::Timestamp _length;
+
+public:
+	CDDAStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);
+	virtual ~CDDAStream();
+	
+	int readBuffer(int16 *buffer, const int numSamples);
+	bool isStereo() const { return true; }
+	int getRate() const { return 44100; }
+	bool endOfData() const { return _stream->eos(); }
+	bool seek(const Audio::Timestamp &where);
+	Audio::Timestamp getLength() const { return _length; }
+};
+
+CDDAStream::CDDAStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) :
+	_stream(stream), _disposeAfterUse(disposeAfterUse), _pos(START_OF_CDDA_DATA) {
+	_stream->seek(START_OF_CDDA_DATA, SEEK_SET);
+	// The total size of CDDA.SOU is 289,808,802 bytes or (289808802 - 800) / 1177 = 246226 blocks
+	// We also deduct the shift values to return the correct length
+	uint32 blocks = (_stream->size() - START_OF_CDDA_DATA) / BLOCK_SIZE;
+	_length = Audio::Timestamp(0, (_stream->size() - START_OF_CDDA_DATA - blocks) / (isStereo() ? 2 : 1), getRate());
+}
+
+CDDAStream::~CDDAStream() {
+	if (_disposeAfterUse == DisposeAfterUse::YES)
+		delete _stream;
+}
+
+bool CDDAStream::seek(const Audio::Timestamp &where) {
+	const uint32 seekSample = convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
+	uint32 blocks = seekSample / 1176;
+
+	// Before seeking, read the shift values from the beginning of that block
+	_stream->seek(START_OF_CDDA_DATA + blocks * BLOCK_SIZE, SEEK_SET);
+	byte shiftVal = _stream->readByte();
+	_shiftLeft = shiftVal >> 4;
+	_shiftRight = shiftVal & 0x0F;
+
+	_pos = START_OF_CDDA_DATA + blocks + seekSample;
+	return _stream->seek(_pos, SEEK_SET);
+}
+
+int CDDAStream::readBuffer(int16 *buffer, const int numSamples) {
+	int samples;
+
+	for (samples = 0 ; samples < numSamples && !_stream->eos() ; ) {
+		if (!((_pos - START_OF_CDDA_DATA) % BLOCK_SIZE)) {
+			byte shiftVal = _stream->readByte();
+			_shiftLeft = shiftVal >> 4;
+			_shiftRight = shiftVal & 0x0F;
+			_pos++;
+		}
+		buffer[samples++] = _stream->readSByte() << _shiftLeft;
+		buffer[samples++] = _stream->readSByte() << _shiftRight;
+		_pos += 2;
+	}
+	return samples;
+}
+
+#pragma mark -
+#pragma mark --- CDDA factory functions ---
+#pragma mark -
+
+Audio::SeekableAudioStream *makeCDDAStream(
+	Common::SeekableReadStream *stream,
+	DisposeAfterUse::Flag disposeAfterUse) {
+	Audio::SeekableAudioStream *s = new CDDAStream(stream, disposeAfterUse);
+	if (s && s->endOfData()) {
+		delete s;
+		return 0;
+	} else {
+		return s;
+	}
+	return 0;
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/cdda.h b/engines/scumm/cdda.h
new file mode 100644
index 0000000..2146777
--- /dev/null
+++ b/engines/scumm/cdda.h
@@ -0,0 +1,58 @@
+
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file
+ * CD audio decoder used in the Steam versions of Loom
+ */
+
+#ifndef SCUMM_CDDA_H
+#define SCUMM_CDDA_H
+
+#include "common/types.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Audio {
+class SeekableAudioStream;
+}
+
+namespace Scumm {
+
+/**
+ * Create a new SeekableAudioStream from the CDDA data in the given stream.
+ * Allows for seeking (which is why we require a SeekableReadStream).
+ *
+ * @param stream			the SeekableReadStream from which to read the CDDA data
+ * @param disposeAfterUse	whether to delete the stream after use
+ * @return	a new SeekableAudioStream, or NULL, if an error occurred
+ */
+Audio::SeekableAudioStream *makeCDDAStream(
+	Common::SeekableReadStream *stream,
+	DisposeAfterUse::Flag disposeAfterUse);
+
+} // End of namespace Audio
+
+#endif // #ifndef SCUMM_CDDA_H
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index d43db1e..416a8f7 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
 	bomp.o \
 	boxes.o \
 	camera.o \
+	cdda.o \
 	charset.o \
 	charset-fontdata.o \
 	costume.o \
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 0aaff4c..7eadb04 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1453,7 +1453,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
 		// forever, then resume playing it. This helps a lot when the audio CD
 		// is used to provide ambient music (see bug #788195).
 		if (s->isLoading() && info.playing && info.numLoops < 0)
-			_system->getAudioCDManager()->play(info.track, info.numLoops, info.start, info.duration);
+			_sound->playCDTrackInternal(info.track, info.numLoops, info.start, info.duration);
 	}
 
 
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 01bdefc..21bf565 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -27,6 +27,7 @@
 #include "common/substream.h"
 
 #include "scumm/actor.h"
+#include "scumm/cdda.h"
 #include "scumm/file.h"
 #include "scumm/imuse/imuse.h"
 #include "scumm/imuse_digi/dimuse.h"
@@ -36,8 +37,6 @@
 #include "scumm/sound.h"
 #include "scumm/util.h"
 
-#include "backends/audiocd/audiocd.h"
-
 #include "audio/decoders/adpcm.h"
 #include "audio/decoders/flac.h"
 #include "audio/mididrv.h"
@@ -89,11 +88,21 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer)
 	memset(_mouthSyncTimes, 0, sizeof(_mouthSyncTimes));
 
 	_musicType = MDT_NONE;
+
+	_loomSteamCD.playing = false;
+	_loomSteamCD.track = 0;
+	_loomSteamCD.start = 0;
+	_loomSteamCD.duration = 0;
+	_loomSteamCD.numLoops = 0;
+	_loomSteamCD.volume = Audio::Mixer::kMaxChannelVolume;
+	_loomSteamCD.balance = 0;
+
+	_isLoomSteam = _vm->_game.id == GID_LOOM && Common::File::exists("CDDA.SOU");
 }
 
 Sound::~Sound() {
 	stopCDTimer();
-	g_system->getAudioCDManager()->stop();
+	stopCD();
 	free(_offsetTable);
 }
 
@@ -1033,7 +1042,7 @@ void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
 
 	// Play it
 	if (!_soundsPaused)
-		g_system->getAudioCDManager()->play(track, numLoops, startFrame, duration);
+		playCDTrackInternal(track, numLoops, startFrame, duration);
 
 	// Start the timer after starting the track. Starting an MP3 track is
 	// almost instantaneous, but a CD player may take some time. Hopefully
@@ -1041,16 +1050,59 @@ void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
 	startCDTimer();
 }
 
+void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int duration) {
+	_loomSteamCD.track = track;
+	_loomSteamCD.numLoops = numLoops;
+	_loomSteamCD.start = startFrame;
+	_loomSteamCD.duration = duration;
+
+	if (!_isLoomSteam) {
+		g_system->getAudioCDManager()->play(track, numLoops, startFrame, duration);
+	} else {
+		// Stop any currently playing track
+		_mixer->stopHandle(_loomSteamCDAudioHandle);
+
+		Common::File *cddaFile = new Common::File();
+		if (cddaFile->open("CDDA.SOU")) {
+			Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
+			Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);				
+			Audio::SeekableAudioStream *stream = makeCDDAStream(cddaFile, DisposeAfterUse::YES);
+			
+			_mixer->playStream(Audio::Mixer::kMusicSoundType, &_loomSteamCDAudioHandle,
+			                    Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
+		} else {
+			delete cddaFile;
+		}
+	}
+}
+
 void Sound::stopCD() {
-	g_system->getAudioCDManager()->stop();
+	if (!_isLoomSteam)
+		g_system->getAudioCDManager()->stop();
+	else
+		_mixer->stopHandle(_loomSteamCDAudioHandle);
 }
 
 int Sound::pollCD() const {
-	return g_system->getAudioCDManager()->isPlaying();
+	if (!_isLoomSteam)
+		return g_system->getAudioCDManager()->isPlaying();
+	else
+		return _mixer->isSoundHandleActive(_loomSteamCDAudioHandle);
 }
 
 void Sound::updateCD() {
-	g_system->getAudioCDManager()->updateCD();
+	if (!_isLoomSteam)
+		g_system->getAudioCDManager()->updateCD();
+}
+
+AudioCDManager::Status Sound::getCDStatus() {
+	if (!_isLoomSteam)
+		return g_system->getAudioCDManager()->getStatus();
+	else {
+		AudioCDManager::Status info = _loomSteamCD;
+		_loomSteamCD.playing = _mixer->isSoundHandleActive(_loomSteamCDAudioHandle);
+		return info;
+	}
 }
 
 void Sound::saveLoadWithSerializer(Serializer *ser) {
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index a96d2b8..a479ad5 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -27,6 +27,7 @@
 #include "audio/audiostream.h"
 #include "audio/mididrv.h"
 #include "audio/mixer.h"
+#include "backends/audiocd/audiocd.h"
 #include "scumm/saveload.h"
 
 namespace Audio {
@@ -86,6 +87,10 @@ protected:
 	int16 _currentCDSound;
 	int16 _currentMusic;
 
+	Audio::SoundHandle _loomSteamCDAudioHandle;
+	bool _isLoomSteam;
+	AudioCDManager::Status _loomSteamCD;
+
 public:
 	Audio::SoundHandle _talkChannelHandle;	// Handle of mixer channel actor is talking on
 
@@ -119,9 +124,11 @@ public:
 	void stopCDTimer();
 
 	void playCDTrack(int track, int numLoops, int startFrame, int duration);
+	void playCDTrackInternal(int track, int numLoops, int startFrame, int duration);
 	void stopCD();
 	int pollCD() const;
 	void updateCD();
+	AudioCDManager::Status getCDStatus();
 	int getCurrentCDSound() const { return _currentCDSound; }
 
 	// Used by the save/load system:


Commit: b77412a9a07e58a21dd430e28cf34210d4648fd0
    https://github.com/scummvm/scummvm/commit/b77412a9a07e58a21dd430e28cf34210d4648fd0
Author: Johannes Schickel (lordhoto at gmail.com)
Date: 2014-07-05T13:35:34+02:00

Commit Message:
Merge pull request #470 from bluegr/Lucasarts_Steam

SCUMM: Add support for Steam versions of Indy 3, Indy 4, Loom and Dig

Changed paths:
  A engines/scumm/cdda.cpp
  A engines/scumm/cdda.h
    devtools/scumm-md5.txt
    engines/scumm/detection.cpp
    engines/scumm/detection.h
    engines/scumm/detection_tables.h
    engines/scumm/file.cpp
    engines/scumm/file.h
    engines/scumm/module.mk
    engines/scumm/saveload.cpp
    engines/scumm/scumm-md5.h
    engines/scumm/scumm.cpp
    engines/scumm/sound.cpp
    engines/scumm/sound.h









More information about the Scummvm-git-logs mailing list