[Scummvm-git-logs] scummvm master -> 5661a8b4a2db5a009cb0ead99d111acfca92584a
bluegr
noreply at scummvm.org
Fri Dec 20 11:21:01 UTC 2024
This automated email contains information about 19 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6a0965c239 SCUMM: Add support for reading files from DoubleFine PAK files
15fcc87ba8 SCUMM: Hook the new Doublefine PAK file handler
e9400af000 SCUMM: Hook up the new PAK file handler in the sound code
d2d08511b8 SCUMM: Hook up the PAK file manager in INSANE, NUT and SMUSH code
3daad8f5f1 SCUMM: Add SE variants for classic versions of MI1, MI2, DOTT and FT
8dba3ecdbf SCUMM: Use a 64-bit integer for file sizes of detection entries
28889be3d5 SCUMM: Add entries for the SE versions of MI1, MI2, DOTT and FT
3b7e4ac7d6 SCUMM: Add support for SMUSH subtitles in PAK files
a318189cf6 SCUMM: Simplify instantiation of the Doublefine file handler
808fc410f3 SCUMM: Add support for the MM easter egg variant in the DOTT SE version
0cbba7c029 SCUMM: Some renaming for the Loom CD related code
a3d3720f33 SCUMM: Add audio directory for the DoubleFine versions of MI1 and MI2
7b33acb96a SCUMM: Don't warn about missing audio CD tracks for Doublefine MI1
90091e3afb SCUMM: Initial support for XWB audio containers for DoubleFine MI1+MI2
f8a532cfd7 SCUMM: Fix DoubleFine XWB PCM and ADPCM streams. Some cleanup
13a3eca146 SCUMM: Encapsulate the new Doublefine SE sound code in a separate class
b628296f3f SCUMM: Remove obsolete define and TODO
43c06db34a SCUMM: Cleanup WMA codec error handling
5661a8b4a2 SCUMM: Add checksum for the GoG version of DOTT Remastered
Commit: 6a0965c239862d040696e4f59895c780307d7875
https://github.com/scummvm/scummvm/commit/6a0965c239862d040696e4f59895c780307d7875
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add support for reading files from DoubleFine PAK files
This will be used when reading the files of the classic versions found in
the DoubleFine remasters. Since the Full Throttle package is over 4GB,
we have adapted the internal sub file range code to use 64-bit integers
for file locations
The implementation is based on the work done in DoubleFine Explorer:
https://github.com/bgbennyboy/DoubleFine-Explorer/blob/master/uDFExplorer_LPAKManager.pas
Changed paths:
engines/scumm/file.cpp
engines/scumm/file.h
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 41c2f88f8bd..5c9962883a2 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -40,9 +40,9 @@ void BaseScummFile::close() {
ScummFile::ScummFile(const ScummEngine *vm) : _subFileStart(0), _subFileLen(0), _myEos(false), _isMac(vm->_game.platform == Common::kPlatformMacintosh) {
}
-void ScummFile::setSubfileRange(int32 start, int32 len) {
+void ScummFile::setSubfileRange(int64 start, int32 len) {
// TODO: Add sanity checks
- const int32 fileSize = _baseStream->size();
+ const int64 fileSize = _baseStream->size();
assert(start <= fileSize);
assert(start + len <= fileSize);
_subFileStart = start;
@@ -155,7 +155,7 @@ bool ScummFile::seek(int64 offs, int whence) {
offs += _baseStream->pos();
break;
}
- assert((int32)_subFileStart <= offs && offs <= (int32)(_subFileStart + _subFileLen));
+ assert(_subFileStart <= offs && offs <= _subFileStart + _subFileLen);
whence = SEEK_SET;
}
bool ret = _baseStream->seek(offs, whence);
@@ -218,6 +218,86 @@ bool ScummSteamFile::openWithSubRange(const Common::Path &filename, int32 subFil
}
}
+#pragma mark -
+#pragma mark--- ScummPAKFile ---
+#pragma mark -
+
+ScummPAKFile::ScummPAKFile(const ScummEngine *vm, bool indexFiles) : ScummFile(vm) {
+ if (!indexFiles)
+ return;
+
+ ScummFile::open(vm->_containerFile);
+
+ const uint32 magic = _baseStream->readUint32BE();
+ const bool isFT = vm->_game.id == GID_FT;
+ const byte recordSize = isFT ? 24 : 20;
+
+ if (magic != MKTAG('K', 'A', 'P', 'L')) {
+ warning("ScummPAKFile: invalid PAK file");
+ return;
+ }
+
+ _baseStream->skip(4); // skip version
+
+ if (!isFT)
+ _baseStream->skip(4); // skip start of index
+
+ const uint32 fileEntriesOffset = _baseStream->readUint32LE();
+
+ if (isFT)
+ _baseStream->skip(4); // skip start of index
+
+ const uint32 fileNamesOffset = _baseStream->readUint32LE();
+ const uint32 dataOffset = _baseStream->readUint32LE();
+ _baseStream->skip(4); // skip size of index
+ const uint32 fileEntriesLength = _baseStream->readUint32LE();
+
+ const uint32 fileCount = fileEntriesLength / recordSize;
+ uint32 curNameOffset = 0;
+
+ for (uint32 i = 0; i < fileCount; i++) {
+ PAKFile pakFile;
+
+ _baseStream->seek(fileEntriesOffset + i * recordSize, SEEK_SET);
+ pakFile.start = !isFT ? _baseStream->readUint32LE() : _baseStream->readUint64LE();
+ pakFile.start += dataOffset;
+ _baseStream->skip(4); // skip file name offset
+ pakFile.len = _baseStream->readUint32LE();
+
+ _baseStream->seek(fileNamesOffset + curNameOffset, SEEK_SET);
+ Common::String fileName = _baseStream->readString();
+ curNameOffset += fileName.size() + 1;
+
+ // We only want to index the files of the classic versions
+ // FT data and video folders are located in the root folder
+ if (fileName.hasPrefixIgnoreCase("classic/") ||
+ fileName.hasPrefixIgnoreCase("data/") ||
+ fileName.hasPrefixIgnoreCase("video/")) {
+ // Remove the directory prefix
+ fileName = fileName.substr(fileName.findLastOf("/") + 1);
+ fileName.toLowercase();
+ _pakIndex[fileName] = pakFile;
+ }
+ }
+
+ ScummFile::close();
+}
+
+bool ScummPAKFile::openSubFile(const Common::Path &filePath) {
+ assert(_baseStream);
+
+ Common::String fileName = filePath.toString();
+ fileName.toLowercase();
+
+ if (_pakIndex.contains(fileName)) {
+ PAKFile pakFile = _pakIndex[fileName];
+ setSubfileRange(pakFile.start, pakFile.len);
+ 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 d0d29d98f7b..3320a9ef0f0 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -62,12 +62,12 @@ public:
class ScummFile : public BaseScummFile {
protected:
- int32 _subFileStart;
+ int64 _subFileStart;
int32 _subFileLen;
bool _myEos; // Have we read past the end of the subfile?
bool _isMac;
- void setSubfileRange(int32 start, int32 len);
+ void setSubfileRange(int64 start, int32 len);
void resetSubfile();
public:
@@ -150,6 +150,24 @@ public:
bool open(const Common::Path &filename) override;
};
+struct PAKFile {
+ uint64 start;
+ uint32 len;
+};
+
+typedef Common::HashMap<Common::String, PAKFile> PAKFileHashMap;
+
+class ScummPAKFile : public ScummFile {
+private:
+ PAKFileHashMap _pakIndex;
+
+public:
+ ScummPAKFile(const ScummEngine *vm, bool indexFiles = true);
+ ~ScummPAKFile() override { _pakIndex.clear(); }
+
+ bool openSubFile(const Common::Path &filePath) override;
+};
+
} // End of namespace Scumm
#endif
Commit: 15fcc87ba88b82cb46849a4e269f61ae29090acd
https://github.com/scummvm/scummvm/commit/15fcc87ba88b82cb46849a4e269f61ae29090acd
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Hook the new Doublefine PAK file handler
With this, it's possible to handle the files of the MI1 and MI2
classic versions found in MI1 SE and MI2 SE
Changed paths:
engines/scumm/detection.h
engines/scumm/detection_internal.h
engines/scumm/scumm.cpp
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index d8c258efa48..fa59bc75a96 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -105,6 +105,7 @@ struct GameSettings {
enum FilenameGenMethod {
kGenDiskNum,
kGenDiskNumSteam,
+ kGenDiskNumPak,
kGenRoomNum,
kGenRoomNumSteam,
kGenHEMac,
@@ -204,8 +205,8 @@ enum GameFeatures {
GF_ULTIMATE_TALKIE = 1 << 18,
/**
- * HE99 games which were ported to a C++ codebase with HE99 opcodes
- * and several HE100 GFX/Wiz features.
+ * HE99 games which were ported to a C++ codebase with HE99 opcodes
+ * and several HE100 GFX/Wiz features.
*/
GF_HE_995 = 1 << 19
};
diff --git a/engines/scumm/detection_internal.h b/engines/scumm/detection_internal.h
index 6b4baf9c751..08225e9ccb4 100644
--- a/engines/scumm/detection_internal.h
+++ b/engines/scumm/detection_internal.h
@@ -91,6 +91,7 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename
break;
case kGenUnchanged:
+ case kGenDiskNumPak:
result = pattern;
break;
@@ -527,7 +528,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
if (tmp)
md5str = computeStreamMD5AsString(*tmp, kMD5FileSizeLimit);
if (!md5str.empty()) {
- int filesize = tmp->size();
+ int64 filesize = tmp->size();
d.md5 = md5str;
d.md5Entry = findInMD5Table(md5str.c_str());
@@ -554,7 +555,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
computeGameSettingsFromMD5(fslist, gfp, d.md5Entry, dr);
// Print some debug info.
- debugC(1, kDebugGlobalDetection, "SCUMM detector found matching file '%s' with MD5 %s, size %d\n",
+ debugC(1, kDebugGlobalDetection, "SCUMM detector found matching file '%s' with MD5 %s, size %ld\n",
file.c_str(), md5str.c_str(), filesize);
// Sanity check: We *should* have found a matching gameid/variant at this point.
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 088146aca51..71fadf89e94 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1155,6 +1155,28 @@ Common::Error ScummEngine::init() {
} else {
_fileHandle = new ScummSteamFile(this, *indexFile);
}
+ } else if (_filenamePattern.genMethod == kGenDiskNumPak) {
+ // Container files used in remastered/SE versions
+ _containerFile = _filenamePattern.pattern; // needs to be set before instantiating ScummPAKFile
+ _fileHandle = new ScummPAKFile(this);
+ _filenamePattern.genMethod = kGenDiskNum;
+
+ switch (_game.id) {
+ case GID_MONKEY:
+ _filenamePattern.pattern = "monkey1.%03d";
+ break;
+ case GID_MONKEY2:
+ _filenamePattern.pattern = "monkey2.%03d";
+ break;
+ case GID_TENTACLE:
+ _filenamePattern.pattern = "tentacle.%03d";
+ break;
+ case GID_FT:
+ _filenamePattern.pattern = "ft.la%d";
+ break;
+ default:
+ error("kGenDiskNumPak used with unsupported game");
+ }
} else {
// Regular access, no container file involved
_fileHandle = new ScummFile(this);
@@ -4014,7 +4036,7 @@ bool ScummEngine::startManiac() {
_saveLoadSlot = 100;
_saveTemporaryState = true;
- // Set up the chanined games to Maniac Mansion, and then back
+ // Set up the chained games to Maniac Mansion, and then back
// to the current game again with that save slot.
ChainedGamesMan.push(Common::move(maniacTarget));
ChainedGamesMan.push(ConfMan.getActiveDomainName(), 100);
Commit: e9400af000ed5b823b90b7e918e968ee1927b241
https://github.com/scummvm/scummvm/commit/e9400af000ed5b823b90b7e918e968ee1927b241
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Hook up the new PAK file handler in the sound code
We need to cache the location of monster.sou, otherwise we'll end up
reindexing the PAK file on every speech sound.
With this, the classic version of DOTT found in the remaster works
Changed paths:
engines/scumm/file.cpp
engines/scumm/file.h
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 5c9962883a2..9236e66acc6 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -298,6 +298,20 @@ bool ScummPAKFile::openSubFile(const Common::Path &filePath) {
}
}
+PAKFile *ScummPAKFile::getPAKFileIndex(Common::String fileName) {
+ fileName.toLowercase();
+
+ assert(_pakIndex.contains(fileName));
+
+ return &_pakIndex[fileName];
+}
+
+void ScummPAKFile::setPAKFileIndex(Common::String fileName, const PAKFile &pakFile) {
+ fileName.toLowercase();
+
+ _pakIndex[fileName] = pakFile;
+}
+
#pragma mark -
#pragma mark --- ScummDiskImage ---
#pragma mark -
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index 3320a9ef0f0..ddd895a9066 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -166,6 +166,8 @@ public:
~ScummPAKFile() override { _pakIndex.clear(); }
bool openSubFile(const Common::Path &filePath) override;
+ PAKFile *getPAKFileIndex(Common::String fileName);
+ void setPAKFileIndex(Common::String fileName, const PAKFile &pakFile);
};
} // End of namespace Scumm
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index c6a5622bd95..45fa5ae7ebb 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -708,7 +708,21 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
int totalOffset, soundSize, fileSize, headerTag, vctlBlockSize;
if (_vm->_voiceMode != 2) {
- file.reset(new ScummFile(_vm));
+ if (_vm->_containerFile.empty()) {
+ file.reset(new ScummFile(_vm));
+ } else {
+ // Don't read the index of the PAK file, as we cached the
+ // location and size of monster.sou, which is the only file
+ // we need at this point. We do this to avoid reading the
+ // whole PAK file index for each speech sound.
+ ScummPAKFile *pakFile = new ScummPAKFile(_vm, false);
+ PAKFile tmpPak;
+ tmpPak.start = _cachedSfxLocationInPak;
+ tmpPak.len = _cachedSfxLengthInPak;
+ pakFile->setPAKFileIndex(DEFAULT_SFX_FILE, tmpPak);
+ file.reset(pakFile);
+ }
+
if (!file)
error("startTalkSound: Out of memory");
@@ -825,7 +839,21 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
offset += 8;
}
- file.reset(new ScummFile(_vm));
+ if (_vm->_containerFile.empty()) {
+ file.reset(new ScummFile(_vm));
+ } else {
+ // Don't read the index of the PAK file, as we cached the
+ // location and size of monster.sou, which is the only file
+ // we need at this point. We do this to avoid reading the
+ // whole PAK file index for each speech sound.
+ ScummPAKFile *pakFile = new ScummPAKFile(_vm, false);
+ PAKFile tmpPak;
+ tmpPak.start = _cachedSfxLocationInPak;
+ tmpPak.len = _cachedSfxLengthInPak;
+ pakFile->setPAKFileIndex(DEFAULT_SFX_FILE, tmpPak);
+ file.reset(pakFile);
+ }
+
if (!file)
error("startTalkSound: Out of memory");
@@ -1188,7 +1216,7 @@ bool Sound::hasSfxFile() const
ScummFile *Sound::restoreDiMUSESpeechFile(const char *fileName) {
Common::ScopedPtr<ScummFile> file;
- file.reset(new ScummFile(_vm));
+ file.reset(_vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm));
if (!_vm->openFile(*file, fileName)) {
return NULL;
}
@@ -1285,6 +1313,19 @@ void Sound::setupSfxFile() {
}
}
}
+
+ // Handle SFX file for classic game versions packed within remastered ones
+ if (!_vm->_containerFile.empty()) {
+ ScummPAKFile pakFile(_vm);
+ if (_vm->openFile(pakFile, DEFAULT_SFX_FILE)) {
+ _soundMode = kVOCMode;
+ _sfxFilename = DEFAULT_SFX_FILE;
+
+ PAKFile tmpPak = *pakFile.getPAKFileIndex(DEFAULT_SFX_FILE);
+ _cachedSfxLocationInPak = tmpPak.start;
+ _cachedSfxLengthInPak = tmpPak.len;
+ }
+ }
}
if (_soundMode != kVOCMode) {
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 05227481632..354567214be 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -39,6 +39,8 @@
#define DIGI_SND_MODE_SFX 1
#define DIGI_SND_MODE_TALKIE 2
+#define DEFAULT_SFX_FILE "monster.sou"
+
namespace Audio {
class Mixer;
class SoundHandle;
@@ -87,6 +89,8 @@ protected:
SoundMode _soundMode;
MP3OffsetTable *_offsetTable; // For compressed audio
int _numSoundEffects; // For compressed audio
+ int64 _cachedSfxLocationInPak = -1; // For sfx files in pak files
+ int32 _cachedSfxLengthInPak = 0; // For sfx files in pak files
uint32 _queuedSfxOffset, _queuedTalkieOffset, _queuedSfxLen, _queuedTalkieLen;
byte _queuedSoundMode, _queuedSfxChannel;
Commit: d2d08511b895306b57796f56a3fc2da19ba2fe41
https://github.com/scummvm/scummvm/commit/d2d08511b895306b57796f56a3fc2da19ba2fe41
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Hook up the PAK file manager in INSANE, NUT and SMUSH code
With this, the files of the classic version of FT found in the
remastered version are now properly handled
Changed paths:
engines/scumm/insane/insane.cpp
engines/scumm/nut_renderer.cpp
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp
index 8d3deaa475c..566319d6d5a 100644
--- a/engines/scumm/insane/insane.cpp
+++ b/engines/scumm/insane/insane.cpp
@@ -611,14 +611,16 @@ int32 Insane::processKeyboard() {
}
void Insane::readFileToMem(const char *name, byte **buf) {
- ScummFile in(_vm);
+ ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
uint32 len;
- if (!_vm->openFile(in, name))
+ if (!_vm->openFile(*file, name))
error("Cannot open file %s", name);
- len = in.size();
+ len = file->size();
*buf = (byte *)malloc(len);
- in.read(*buf, len);
+ file->read(*buf, len);
+ file->close();
+ delete file;
}
void Insane::startVideo(const char *filename, int num, int argC, int frameRate,
diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp
index 223fcda612f..4ef3d7c10e2 100644
--- a/engines/scumm/nut_renderer.cpp
+++ b/engines/scumm/nut_renderer.cpp
@@ -101,21 +101,23 @@ void NutRenderer::codec21(byte *dst, const byte *src, int width, int height, int
}
void NutRenderer::loadFont(const char *filename) {
- ScummFile file(_vm);
- _vm->openFile(file, filename);
- if (!file.isOpen()) {
+ ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
+
+ _vm->openFile(*file, filename);
+ if (!file->isOpen()) {
error("NutRenderer::loadFont() Can't open font file: %s", filename);
}
- uint32 tag = file.readUint32BE();
+ uint32 tag = file->readUint32BE();
if (tag != MKTAG('A','N','I','M')) {
error("NutRenderer::loadFont() there is no ANIM chunk in font header");
}
- uint32 length = file.readUint32BE();
+ uint32 length = file->readUint32BE();
byte *dataSrc = new byte[length];
- file.read(dataSrc, length);
- file.close();
+ file->read(dataSrc, length);
+ file->close();
+ delete file;
if (READ_BE_UINT32(dataSrc) != MKTAG('A','H','D','R')) {
error("NutRenderer::loadFont() there is no AHDR chunk in font header");
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 2e54d0fe816..c814b4f5f40 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1023,7 +1023,7 @@ void SmushPlayer::parseNextFrame() {
if (_seekFile.size() > 0) {
delete _base;
- ScummFile *tmp = new ScummFile(_vm);
+ ScummFile *tmp = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
if (!g_scumm->openFile(*tmp, Common::Path(_seekFile)))
error("SmushPlayer: Unable to open file %s", _seekFile.c_str());
_base = tmp;
@@ -1190,13 +1190,15 @@ void SmushPlayer::unpause() {
void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 startFrame) {
// Verify the specified file exists
- ScummFile f(_vm);
- _vm->openFile(f, filename);
- if (!f.isOpen()) {
+ ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
+
+ _vm->openFile(*file, filename);
+ if (!file->isOpen()) {
warning("SmushPlayer::play() File not found %s", filename);
return;
}
- f.close();
+ file->close();
+ delete file;
_updateNeeded = false;
_warpNeeded = false;
@@ -1238,7 +1240,7 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
if (_insanity) {
// Seeking makes a mess of trying to sync the audio to
- // the sound. Synt to time instead.
+ // the sound. Sync to time instead.
now = _vm->_system->getMillis() - _pauseTime;
elapsed = now - _startTime;
} else if (_vm->_mixer->isSoundHandleActive(*_compressedFileSoundHandle)) {
Commit: 3daad8f5f1f8a09cab4c40583c4d05c100325880
https://github.com/scummvm/scummvm/commit/3daad8f5f1f8a09cab4c40583c4d05c100325880
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add SE variants for classic versions of MI1, MI2, DOTT and FT
These are found within the remastered/SE versions
Changed paths:
engines/scumm/detection_tables.h
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 4ec2c769c54..3a14e0dda63 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -193,11 +193,13 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR | GF_DEMO, Common::kPlatformDOS, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GAMEOPTION_ORIGINALGUI)},
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
- {"monkey", "Mac", 0, GID_MONKEY, 5, 0, MDT_MACINTOSH, 0, UNK, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION, GUIO_NOASPECT)},
+ {"monkey", "SE", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
+ {"monkey", "Mac", 0, GID_MONKEY, 5, 0, MDT_MACINTOSH, 0, UNK, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION, GUIO_NOASPECT)},
{"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GAMEOPTION_TRIM_FMTOWNS_TO_200_PIXELS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "SE Talkie", 0, GID_MONKEY, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_AUDIOTRACKS | GF_ULTIMATE_TALKIE, UNK, GUIO2(GUIO_RENDEREGA, GAMEOPTION_ORIGINALGUI)},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO5(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
+ {"monkey2", "SE", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO5(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"monkey2", "Demo", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_DEMO, UNK, GUIO2(GUIO_NOSPEECH, GAMEOPTION_ENHANCEMENTS)},
{"monkey2", "Amiga", 0, GID_MONKEY2, 5, 0, MDT_AMIGA, 0, Common::kPlatformAmiga, GUIO5(GUIO_NOSPEECH, GUIO_MIDIAMIGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"monkey2", "Mac", 0, GID_MONKEY2, 5, 0, MDT_MACINTOSH, 0, UNK, GUIO5(GUIO_NOSPEECH, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION, GUIO_NOASPECT)},
@@ -212,12 +214,14 @@ static const GameSettings gameVariantsTable[] = {
{"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO6(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GAMEOPTION_TRIM_FMTOWNS_TO_200_PIXELS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
+ {"tentacle", "SE", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO4(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO4(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"ft", "", 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
+ {"ft", "SE", 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
{"ft", "Demo", 0, GID_FT, 7, 0, MDT_NONE, GF_DEMO, UNK, GUIO3(GUIO_NOMIDI, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
{"dig", "", 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
@@ -437,10 +441,12 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "monkey", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 }, // EGA & VGA versions
{ "monkey", "monkey.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "monkey", "monkey1.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
+ { "monkey", "monkey1.pak", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "monkey", "monkeyk.%03d", kGenDiskNum, Common::JA_JPN, Common::kPlatformFMTowns, "FM-TOWNS" },
{ "monkey", "game.%03d", kGenDiskNum, UNK_LANG, Common::kPlatformSegaCD, "SEGA" }, // SegaCD
{ "monkey2", "monkey2.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
+ { "monkey2", "monkey2.pak", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "monkey2", "mi2demo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "atlantis", "atlantis.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
@@ -453,6 +459,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
{ "tentacle", "tentacle.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
+ { "tentacle", "tenta.cle", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "tentacle", "dottdemo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "tentacle", "Day of the Tentacle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "tentacle", "Day of the Tentacle Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -475,6 +482,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
{ "ft", "ft.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
+ { "ft", "full.data", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "ft", "ft.%03d", kGenDiskNum, UNK_LANG, UNK, "Demo" }, // Used by PC version of Full Throttle demo
{ "ft", "ftdemo.la%d", kGenDiskNum, UNK_LANG, UNK, "Demo" },
{ "ft", "Full Throttle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
Commit: 8dba3ecdbff9df00fdd1a9a38778aa118eaf0958
https://github.com/scummvm/scummvm/commit/8dba3ecdbff9df00fdd1a9a38778aa118eaf0958
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Use a 64-bit integer for file sizes of detection entries
Since the PAK files of the remastered versions of DOTT and FT are
very large, we need a 64-bit integer to hold their size
Changed paths:
devtools/md5table.cpp
engines/scumm/scumm-md5.h
diff --git a/devtools/md5table.cpp b/devtools/md5table.cpp
index 90221659998..9b1556e0828 100644
--- a/devtools/md5table.cpp
+++ b/devtools/md5table.cpp
@@ -146,7 +146,7 @@ static const char *c_header =
" const char *gameid;\n"
" const char *variant;\n"
" const char *extra;\n"
- " int32 filesize;\n"
+ " int64 filesize;\n"
" Common::Language language;\n"
" Common::Platform platform;\n"
"};\n"
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 801261e4a0e..ff9a2b2bdea 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -14,7 +14,7 @@ struct MD5Table {
const char *gameid;
const char *variant;
const char *extra;
- int32 filesize;
+ int64 filesize;
Common::Language language;
Common::Platform platform;
};
Commit: 28889be3d571ddfaebd72fa4c7909968786fffb9
https://github.com/scummvm/scummvm/commit/28889be3d571ddfaebd72fa4c7909968786fffb9
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add entries for the SE versions of MI1, MI2, DOTT and FT
We now support the classic versions of these game variants
Changed paths:
devtools/scumm-md5.txt
engines/scumm/scumm-md5.h
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 9a8f847ddbb..9848844327d 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -240,6 +240,7 @@ monkey The Secret of Monkey Island
8776caed014c321272af407c1502a2df 8955 en Mac Mac - Mac v2.4 Petr Maruska (#3295)
2d1e891fe52df707c30185e52c50cd92 8955 en DOS CD CD CD-ROM v2.3 Fingolfin
+ 190ab1effbfd186cda821b71a9732c7d 1242812968 en DOS SE SE SE Filippos Karapetis
aa8a0cb65f3afbbe2c14c3f9f92775a3 8955 fr DOS CD CD CD-ROM v2.3 Fingolfin, Andrej Sinicyn, Andrea Petrucci
305d3dd57c96c65b017bc70c8c7cfb5e 8955 de DOS CD CD CD-ROM v2.3 Fingolfin
da6269b18fcb08189c0aa9c95533cce2 8955 it DOS CD CD CD-ROM v2.3 Fingolfin, Andrej Sinicyn, Andrea Petrucci
@@ -285,6 +286,7 @@ monkey2 Monkey Island 2: LeChuck's Revenge
11ddf1fde76e3156eb3a38da213f484e -1 it Amiga Amiga - - Andrea Petrucci
6ea966b4d660c870b9ee790d1fbfc535 -1 es Amiga Amiga - - Andreas Bylund
3686cf8f89e102ececf4366e1d2c8126 11135 en DOS - - v1.0 11/21/91
+ d670454da245c19bef988a341c416e40 506101054 en DOS SE SE SE Filippos Karapetis
8e4ee4db46954bfe2912e259a16fad82 11135 fr DOS - - v1.0 21/12/91 Nicolas Sauzède, Andrea Petrucci
6886e5d08cee329b1f2e743ae2e3ceed 11135 de DOS - - v1.0D 17Feb92 Fingolfin
69ea626f1f87eecb78ea0d6c6b983a1d -1 it DOS - - - Andrea Petrucci
@@ -356,6 +358,7 @@ tentacle Day of the Tentacle
ae94f110a14ce71fc515d5b648827a8f 7932 es DOS Floppy Floppy - abnog, Andrea Petrucci
4167a92a1d46baa4f4127d918d561f88 7932 en All? - CD 1.6 Fingolfin
+ 64d07dec2bf0789c4f2a7b656cf5bb83 2731584777 en DOS SE SE Filippos Karapetis
8aa05d3cdb0e795436043f0546af2da2 7932 fr All? - CD - Andrea Petrucci
6e959d65358eedf9b68b81e304b97fa4 7932 de All? - CD - Fingolfin
4fbbe9f64b8bc547503a379a301183ce -1 it All? - CD - Andrea Petrucci
@@ -403,6 +406,7 @@ ft Full Throttle
41958e24d03181ff9a381a66d048a581 -1 br All? - - - Danilo E.S.
09820417db26687bb7fe0c83cc4c553b 19697 en All? - Version A - Fingolfin
60ba818dc3bede86d40357e3913f8505 19697 en All? - Version B - sev, Fingolfin
+ 3ad7672a6c4d190f0a08ea524f711dd6 5465581773 en DOS SE SE SE Filippos Karapetis
4bedb49943df95a9c900a5a82ccbe9de 19752 fr All? - - - cyx
8bdb0bf87b5e303dd35693afb9351215 -1 de All? - - - dhewg
55518cd73cf9c6d23ea29c51ee06bdfe -1 it All? - - - delfino
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index ff9a2b2bdea..06c8a824fad 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 Dec 11 19:08:57 2024
+ This file was generated by the md5table tool on Sun Dec 15 09:46:30 2024
DO NOT EDIT MANUALLY!
*/
@@ -105,6 +105,7 @@ static const MD5Table md5table[] = {
{ "1875b90fade138c9253a8e967007031a", "indy3", "VGA", "VGA", 6295, Common::EN_ANY, Common::kPlatformDOS },
{ "187d315f6b5168f68680dfe8c3d76a3e", "loom", "EGA", "EGA", 5748, Common::HE_ISR, Common::kPlatformDOS },
{ "1900e501a52fbf55bde6e4196f6d2aa6", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS },
+ { "190ab1effbfd186cda821b71a9732c7d", "monkey", "SE", "SE", 1242812968, Common::EN_ANY, Common::kPlatformDOS },
{ "19263586f749a560c1adf8b3393a9593", "socks", "HE 85", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", 14689, Common::EN_GRB, Common::kPlatformWindows },
{ "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "Mac", "CD", 11885, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -211,6 +212,7 @@ static const MD5Table md5table[] = {
{ "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", 228446581, Common::FR_FRA, Common::kPlatformMacintosh },
{ "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "", 2082, Common::DE_DEU, Common::kPlatformNES },
{ "3a988de37118873ad129246b452909c0", "maniac", "V2 Demo", "V2 Demo", 1988, Common::RU_RUS, Common::kPlatformDOS },
+ { "3ad7672a6c4d190f0a08ea524f711dd6", "ft", "SE", "SE", 5465581773, Common::EN_ANY, Common::kPlatformDOS },
{ "3ae7f002d9256b8bdf76aaf8a3a069f8", "freddi", "HE 100", "", 34837, Common::EN_ANY, Common::kPlatformWii },
{ "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", 12364, Common::HE_ISR, Common::kPlatformWindows },
{ "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", 9040, Common::EN_ANY, Common::kPlatformDOS },
@@ -332,6 +334,7 @@ static const MD5Table md5table[] = {
{ "632d2fddb8ba97723fa15334763ae857", "thinker1", "", "", 33270, Common::EN_ANY, Common::kPlatformWindows },
{ "63fdcdc95cdeea00060883aed38e5504", "PuttTime", "HE 85", "", 62582, Common::EN_USA, Common::kPlatformUnknown },
{ "64a22be96d679018696e5c8d3ca8b71d", "freddi", "HE 73", "", 26375, Common::JA_JPN, Common::kPlatformWindows },
+ { "64d07dec2bf0789c4f2a7b656cf5bb83", "tentacle", "SE", "SE", 2731584777, Common::EN_ANY, Common::kPlatformDOS },
{ "6508fd55530e6915507e1cc37f7f045d", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformDOS },
{ "65563295c3a06493351870f20a1630cf", "spyozon", "HE CUP", "Preview", 5235008, Common::UNK_LANG, Common::kPlatformUnknown },
{ "659942b9a6b519f123a13cca3c333a13", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -673,6 +676,7 @@ static const MD5Table md5table[] = {
{ "d62047a6729349ab36f7ee065bf26509", "dig", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "d62d248c3df6ec177405e2cb23d923b2", "indy3", "EGA", "EGA", 5361, Common::IT_ITA, Common::kPlatformDOS },
{ "d6334a5a9b61afe18c368540fdf522ca", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "d670454da245c19bef988a341c416e40", "monkey2", "SE", "SE", 506101054, Common::EN_ANY, Common::kPlatformDOS },
{ "d6dd0646404768a63e963891a96daadd", "atlantis", "Mac Floppy", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh },
{ "d73c851b942af44deb9b6d5f416a0972", "freddi3", "HE 99", "Demo", 22779, Common::HE_ISR, Common::kPlatformWindows },
{ "d74122362a77ec24525fdd50297dfd82", "freddi4", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
Commit: 3b7e4ac7d68d08ef8ba42b8d7ee4335d8b71e753
https://github.com/scummvm/scummvm/commit/3b7e4ac7d68d08ef8ba42b8d7ee4335d8b71e753
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add support for SMUSH subtitles in PAK files
Now, subtitles in FT videos are displayed correctly
Changed paths:
engines/scumm/file.cpp
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 9236e66acc6..7e27ec4736f 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -268,11 +268,13 @@ ScummPAKFile::ScummPAKFile(const ScummEngine *vm, bool indexFiles) : ScummFile(v
Common::String fileName = _baseStream->readString();
curNameOffset += fileName.size() + 1;
- // We only want to index the files of the classic versions
+ // We only want to index the files of the classic versions.
// FT data and video folders are located in the root folder
if (fileName.hasPrefixIgnoreCase("classic/") ||
fileName.hasPrefixIgnoreCase("data/") ||
- fileName.hasPrefixIgnoreCase("video/")) {
+ fileName.hasPrefixIgnoreCase("video/") ||
+ fileName.hasPrefixIgnoreCase("en/data/") || // TODO: Support non-English versions
+ fileName.hasPrefixIgnoreCase("en/video/")) { // TODO: Support non-English versions
// Remove the directory prefix
fileName = fileName.substr(fileName.findLastOf("/") + 1);
fileName.toLowercase();
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index c814b4f5f40..bd00a6340f8 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -182,17 +182,20 @@ public:
static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_encoded) {
debugC(DEBUG_SMUSH, "trying to read text resources from %s", file);
- ScummFile theFile(vm);
+ ScummFile *theFile = vm->_containerFile.empty() ? new ScummFile(vm) : new ScummPAKFile(vm);
- vm->openFile(theFile, file);
- if (!theFile.isOpen()) {
+ vm->openFile(*theFile, file);
+ if (!theFile->isOpen()) {
+ delete theFile;
return 0;
}
- int32 length = theFile.size();
+ int32 length = theFile->size();
char *filebuffer = new char [length + 1];
assert(filebuffer);
- theFile.read(filebuffer, length);
+ theFile->read(filebuffer, length);
filebuffer[length] = 0;
+ theFile->close();
+ delete theFile;
if (is_encoded && READ_BE_UINT32(filebuffer) == MKTAG('E','T','R','S')) {
assert(length > ETRS_HEADER_LENGTH);
Commit: a318189cf62153fb2a3f27ab4b7a2b533881cd9b
https://github.com/scummvm/scummvm/commit/a318189cf62153fb2a3f27ab4b7a2b533881cd9b
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Simplify instantiation of the Doublefine file handler
Add a game flag for Doublefine packed games, and simplify
the instantiation of the PAK file handler. This avoids
clashes with other packed games (e.g. the Mac version of DOTT)
Changed paths:
engines/scumm/detection.h
engines/scumm/detection_internal.h
engines/scumm/detection_tables.h
engines/scumm/insane/insane.cpp
engines/scumm/nut_renderer.cpp
engines/scumm/resource.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
engines/scumm/smush/smush_player.cpp
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index fa59bc75a96..2ff4a9f2bcf 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -105,7 +105,6 @@ struct GameSettings {
enum FilenameGenMethod {
kGenDiskNum,
kGenDiskNumSteam,
- kGenDiskNumPak,
kGenRoomNum,
kGenRoomNumSteam,
kGenHEMac,
@@ -208,7 +207,12 @@ enum GameFeatures {
* HE99 games which were ported to a C++ codebase with HE99 opcodes
* and several HE100 GFX/Wiz features.
*/
- GF_HE_995 = 1 << 19
+ GF_HE_995 = 1 << 19,
+
+ /**
+ * Games packed within Doublefine PAK containers.
+ */
+ GF_DOUBLEFINE_PAK = 1 << 20
};
enum ScummGameId {
diff --git a/engines/scumm/detection_internal.h b/engines/scumm/detection_internal.h
index 08225e9ccb4..4d3dde980a9 100644
--- a/engines/scumm/detection_internal.h
+++ b/engines/scumm/detection_internal.h
@@ -91,7 +91,6 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename
break;
case kGenUnchanged:
- case kGenDiskNumPak:
result = pattern;
break;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 3a14e0dda63..a31d12fc1c5 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -193,13 +193,13 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR | GF_DEMO, Common::kPlatformDOS, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GAMEOPTION_ORIGINALGUI)},
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
- {"monkey", "SE", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
+ {"monkey", "SE", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS | GF_DOUBLEFINE_PAK, UNK, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "Mac", 0, GID_MONKEY, 5, 0, MDT_MACINTOSH, 0, UNK, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION, GUIO_NOASPECT)},
{"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO6(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GAMEOPTION_TRIM_FMTOWNS_TO_200_PIXELS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"monkey", "SE Talkie", 0, GID_MONKEY, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_AUDIOTRACKS | GF_ULTIMATE_TALKIE, UNK, GUIO2(GUIO_RENDEREGA, GAMEOPTION_ORIGINALGUI)},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO5(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
- {"monkey2", "SE", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO5(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
+ {"monkey2", "SE", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_DOUBLEFINE_PAK, UNK, GUIO5(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"monkey2", "Demo", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_DEMO, UNK, GUIO2(GUIO_NOSPEECH, GAMEOPTION_ENHANCEMENTS)},
{"monkey2", "Amiga", 0, GID_MONKEY2, 5, 0, MDT_AMIGA, 0, Common::kPlatformAmiga, GUIO5(GUIO_NOSPEECH, GUIO_MIDIAMIGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"monkey2", "Mac", 0, GID_MONKEY2, 5, 0, MDT_MACINTOSH, 0, UNK, GUIO5(GUIO_NOSPEECH, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION, GUIO_NOASPECT)},
@@ -214,14 +214,14 @@ static const GameSettings gameVariantsTable[] = {
{"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO6(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GAMEOPTION_TRIM_FMTOWNS_TO_200_PIXELS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
- {"tentacle", "SE", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
+ {"tentacle", "SE", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY | GF_DOUBLEFINE_PAK, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO4(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO3(GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO4(GUIO_NOSPEECH, GUIO_RENDEREGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"ft", "", 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
- {"ft", "SE", 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
+ {"ft", "SE", 0, GID_FT, 7, 0, MDT_NONE, GF_DOUBLEFINE_PAK, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
{"ft", "Demo", 0, GID_FT, 7, 0, MDT_NONE, GF_DEMO, UNK, GUIO3(GUIO_NOMIDI, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
{"dig", "", 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO)},
@@ -441,12 +441,12 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "monkey", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 }, // EGA & VGA versions
{ "monkey", "monkey.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "monkey", "monkey1.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
- { "monkey", "monkey1.pak", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
+ { "monkey", "monkey1.pak", kGenUnchanged, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "monkey", "monkeyk.%03d", kGenDiskNum, Common::JA_JPN, Common::kPlatformFMTowns, "FM-TOWNS" },
{ "monkey", "game.%03d", kGenDiskNum, UNK_LANG, Common::kPlatformSegaCD, "SEGA" }, // SegaCD
{ "monkey2", "monkey2.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
- { "monkey2", "monkey2.pak", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
+ { "monkey2", "monkey2.pak", kGenUnchanged, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "monkey2", "mi2demo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "atlantis", "atlantis.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
@@ -459,7 +459,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "atlantis", "atlantis.%03d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
{ "tentacle", "tentacle.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
- { "tentacle", "tenta.cle", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
+ { "tentacle", "tenta.cle", kGenUnchanged, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "tentacle", "dottdemo.%03d", kGenDiskNum, UNK_LANG, UNK, 0 },
{ "tentacle", "Day of the Tentacle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "tentacle", "Day of the Tentacle Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -482,7 +482,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "dig", "dig.la%d", kGenDiskNumSteam, UNK_LANG, Common::kPlatformMacintosh, "Steam" },
{ "ft", "ft.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
- { "ft", "full.data", kGenDiskNumPak, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
+ { "ft", "full.data", kGenUnchanged, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one
{ "ft", "ft.%03d", kGenDiskNum, UNK_LANG, UNK, "Demo" }, // Used by PC version of Full Throttle demo
{ "ft", "ftdemo.la%d", kGenDiskNum, UNK_LANG, UNK, "Demo" },
{ "ft", "Full Throttle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp
index 566319d6d5a..5d8698ab3f9 100644
--- a/engines/scumm/insane/insane.cpp
+++ b/engines/scumm/insane/insane.cpp
@@ -611,7 +611,7 @@ int32 Insane::processKeyboard() {
}
void Insane::readFileToMem(const char *name, byte **buf) {
- ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
+ ScummFile *file = _vm->instantiateScummFile();
uint32 len;
if (!_vm->openFile(*file, name))
diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp
index 4ef3d7c10e2..31420030686 100644
--- a/engines/scumm/nut_renderer.cpp
+++ b/engines/scumm/nut_renderer.cpp
@@ -101,7 +101,7 @@ void NutRenderer::codec21(byte *dst, const byte *src, int width, int height, int
}
void NutRenderer::loadFont(const char *filename) {
- ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
+ ScummFile *file = _vm->instantiateScummFile();
_vm->openFile(*file, filename);
if (!file->isOpen()) {
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 7e97aa33534..e630e6b601f 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -182,6 +182,10 @@ void ScummEngine::readRoomsOffsets() {
}
}
+ScummFile *ScummEngine::instantiateScummFile(bool indexPAKFiles) {
+ return !(_game.features & GF_DOUBLEFINE_PAK) ? new ScummFile(this) : new ScummPAKFile(this, indexPAKFiles);
+}
+
bool ScummEngine::openFile(BaseScummFile &file, const Common::Path &filename, bool resourceFile) {
bool result = false;
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 71fadf89e94..d4079d71e5b 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1041,12 +1041,33 @@ Common::Error ScummEngine::init() {
// The kGenUnchanged method is only used for 'container files', i.e. files
// that contain the real game files bundled together in an archive format.
- // This is the case of the NES, v0 and Mac versions of certain games.
+ // This is the case of the DoubleFine, NES, v0 and Mac versions of certain games.
// Note: All of these can also occur in 'extracted' form, in which case they
// are treated like any other SCUMM game.
if (_filenamePattern.genMethod == kGenUnchanged) {
+ if (_game.platform == Common::kPlatformDOS && (_game.features & GF_DOUBLEFINE_PAK)) {
+ // Container files used in remastered/SE versions
+ _containerFile = _filenamePattern.pattern; // needs to be set before instantiating ScummPAKFile
+ _fileHandle = new ScummPAKFile(this);
+ _filenamePattern.genMethod = kGenDiskNum;
- if (_game.platform == Common::kPlatformNES) {
+ switch (_game.id) {
+ case GID_MONKEY:
+ _filenamePattern.pattern = "monkey1.%03d";
+ break;
+ case GID_MONKEY2:
+ _filenamePattern.pattern = "monkey2.%03d";
+ break;
+ case GID_TENTACLE:
+ _filenamePattern.pattern = "tentacle.%03d";
+ break;
+ case GID_FT:
+ _filenamePattern.pattern = "ft.la%d";
+ break;
+ default:
+ error("Unsupported Doublefine packed game");
+ }
+ } else if (_game.platform == Common::kPlatformNES) {
// We read data directly from NES ROM instead of extracting it with
// external tool
assert(_game.id == GID_MANIAC);
@@ -1155,28 +1176,6 @@ Common::Error ScummEngine::init() {
} else {
_fileHandle = new ScummSteamFile(this, *indexFile);
}
- } else if (_filenamePattern.genMethod == kGenDiskNumPak) {
- // Container files used in remastered/SE versions
- _containerFile = _filenamePattern.pattern; // needs to be set before instantiating ScummPAKFile
- _fileHandle = new ScummPAKFile(this);
- _filenamePattern.genMethod = kGenDiskNum;
-
- switch (_game.id) {
- case GID_MONKEY:
- _filenamePattern.pattern = "monkey1.%03d";
- break;
- case GID_MONKEY2:
- _filenamePattern.pattern = "monkey2.%03d";
- break;
- case GID_TENTACLE:
- _filenamePattern.pattern = "tentacle.%03d";
- break;
- case GID_FT:
- _filenamePattern.pattern = "ft.la%d";
- break;
- default:
- error("kGenDiskNumPak used with unsupported game");
- }
} else {
// Regular access, no container file involved
_fileHandle = new ScummFile(this);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index f2ff324684d..b9f53d322ca 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -40,6 +40,7 @@
#include "graphics/sjis.h"
#include "graphics/palette.h"
+#include "scumm/file.h"
#include "scumm/gfx.h"
#include "scumm/detection.h"
#include "scumm/script.h"
@@ -1089,6 +1090,7 @@ public:
Common::Path _macCursorFile;
bool openFile(BaseScummFile &file, const Common::Path &filename, bool resourceFile = false);
+ ScummFile *instantiateScummFile(bool indexPAKFiles = true);
protected:
int _resourceHeaderSize = 8;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index bd00a6340f8..efbc734d1f8 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -182,7 +182,7 @@ public:
static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_encoded) {
debugC(DEBUG_SMUSH, "trying to read text resources from %s", file);
- ScummFile *theFile = vm->_containerFile.empty() ? new ScummFile(vm) : new ScummPAKFile(vm);
+ ScummFile *theFile = vm->instantiateScummFile();
vm->openFile(*theFile, file);
if (!theFile->isOpen()) {
@@ -1026,8 +1026,8 @@ void SmushPlayer::parseNextFrame() {
if (_seekFile.size() > 0) {
delete _base;
- ScummFile *tmp = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
- if (!g_scumm->openFile(*tmp, Common::Path(_seekFile)))
+ ScummFile *tmp = _vm->instantiateScummFile();
+ if (!_vm->openFile(*tmp, Common::Path(_seekFile)))
error("SmushPlayer: Unable to open file %s", _seekFile.c_str());
_base = tmp;
_base->readUint32BE();
@@ -1193,7 +1193,7 @@ void SmushPlayer::unpause() {
void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 startFrame) {
// Verify the specified file exists
- ScummFile *file = _vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm);
+ ScummFile *file = _vm->instantiateScummFile();
_vm->openFile(*file, filename);
if (!file->isOpen()) {
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 45fa5ae7ebb..4ed03ab0518 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -708,20 +708,18 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
int totalOffset, soundSize, fileSize, headerTag, vctlBlockSize;
if (_vm->_voiceMode != 2) {
- if (_vm->_containerFile.empty()) {
- file.reset(new ScummFile(_vm));
- } else {
- // Don't read the index of the PAK file, as we cached the
- // location and size of monster.sou, which is the only file
- // we need at this point. We do this to avoid reading the
- // whole PAK file index for each speech sound.
- ScummPAKFile *pakFile = new ScummPAKFile(_vm, false);
+ // Don't read the index of the PAK file, as we cached the
+ // location and size of monster.sou, which is the only file
+ // we need at this point. We do this to avoid reading the
+ // whole PAK file index for each speech sound.
+ ScummFile *scummFile = _vm->instantiateScummFile(false);
+ if (_vm->_game.features & GF_DOUBLEFINE_PAK) {
PAKFile tmpPak;
tmpPak.start = _cachedSfxLocationInPak;
tmpPak.len = _cachedSfxLengthInPak;
- pakFile->setPAKFileIndex(DEFAULT_SFX_FILE, tmpPak);
- file.reset(pakFile);
+ dynamic_cast<ScummPAKFile *>(scummFile)->setPAKFileIndex(_sfxFilename, tmpPak);
}
+ file.reset(scummFile);
if (!file)
error("startTalkSound: Out of memory");
@@ -839,20 +837,18 @@ void Sound::startTalkSound(uint32 offset, uint32 length, int mode, Audio::SoundH
offset += 8;
}
- if (_vm->_containerFile.empty()) {
- file.reset(new ScummFile(_vm));
- } else {
- // Don't read the index of the PAK file, as we cached the
- // location and size of monster.sou, which is the only file
- // we need at this point. We do this to avoid reading the
- // whole PAK file index for each speech sound.
- ScummPAKFile *pakFile = new ScummPAKFile(_vm, false);
+ // Don't read the index of the PAK file, as we cached the
+ // location and size of monster.sou, which is the only file
+ // we need at this point. We do this to avoid reading the
+ // whole PAK file index for each speech sound.
+ ScummFile *scummFile = _vm->instantiateScummFile(false);
+ if (_vm->_game.features & GF_DOUBLEFINE_PAK) {
PAKFile tmpPak;
tmpPak.start = _cachedSfxLocationInPak;
tmpPak.len = _cachedSfxLengthInPak;
- pakFile->setPAKFileIndex(DEFAULT_SFX_FILE, tmpPak);
- file.reset(pakFile);
+ dynamic_cast<ScummPAKFile *>(scummFile)->setPAKFileIndex(_sfxFilename, tmpPak);
}
+ file.reset(scummFile);
if (!file)
error("startTalkSound: Out of memory");
@@ -1216,7 +1212,7 @@ bool Sound::hasSfxFile() const
ScummFile *Sound::restoreDiMUSESpeechFile(const char *fileName) {
Common::ScopedPtr<ScummFile> file;
- file.reset(_vm->_containerFile.empty() ? new ScummFile(_vm) : new ScummPAKFile(_vm));
+ file.reset(_vm->instantiateScummFile());
if (!_vm->openFile(*file, fileName)) {
return NULL;
}
@@ -1265,7 +1261,7 @@ void Sound::setupSfxFile() {
{ nullptr, kVOCMode }
};
- ScummFile file(_vm);
+ ScummFile *file = _vm->instantiateScummFile();
_offsetTable = nullptr;
_sfxFileEncByte = 0;
_sfxFilename.clear();
@@ -1294,7 +1290,7 @@ void Sound::setupSfxFile() {
tmp.appendInPlace("tlk");
}
- if (file.open(Common::Path(tmp)))
+ if (file->open(Common::Path(tmp)))
_sfxFilename = tmp.toString('/');
if (_vm->_game.heversion <= 74)
@@ -1302,30 +1298,25 @@ void Sound::setupSfxFile() {
_soundMode = kVOCMode;
} else {
- for (uint j = 0; j < 2 && !file.isOpen(); ++j) {
+ for (uint j = 0; j < 2 && !file->isOpen(); ++j) {
for (int i = 0; extensions[i].ext; ++i) {
tmp = basename[j];
tmp.appendInPlace(extensions[i].ext);
- if (_vm->openFile(file, tmp)) {
+ if (_vm->openFile(*file, tmp)) {
_soundMode = extensions[i].mode;
_sfxFilename = tmp.toString('/');
+
+ // Cache SFX file location for classic game versions
+ // packed within remastered ones
+ if (_vm->_game.features & GF_DOUBLEFINE_PAK) {
+ PAKFile *tmpPak = dynamic_cast<ScummPAKFile *>(file)->getPAKFileIndex(_sfxFilename);
+ _cachedSfxLocationInPak = tmpPak->start;
+ _cachedSfxLengthInPak = tmpPak->len;
+ }
break;
}
}
}
-
- // Handle SFX file for classic game versions packed within remastered ones
- if (!_vm->_containerFile.empty()) {
- ScummPAKFile pakFile(_vm);
- if (_vm->openFile(pakFile, DEFAULT_SFX_FILE)) {
- _soundMode = kVOCMode;
- _sfxFilename = DEFAULT_SFX_FILE;
-
- PAKFile tmpPak = *pakFile.getPAKFileIndex(DEFAULT_SFX_FILE);
- _cachedSfxLocationInPak = tmpPak.start;
- _cachedSfxLengthInPak = tmpPak.len;
- }
- }
}
if (_soundMode != kVOCMode) {
@@ -1345,21 +1336,24 @@ void Sound::setupSfxFile() {
*/
int size, compressed_offset;
MP3OffsetTable *cur;
- compressed_offset = file.readUint32BE();
+ compressed_offset = file->readUint32BE();
_offsetTable = (MP3OffsetTable *) malloc(compressed_offset);
_numSoundEffects = compressed_offset / 16;
size = compressed_offset;
cur = _offsetTable;
while (size > 0) {
- cur->org_offset = file.readUint32BE();
- cur->new_offset = file.readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */
- cur->num_tags = file.readUint32BE();
- cur->compressed_size = file.readUint32BE();
+ cur->org_offset = file->readUint32BE();
+ cur->new_offset = file->readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */
+ cur->num_tags = file->readUint32BE();
+ cur->compressed_size = file->readUint32BE();
size -= 4 * 4;
cur++;
}
}
+
+ file->close();
+ delete file;
}
bool Sound::isSfxFinished() const {
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 354567214be..e48aac25b85 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -39,8 +39,6 @@
#define DIGI_SND_MODE_SFX 1
#define DIGI_SND_MODE_TALKIE 2
-#define DEFAULT_SFX_FILE "monster.sou"
-
namespace Audio {
class Mixer;
class SoundHandle;
Commit: 808fc410f30eea940d0e7936a848337970782407
https://github.com/scummvm/scummvm/commit/808fc410f30eea940d0e7936a848337970782407
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add support for the MM easter egg variant in the DOTT SE version
Changed paths:
devtools/scumm-md5.txt
engines/scumm/detection_tables.h
engines/scumm/file.cpp
engines/scumm/scumm-md5.h
engines/scumm/scumm.cpp
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 9848844327d..21061920c93 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -73,6 +73,7 @@ maniac Maniac Mansion
be83e882b44f2767bc08d4f766ebc347 -1 de Atari V2 V2 - Joachim Eberhard
15240c59d3681ed53f714f8d925cb2d6 -1 es Atari V2 V2 - VooD
624cdb93654667c869d204a64af7e57f 1988 en DOS V2 V2 - Kirben, Andrea Petrucci
+ ff678e9ef8e4af2a37ca8658833c795a 1988 en DOS SE SE - Filippos Karapetis
b250d0f9cc83f80ced56fe11a4fb057c 1988 en DOS V2 V2 alt? Andrea Petrucci, Fingolfin
114acdc2659a273c220f86ee9edb24c1 -1 fr DOS V2 V2 - Nicolas Sauzède
99a3699f80b8f776efae592b44b9b991 1988 fr DOS V2 V2 from DOTT Nicolas Sauzède, Andrea Petrucci
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index a31d12fc1c5..cbe89be8f1f 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -161,6 +161,7 @@ static const GameSettings gameVariantsTable[] = {
{"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO5(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOASPECT, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI)},
{"maniac", "V2", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO9(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GUIO_RENDERAMIGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"maniac", "V2 Demo", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformDOS, GUIO7(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GUIO_RENDERAMIGA, GAMEOPTION_ORIGINALGUI)},
+ {"maniac", "SE", 0, GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, GF_DOUBLEFINE_PAK, Common::kPlatformDOS, GUIO9(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GUIO_RENDERAMIGA, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"zak", "V1", "v1", GID_ZAK, 1, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO9(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGABW, GUIO_RENDERCGACOMP, GUIO_RENDERCGA, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
{"zak", "V2", "v2", GID_ZAK, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO8(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_RENDERHERCGREEN, GUIO_RENDERHERCAMBER, GUIO_RENDERCGA, GUIO_RENDERAMIGA, GAMEOPTION_ORIGINALGUI, GAMEOPTION_COPY_PROTECTION)},
@@ -409,6 +410,7 @@ using Common::UNK_LANG;
static const GameFilenamePattern gameFilenamesTable[] = {
{ "maniac", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
{ "maniac", "%02d.MAN", kGenRoomNum, UNK_LANG, UNK, "V1 Demo" },
+ { "maniac", "dott.exe", kGenUnchanged, UNK_LANG, UNK, "SE" }, // Classic version within the remastered one. We don't really need this file, but it has to be different from DOTT's tenta.cle file
{ "maniac", "maniac1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64" }, // ... and maniac2.d64
{ "maniac", "maniac1.dsk", kGenUnchanged, UNK_LANG, Common::kPlatformApple2GS, "Apple II" }, // ... and maniac2.dsk
{ "maniac", "maniacdemo.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64 Demo" },
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 7e27ec4736f..9a79adb32cb 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -271,8 +271,9 @@ ScummPAKFile::ScummPAKFile(const ScummEngine *vm, bool indexFiles) : ScummFile(v
// We only want to index the files of the classic versions.
// FT data and video folders are located in the root folder
if (fileName.hasPrefixIgnoreCase("classic/") ||
- fileName.hasPrefixIgnoreCase("data/") ||
- fileName.hasPrefixIgnoreCase("video/") ||
+ fileName.hasPrefixIgnoreCase("maniac/") || // DOTT MM easter egg
+ fileName.hasPrefixIgnoreCase("data/") || // FT data folder
+ fileName.hasPrefixIgnoreCase("video/") || // FT video folder
fileName.hasPrefixIgnoreCase("en/data/") || // TODO: Support non-English versions
fileName.hasPrefixIgnoreCase("en/video/")) { // TODO: Support non-English versions
// Remove the directory prefix
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 06c8a824fad..740113cc3d7 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 Sun Dec 15 09:46:30 2024
+ This file was generated by the md5table tool on Sun Dec 15 22:58:56 2024
DO NOT EDIT MANUALLY!
*/
@@ -784,6 +784,7 @@ static const MD5Table md5table[] = {
{ "fe60d6b5ff51b0553ac59963123b5777", "comi", "", "", 76791, Common::UNK_LANG, Common::kPlatformWindows },
{ "febf4a983ea5faea1c9dd6c710ebb09c", "puttcircus", "", "", 36655, Common::DE_DEU, Common::kPlatformWindows },
{ "ff05c07990061d97647f059c48c1d05a", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAtariST },
+ { "ff678e9ef8e4af2a37ca8658833c795a", "maniac", "SE", "SE", 1988, Common::EN_ANY, Common::kPlatformDOS },
{ "ff90541cd06403ebea117274a3203c49", "baseball", "", "Steam", -1, Common::EN_ANY, Common::kPlatformWindows },
{ 0, 0, 0, 0, 0, Common::UNK_LANG, Common::kPlatformUnknown }
};
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index d4079d71e5b..6864c8b9d3a 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1048,6 +1048,8 @@ Common::Error ScummEngine::init() {
if (_game.platform == Common::kPlatformDOS && (_game.features & GF_DOUBLEFINE_PAK)) {
// Container files used in remastered/SE versions
_containerFile = _filenamePattern.pattern; // needs to be set before instantiating ScummPAKFile
+ if (_game.id == GID_MANIAC)
+ _containerFile = "tenta.cle";
_fileHandle = new ScummPAKFile(this);
_filenamePattern.genMethod = kGenDiskNum;
@@ -1064,6 +1066,10 @@ Common::Error ScummEngine::init() {
case GID_FT:
_filenamePattern.pattern = "ft.la%d";
break;
+ case GID_MANIAC:
+ _filenamePattern.pattern = "%.2d.LFL";
+ _filenamePattern.genMethod = kGenRoomNum;
+ break;
default:
error("Unsupported Doublefine packed game");
}
@@ -4007,11 +4013,13 @@ void ScummEngine_v90he::runBootscript() {
bool ScummEngine::startManiac() {
Common::Path currentPath = ConfMan.getPath("path");
+ Common::String gameId = ConfMan.get("gameid");
Common::String maniacTarget;
if (!ConfMan.hasKey("easter_egg")) {
// Look for a game with a game path pointing to a 'Maniac' directory
- // as a subdirectory to the current game.
+ // as a subdirectory to the current game. For the Double Fine SE version,
+ // we'll look for a game with the same path as the current game.
Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
for (; iter != ConfMan.endGameDomains(); ++iter) {
Common::ConfigManager::Domain &dom = iter->_value;
@@ -4023,6 +4031,16 @@ bool ScummEngine::startManiac() {
maniacTarget = iter->_key;
break;
}
+
+ // Since DOTT and MM are enclosed in the same PAK file, find
+ // a target with the same path as the current game and a game
+ // ID containing "maniac".
+ if (path.empty() && (_game.features & GF_DOUBLEFINE_PAK)) {
+ if (iter->_key != gameId && iter->_key.contains("maniac")) {
+ maniacTarget = iter->_key;
+ break;
+ }
+ }
}
}
} else {
Commit: 0cbba7c02994180f6c1f96982d9168a5eb4ae1a9
https://github.com/scummvm/scummvm/commit/0cbba7c02994180f6c1f96982d9168a5eb4ae1a9
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Some renaming for the Loom CD related code
No functional changes. This will be reused for the DoubleFine MI1 CD
audio functionality
Changed paths:
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 4ed03ab0518..ddded4f65f9 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -92,18 +92,18 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer, bool useReplacementAudioT
_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");
+ _fileBasedCDStatus.playing = false;
+ _fileBasedCDStatus.track = 0;
+ _fileBasedCDStatus.start = 0;
+ _fileBasedCDStatus.duration = 0;
+ _fileBasedCDStatus.numLoops = 0;
+ _fileBasedCDStatus.volume = Audio::Mixer::kMaxChannelVolume;
+ _fileBasedCDStatus.balance = 0;
+
+ _hasFileBasedCDAudio = _vm->_game.id == GID_LOOM && Common::File::exists("CDDA.SOU");
_loomOvertureTransition = DEFAULT_LOOM_OVERTURE_TRANSITION + ConfMan.getInt("loom_overture_ticks");
- _loomSteamCDAudioHandle = new Audio::SoundHandle();
+ _fileBasedCDAudioHandle = new Audio::SoundHandle();
_talkChannelHandle = new Audio::SoundHandle();
// This timer targets every talkie game, except for LOOM CD
@@ -118,7 +118,7 @@ Sound::~Sound() {
stopCDTimer();
stopCD();
free(_offsetTable);
- delete _loomSteamCDAudioHandle;
+ delete _fileBasedCDAudioHandle;
delete _talkChannelHandle;
if (_vm->_game.version >= 5 && _vm->_game.version <= 7 && _vm->_game.heversion == 0) {
stopSpeechTimer();
@@ -1414,7 +1414,7 @@ void Sound::startCDTimer() {
// LOOM Steam uses a fixed 240Hz rate. This was probably done to get rid of some
// audio glitches which are confirmed to be in the original. So let's activate this
// fix for the DOS version of LOOM as well, if enhancements are enabled.
- if (_isLoomSteam || (_vm->_game.id == GID_LOOM && _vm->enhancementEnabled(kEnhMinorBugFixes)))
+ if (_vm->_game.id == GID_LOOM && (_hasFileBasedCDAudio || _vm->enhancementEnabled(kEnhMinorBugFixes)))
interval = 1000000 / LOOM_STEAM_CDDA_RATE;
_vm->getTimerManager()->removeTimerProc(&cdTimerHandler);
@@ -1445,16 +1445,16 @@ void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
}
void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int duration) {
- _loomSteamCD.track = track;
- _loomSteamCD.numLoops = numLoops;
- _loomSteamCD.start = startFrame;
- _loomSteamCD.duration = duration;
+ _fileBasedCDStatus.track = track;
+ _fileBasedCDStatus.numLoops = numLoops;
+ _fileBasedCDStatus.start = startFrame;
+ _fileBasedCDStatus.duration = duration;
- if (!_isLoomSteam) {
+ if (!_hasFileBasedCDAudio) {
g_system->getAudioCDManager()->play(track, numLoops, startFrame, duration);
} else {
// Stop any currently playing track
- _mixer->stopHandle(*_loomSteamCDAudioHandle);
+ _mixer->stopHandle(*_fileBasedCDAudioHandle);
Common::File *cddaFile = new Common::File();
if (cddaFile->open("CDDA.SOU")) {
@@ -1462,7 +1462,7 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur
Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);
Audio::SeekableAudioStream *stream = makeCDDAStream(cddaFile, DisposeAfterUse::YES);
- _mixer->playStream(Audio::Mixer::kMusicSoundType, _loomSteamCDAudioHandle,
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, _fileBasedCDAudioHandle,
Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
} else {
delete cddaFile;
@@ -1471,30 +1471,30 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur
}
void Sound::stopCD() {
- if (!_isLoomSteam)
+ if (!_hasFileBasedCDAudio)
g_system->getAudioCDManager()->stop();
else
- _mixer->stopHandle(*_loomSteamCDAudioHandle);
+ _mixer->stopHandle(*_fileBasedCDAudioHandle);
}
int Sound::pollCD() const {
- if (!_isLoomSteam)
+ if (!_hasFileBasedCDAudio)
return g_system->getAudioCDManager()->isPlaying();
else
- return _mixer->isSoundHandleActive(*_loomSteamCDAudioHandle);
+ return _mixer->isSoundHandleActive(*_fileBasedCDAudioHandle);
}
void Sound::updateCD() {
- if (!_isLoomSteam)
+ if (!_hasFileBasedCDAudio)
g_system->getAudioCDManager()->update();
}
AudioCDManager::Status Sound::getCDStatus() {
- if (!_isLoomSteam)
+ if (!_hasFileBasedCDAudio)
return g_system->getAudioCDManager()->getStatus();
else {
- AudioCDManager::Status info = _loomSteamCD;
- info.playing = _mixer->isSoundHandleActive(*_loomSteamCDAudioHandle);
+ AudioCDManager::Status info = _fileBasedCDStatus;
+ info.playing = _mixer->isSoundHandleActive(*_fileBasedCDAudioHandle);
return info;
}
}
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index e48aac25b85..ef638aa334a 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -100,9 +100,9 @@ protected:
int16 _currentCDSound;
int16 _currentMusic;
- Audio::SoundHandle *_loomSteamCDAudioHandle;
- bool _isLoomSteam;
- AudioCDManager::Status _loomSteamCD;
+ Audio::SoundHandle *_fileBasedCDAudioHandle;
+ bool _hasFileBasedCDAudio;
+ AudioCDManager::Status _fileBasedCDStatus;
bool _useReplacementAudioTracks;
int _musicTimer;
int _loomOvertureTransition;
Commit: a3d3720f33fb47f70e73bb084c768db127c0ba82
https://github.com/scummvm/scummvm/commit/a3d3720f33fb47f70e73bb084c768db127c0ba82
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add audio directory for the DoubleFine versions of MI1 and MI2
Changed paths:
engines/scumm/scumm.cpp
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 6864c8b9d3a..312f2766d66 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -975,6 +975,11 @@ Common::Error ScummEngine::init() {
// This is for the Amiga version of Indy3/Loom/Maniac/Zak
SearchMan.addSubDirectoryMatching(gameDataDir, "rooms");
}
+
+ if ((_game.id == GID_MONKEY || _game.id == GID_MONKEY2) && (_game.features & GF_DOUBLEFINE_PAK)) {
+ // This is for the DoubleFine SE versions of Monkey Island 1 and 2
+ SearchMan.addSubDirectoryMatching(gameDataDir, "audio");
+ }
if ((_game.platform == Common::kPlatformMacintosh) && (_game.version == 3)) {
// This is for the Mac version of Indy3/Loom
Commit: 7b33acb96ab3784b8a56d0ad167f44047b107b10
https://github.com/scummvm/scummvm/commit/7b33acb96ab3784b8a56d0ad167f44047b107b10
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Don't warn about missing audio CD tracks for Doublefine MI1
The audio CD tracks in that version are handled as files
Changed paths:
engines/scumm/scumm.cpp
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 312f2766d66..a3efc1adda9 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1562,7 +1562,8 @@ void ScummEngine::setupScumm(const Common::Path &macResourceFile) {
// fallback with MIDI music when CD tracks are not found.
if (!existExtractedCDAudioFiles(track)
&& !isDataAndCDAudioReadFromSameCD()
- && !(_game.id == GID_MONKEY && _game.features & GF_ULTIMATE_TALKIE)) {
+ && !(_game.id == GID_MONKEY && _game.features & GF_ULTIMATE_TALKIE)
+ && !(_game.id == GID_MONKEY && _game.features & GF_DOUBLEFINE_PAK)) {
warnMissingExtractedCDAudio();
}
_system->getAudioCDManager()->open();
Commit: 90091e3afbd6367ad81cb8981bebf1e1f2339075
https://github.com/scummvm/scummvm/commit/90091e3afbd6367ad81cb8981bebf1e1f2339075
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Initial support for XWB audio containers for DoubleFine MI1+MI2
All the functionality is hooked in the same manner as the Loom Steam
CD audio code. It's still disabled though, since WMA decoding isn't
implemented yet.
There are three known audio formats in MI1 SE and MI2 SE:
- PCM (tested and working)
- WMA (missing implementation)
- MP3 (currently crashes)
Changed paths:
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index ddded4f65f9..c9880d174f9 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -106,6 +106,13 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer, bool useReplacementAudioT
_fileBasedCDAudioHandle = new Audio::SoundHandle();
_talkChannelHandle = new Audio::SoundHandle();
+#ifdef ENABLE_DOUBLEFINE_XWB
+ if (_vm->_game.id == GID_MONKEY && (_vm->_game.features & GF_DOUBLEFINE_PAK)) {
+ _hasFileBasedCDAudio = true;
+ indexXWBFile("MusicOriginal.xwb");
+ }
+#endif
+
// This timer targets every talkie game, except for LOOM CD
// which is handled differently, and except for COMI which
// handles lipsync within Digital iMUSE.
@@ -1444,6 +1451,37 @@ void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
startCDTimer();
}
+#ifdef ENABLE_DOUBLEFINE_XWB
+Audio::SeekableAudioStream *Sound::createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry) {
+ byte flags = Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS;
+ if (entry.channels == 2)
+ flags |= Audio::FLAG_STEREO;
+
+ switch (entry.codec) {
+ case kXWBCodecPCM:
+ return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
+ case kXWBCodecADPCM:
+ error("createXWBStream: ADPCM codec not supported");
+ case kXWBCodecMP3:
+#ifdef USE_MAD
+ return Audio::makeMP3Stream(stream, DisposeAfterUse::YES);
+#endif
+ case kXWBCodecWMA:
+ // TODO: Implement WMA stream
+ /*return new Audio::WMACodec(
+ 2,
+ entry.rate,
+ entry.channels,
+ entry.bits,
+ entry.align,
+ stream
+ );*/
+ default:
+ error("createXWBStream: Unknown XWB codec %d", entry.codec);
+ }
+}
+#endif
+
void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int duration) {
_fileBasedCDStatus.track = track;
_fileBasedCDStatus.numLoops = numLoops;
@@ -1456,17 +1494,44 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur
// Stop any currently playing track
_mixer->stopHandle(*_fileBasedCDAudioHandle);
- 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);
+ Common::File *cdAudioFile = new Common::File();
+ Audio::SeekableAudioStream *stream = nullptr;
- _mixer->playStream(Audio::Mixer::kMusicSoundType, _fileBasedCDAudioHandle,
- Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
- } else {
- delete cddaFile;
+ if (_vm->_game.id == GID_LOOM) {
+ if (!cdAudioFile->open("CDDA.SOU")) {
+ delete cdAudioFile;
+ return;
+ }
+ stream = makeCDDAStream(cdAudioFile, DisposeAfterUse::YES);
+
+#ifdef ENABLE_DOUBLEFINE_XWB
+ } else if (_vm->_game.id == GID_MONKEY) {
+ if (!cdAudioFile->open("MusicOriginal.xwb")) {
+ delete cdAudioFile;
+ return;
+ }
+
+ // HACK: Since we don't support WMA files yet, we'll just play a PCM entry
+ // TODO: Remove this, once WMA streams are supported!
+ track = 20;
+
+ XWBEntry entry = _xwbEntries[track];
+ auto subStream = new Common::SeekableSubReadStream(
+ cdAudioFile,
+ entry.offset,
+ entry.offset + entry.length,
+ DisposeAfterUse::YES
+ );
+
+ stream = createXWBStream(subStream, entry);
+#endif
}
+
+ Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
+ Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);
+
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, _fileBasedCDAudioHandle,
+ Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
}
}
@@ -1583,6 +1648,88 @@ bool Sound::isAudioDisabled() {
return false;
}
+#ifdef ENABLE_DOUBLEFINE_XWB
+void Sound::indexXWBFile(const Common::String &filename) {
+ // This implementation is based off unxwb: https://github.com/mariodon/unxwb/
+ // Only the parts that apply to the Doublefine releases of
+ // MI1 and MI2 have been implemented.
+
+ struct SegmentData {
+ uint32 offset;
+ uint32 length;
+ };
+ SegmentData segments[5] = {};
+
+ Common::File *f = new Common::File();
+ f->open(Common::Path(filename));
+
+ const uint32 magic = f->readUint32BE();
+ if (magic != MKTAG('W', 'B', 'N', 'D')) {
+ warning("Invalid XWB file");
+ f->close();
+ delete f;
+ return;
+ }
+
+ const uint32 version = f->readUint32LE();
+ if (version < 42) {
+ warning("Unsupported XWB version: %d", version);
+ f->close();
+ delete f;
+ return;
+ }
+
+ f->skip(4); // skip dwHeaderVersion
+
+ for (uint32 i = 0; i < 5; i++) {
+ segments[i].offset = f->readUint32LE();
+ segments[i].length = f->readUint32LE();
+ }
+
+ f->seek(segments[kXWBSegmentBankData].offset);
+ const uint32 flags = f->readUint32LE();
+ const uint32 entryCount = f->readUint32LE();
+ f->skip(64); // skip bank name
+ const uint32 entrySize = f->readUint32LE();
+ if (entrySize < 24) {
+ warning("Unsupported XWB entry size: %d", entrySize);
+ f->close();
+ delete f;
+ return;
+ }
+
+ if (flags & 0x00020000) {
+ warning("XWB compact format is not supported");
+ f->close();
+ delete f;
+ return;
+ }
+
+ f->seek(segments[kXWBSegmentEntryMetaData].offset);
+
+ for (uint32 i = 0; i < entryCount; i++) {
+ XWBEntry entry;
+ /*uint32 flagsAndDuration = */ f->readUint32LE();
+ uint32 format = f->readUint32LE();
+ entry.offset = f->readUint32LE() + segments[kXWBSegmentEntryWaveData].offset;
+ entry.length = f->readUint32LE();
+ /*uint32 loopOffset = */ f->readUint32LE();
+ /*uint32 loopLength = */ f->readUint32LE();
+
+ entry.codec = static_cast<XWBCodec>(format & ((1 << 2) - 1));
+ entry.channels = (format >> (2)) & ((1 << 3) - 1);
+ entry.rate = (format >> (2 + 3)) & ((1 << 18) - 1);
+ entry.align = (format >> (2 + 3 + 18)) & ((1 << 8) - 1);
+ entry.bits = (format >> (2 + 3 + 18 + 8)) & ((1 << 1) - 1);
+
+ _xwbEntries.push_back(entry);
+ }
+
+ f->close();
+ delete f;
+}
+#endif
+
#pragma mark -
#pragma mark --- Sound resource handling ---
#pragma mark -
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index ef638aa334a..a32f43dff4e 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -39,9 +39,14 @@
#define DIGI_SND_MODE_SFX 1
#define DIGI_SND_MODE_TALKIE 2
+namespace Common {
+class SeekableSubReadStream;
+}
+
namespace Audio {
class Mixer;
class SoundHandle;
+class SeekableAudioStream;
}
namespace Scumm {
@@ -54,6 +59,11 @@ enum {
kTalkSoundID = 10000
};
+// TODO: XWB audio packages, used in Doublefine MI1 and MI2.
+// We're still missing WMA support in SCUMM, so we can't play
+// the audio files contained in these packages.
+//#define ENABLE_DOUBLEFINE_XWB 1
+
// TODO: Consider splitting Sound into even more subclasses.
// E.g. for v1-v4, v5, v6+, ...
class Sound : public Common::Serializable {
@@ -182,6 +192,41 @@ protected:
virtual void processSoundQueues();
int getReplacementAudioTrack(int soundID);
+
+#ifdef ENABLE_DOUBLEFINE_XWB
+private:
+
+ // For XWB files in Doublefine game variants
+ enum XWBCodec {
+ kXWBCodecPCM = 0,
+ kXWBCodecADPCM = 1,
+ kXWBCodecMP3 = 2,
+ kXWBCodecWMA = 3
+ };
+
+ enum XWBSegmentType {
+ kXWBSegmentBankData = 0,
+ kXWBSegmentEntryMetaData = 1,
+ kXWBSegmentSeekTables = 2,
+ kXWBSegmentEntryNames = 3,
+ kXWBSegmentEntryWaveData = 4
+ };
+
+ struct XWBEntry {
+ uint32 offset;
+ uint32 length;
+ XWBCodec codec;
+ byte channels;
+ uint16 rate;
+ uint16 align;
+ byte bits;
+ };
+
+ Common::Array<XWBEntry> _xwbEntries;
+
+ void indexXWBFile(const Common::String &filename);
+ Audio::SeekableAudioStream *createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry);
+#endif
};
Commit: f8a532cfd76b19a07f811639b8bb42e23f42124c
https://github.com/scummvm/scummvm/commit/f8a532cfd76b19a07f811639b8bb42e23f42124c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Fix DoubleFine XWB PCM and ADPCM streams. Some cleanup
Now, speech and SFX in MI1SE and MI2SE, which use PCM and ADPCM, are
handled correctly. WMA audio is still not handled.
Changed paths:
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index c9880d174f9..1632f483faf 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -39,6 +39,7 @@
#include "audio/decoders/flac.h"
#include "audio/mididrv.h"
#include "audio/mixer.h"
+#include "audio/decoders/adpcm.h"
#include "audio/decoders/mp3.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/voc.h"
@@ -1451,37 +1452,6 @@ void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
startCDTimer();
}
-#ifdef ENABLE_DOUBLEFINE_XWB
-Audio::SeekableAudioStream *Sound::createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry) {
- byte flags = Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS;
- if (entry.channels == 2)
- flags |= Audio::FLAG_STEREO;
-
- switch (entry.codec) {
- case kXWBCodecPCM:
- return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
- case kXWBCodecADPCM:
- error("createXWBStream: ADPCM codec not supported");
- case kXWBCodecMP3:
-#ifdef USE_MAD
- return Audio::makeMP3Stream(stream, DisposeAfterUse::YES);
-#endif
- case kXWBCodecWMA:
- // TODO: Implement WMA stream
- /*return new Audio::WMACodec(
- 2,
- entry.rate,
- entry.channels,
- entry.bits,
- entry.align,
- stream
- );*/
- default:
- error("createXWBStream: Unknown XWB codec %d", entry.codec);
- }
-}
-#endif
-
void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int duration) {
_fileBasedCDStatus.track = track;
_fileBasedCDStatus.numLoops = numLoops;
@@ -1649,8 +1619,18 @@ bool Sound::isAudioDisabled() {
}
#ifdef ENABLE_DOUBLEFINE_XWB
+
+#define WARN_AND_RETURN_XWB(message) \
+ { \
+ warning("indexXWBFile: %s", message); \
+ f->close(); \
+ delete f; \
+ return; \
+ }
+
void Sound::indexXWBFile(const Common::String &filename) {
// This implementation is based off unxwb: https://github.com/mariodon/unxwb/
+ // as well as xwbdump: https://raw.githubusercontent.com/wiki/Microsoft/DirectXTK/xwbdump.cpp
// Only the parts that apply to the Doublefine releases of
// MI1 and MI2 have been implemented.
@@ -1664,23 +1644,15 @@ void Sound::indexXWBFile(const Common::String &filename) {
f->open(Common::Path(filename));
const uint32 magic = f->readUint32BE();
- if (magic != MKTAG('W', 'B', 'N', 'D')) {
- warning("Invalid XWB file");
- f->close();
- delete f;
- return;
- }
-
const uint32 version = f->readUint32LE();
- if (version < 42) {
- warning("Unsupported XWB version: %d", version);
- f->close();
- delete f;
- return;
- }
-
f->skip(4); // skip dwHeaderVersion
+ if (magic != MKTAG('W', 'B', 'N', 'D'))
+ WARN_AND_RETURN_XWB("Invalid XWB file")
+
+ if (version < 42)
+ WARN_AND_RETURN_XWB("Unsupported XWB version")
+
for (uint32 i = 0; i < 5; i++) {
segments[i].offset = f->readUint32LE();
segments[i].length = f->readUint32LE();
@@ -1691,19 +1663,11 @@ void Sound::indexXWBFile(const Common::String &filename) {
const uint32 entryCount = f->readUint32LE();
f->skip(64); // skip bank name
const uint32 entrySize = f->readUint32LE();
- if (entrySize < 24) {
- warning("Unsupported XWB entry size: %d", entrySize);
- f->close();
- delete f;
- return;
- }
+ if (entrySize < 24)
+ WARN_AND_RETURN_XWB("Unsupported XWB entry size")
- if (flags & 0x00020000) {
- warning("XWB compact format is not supported");
- f->close();
- delete f;
- return;
- }
+ if (flags & 0x00020000)
+ WARN_AND_RETURN_XWB("XWB compact format is not supported")
f->seek(segments[kXWBSegmentEntryMetaData].offset);
@@ -1728,6 +1692,51 @@ void Sound::indexXWBFile(const Common::String &filename) {
f->close();
delete f;
}
+
+#undef WARN_AND_RETURN_XWB
+
+Audio::SeekableAudioStream *Sound::createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry) {
+ switch (entry.codec) {
+ case kXWBCodecPCM: {
+ byte flags = Audio::FLAG_LITTLE_ENDIAN;
+ if (entry.bits == 1) // 0: 8 bits, 1: 16 bits
+ flags |= Audio::FLAG_16BITS;
+ if (entry.channels == 2)
+ flags |= Audio::FLAG_STEREO;
+ return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
+ }
+ case kXWBCodecXMA:
+ // Unused in MI1SE and MI2SE
+ error("createXWBStream: XMA codec not supported");
+ case kXWBCodecADPCM: {
+ const uint32 blockAlign = (entry.align + 22) * entry.channels;
+ return Audio::makeADPCMStream(
+ stream,
+ DisposeAfterUse::YES,
+ entry.length,
+ Audio::kADPCMMS,
+ entry.rate,
+ entry.channels,
+ blockAlign
+ );
+ }
+ case kXWBCodecWMA:
+ error("createXWBStream: WMA codec not implemented");
+ // TODO: Implement WMA codec
+ /*return new Audio::WMACodec(
+ 2,
+ entry.rate,
+ entry.channels,
+ entry.bits,
+ entry.align,
+ stream
+ );*/
+
+ }
+
+ error("createXWBStream: Unknown XWB codec %d", entry.codec);
+}
+
#endif
#pragma mark -
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index a32f43dff4e..242c08a9ed9 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -199,8 +199,8 @@ private:
// For XWB files in Doublefine game variants
enum XWBCodec {
kXWBCodecPCM = 0,
- kXWBCodecADPCM = 1,
- kXWBCodecMP3 = 2,
+ kXWBCodecXMA = 1,
+ kXWBCodecADPCM = 2,
kXWBCodecWMA = 3
};
Commit: 13a3eca146d7b6230020efda7b0a8fdf58bd6da5
https://github.com/scummvm/scummvm/commit/13a3eca146d7b6230020efda7b0a8fdf58bd6da5
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Encapsulate the new Doublefine SE sound code in a separate class
Also, change the Loom CDDA class so that it instantiates the CD audio
stream internally, to streamline and simplify the code in the Sound
class
Changed paths:
A engines/scumm/soundse.cpp
A engines/scumm/soundse.h
engines/scumm/cdda.cpp
engines/scumm/cdda.h
engines/scumm/module.mk
engines/scumm/sound.cpp
engines/scumm/sound.h
diff --git a/engines/scumm/cdda.cpp b/engines/scumm/cdda.cpp
index 113918b75c1..8f1785ce3bf 100644
--- a/engines/scumm/cdda.cpp
+++ b/engines/scumm/cdda.cpp
@@ -20,6 +20,7 @@
*/
#include "scumm/cdda.h"
+#include "common/file.h"
#include "common/stream.h"
#include "audio/audiostream.h"
@@ -104,16 +105,22 @@ int CDDAStream::readBuffer(int16 *buffer, const int numSamples) {
#pragma mark -
Audio::SeekableAudioStream *makeCDDAStream(
- Common::SeekableReadStream *stream,
+ const Common::String &filename,
DisposeAfterUse::Flag disposeAfterUse) {
- Audio::SeekableAudioStream *s = new CDDAStream(stream, disposeAfterUse);
+ Common::File *cdAudioFile = new Common::File();
+
+ if (!cdAudioFile->open(Common::Path(filename))) {
+ delete cdAudioFile;
+ return nullptr;
+ }
+
+ Audio::SeekableAudioStream *s = new CDDAStream(cdAudioFile, disposeAfterUse);
if (s && s->endOfData()) {
delete s;
return nullptr;
} else {
return s;
}
- return nullptr;
}
} // End of namespace Scumm
diff --git a/engines/scumm/cdda.h b/engines/scumm/cdda.h
index 5289113e986..1ba0a187fea 100644
--- a/engines/scumm/cdda.h
+++ b/engines/scumm/cdda.h
@@ -27,6 +27,7 @@
#ifndef SCUMM_CDDA_H
#define SCUMM_CDDA_H
+#include "common/str.h"
#include "common/types.h"
namespace Common {
@@ -43,12 +44,12 @@ 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 filename The file name 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,
+ const Common::String &filename,
DisposeAfterUse::Flag disposeAfterUse);
} // End of namespace Audio
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 6783741c648..46bc0a2019e 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -84,6 +84,7 @@ MODULE_OBJS := \
script.o \
scumm.o \
sound.o \
+ soundse.o \
string.o \
usage_bits.o \
util.o \
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 1632f483faf..be5e66757ec 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -107,12 +107,12 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer, bool useReplacementAudioT
_fileBasedCDAudioHandle = new Audio::SoundHandle();
_talkChannelHandle = new Audio::SoundHandle();
-#ifdef ENABLE_DOUBLEFINE_XWB
- if (_vm->_game.id == GID_MONKEY && (_vm->_game.features & GF_DOUBLEFINE_PAK)) {
- _hasFileBasedCDAudio = true;
- indexXWBFile("MusicOriginal.xwb");
+ if (_vm->_game.features & GF_DOUBLEFINE_PAK) {
+ _soundSE = new SoundSE(_vm, _mixer);
+
+ if (_vm->_game.id == GID_MONKEY)
+ _hasFileBasedCDAudio = true;
}
-#endif
// This timer targets every talkie game, except for LOOM CD
// which is handled differently, and except for COMI which
@@ -128,6 +128,7 @@ Sound::~Sound() {
free(_offsetTable);
delete _fileBasedCDAudioHandle;
delete _talkChannelHandle;
+ delete _soundSE;
if (_vm->_game.version >= 5 && _vm->_game.version <= 7 && _vm->_game.heversion == 0) {
stopSpeechTimer();
}
@@ -530,6 +531,13 @@ void Sound::triggerSound(int soundID) {
}
}
+ // TODO: If called from MI2SE, this will play the music
+ // multiple times
+ //if (_soundSE) {
+ // _soundSE->startMusic(soundID);
+ // return;
+ //}
+
if (_vm->_musicEngine)
_vm->_musicEngine->startSound(soundID);
@@ -1464,39 +1472,17 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur
// Stop any currently playing track
_mixer->stopHandle(*_fileBasedCDAudioHandle);
- Common::File *cdAudioFile = new Common::File();
Audio::SeekableAudioStream *stream = nullptr;
if (_vm->_game.id == GID_LOOM) {
- if (!cdAudioFile->open("CDDA.SOU")) {
- delete cdAudioFile;
- return;
- }
- stream = makeCDDAStream(cdAudioFile, DisposeAfterUse::YES);
-
-#ifdef ENABLE_DOUBLEFINE_XWB
- } else if (_vm->_game.id == GID_MONKEY) {
- if (!cdAudioFile->open("MusicOriginal.xwb")) {
- delete cdAudioFile;
- return;
- }
-
- // HACK: Since we don't support WMA files yet, we'll just play a PCM entry
- // TODO: Remove this, once WMA streams are supported!
- track = 20;
-
- XWBEntry entry = _xwbEntries[track];
- auto subStream = new Common::SeekableSubReadStream(
- cdAudioFile,
- entry.offset,
- entry.offset + entry.length,
- DisposeAfterUse::YES
- );
-
- stream = createXWBStream(subStream, entry);
-#endif
+ stream = makeCDDAStream("CDDA.SOU", DisposeAfterUse::YES);
+ } else if (_soundSE) {
+ stream = _soundSE->getXWBTrack(track);
}
+ if (!stream)
+ return;
+
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75);
@@ -1618,127 +1604,6 @@ bool Sound::isAudioDisabled() {
return false;
}
-#ifdef ENABLE_DOUBLEFINE_XWB
-
-#define WARN_AND_RETURN_XWB(message) \
- { \
- warning("indexXWBFile: %s", message); \
- f->close(); \
- delete f; \
- return; \
- }
-
-void Sound::indexXWBFile(const Common::String &filename) {
- // This implementation is based off unxwb: https://github.com/mariodon/unxwb/
- // as well as xwbdump: https://raw.githubusercontent.com/wiki/Microsoft/DirectXTK/xwbdump.cpp
- // Only the parts that apply to the Doublefine releases of
- // MI1 and MI2 have been implemented.
-
- struct SegmentData {
- uint32 offset;
- uint32 length;
- };
- SegmentData segments[5] = {};
-
- Common::File *f = new Common::File();
- f->open(Common::Path(filename));
-
- const uint32 magic = f->readUint32BE();
- const uint32 version = f->readUint32LE();
- f->skip(4); // skip dwHeaderVersion
-
- if (magic != MKTAG('W', 'B', 'N', 'D'))
- WARN_AND_RETURN_XWB("Invalid XWB file")
-
- if (version < 42)
- WARN_AND_RETURN_XWB("Unsupported XWB version")
-
- for (uint32 i = 0; i < 5; i++) {
- segments[i].offset = f->readUint32LE();
- segments[i].length = f->readUint32LE();
- }
-
- f->seek(segments[kXWBSegmentBankData].offset);
- const uint32 flags = f->readUint32LE();
- const uint32 entryCount = f->readUint32LE();
- f->skip(64); // skip bank name
- const uint32 entrySize = f->readUint32LE();
- if (entrySize < 24)
- WARN_AND_RETURN_XWB("Unsupported XWB entry size")
-
- if (flags & 0x00020000)
- WARN_AND_RETURN_XWB("XWB compact format is not supported")
-
- f->seek(segments[kXWBSegmentEntryMetaData].offset);
-
- for (uint32 i = 0; i < entryCount; i++) {
- XWBEntry entry;
- /*uint32 flagsAndDuration = */ f->readUint32LE();
- uint32 format = f->readUint32LE();
- entry.offset = f->readUint32LE() + segments[kXWBSegmentEntryWaveData].offset;
- entry.length = f->readUint32LE();
- /*uint32 loopOffset = */ f->readUint32LE();
- /*uint32 loopLength = */ f->readUint32LE();
-
- entry.codec = static_cast<XWBCodec>(format & ((1 << 2) - 1));
- entry.channels = (format >> (2)) & ((1 << 3) - 1);
- entry.rate = (format >> (2 + 3)) & ((1 << 18) - 1);
- entry.align = (format >> (2 + 3 + 18)) & ((1 << 8) - 1);
- entry.bits = (format >> (2 + 3 + 18 + 8)) & ((1 << 1) - 1);
-
- _xwbEntries.push_back(entry);
- }
-
- f->close();
- delete f;
-}
-
-#undef WARN_AND_RETURN_XWB
-
-Audio::SeekableAudioStream *Sound::createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry) {
- switch (entry.codec) {
- case kXWBCodecPCM: {
- byte flags = Audio::FLAG_LITTLE_ENDIAN;
- if (entry.bits == 1) // 0: 8 bits, 1: 16 bits
- flags |= Audio::FLAG_16BITS;
- if (entry.channels == 2)
- flags |= Audio::FLAG_STEREO;
- return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
- }
- case kXWBCodecXMA:
- // Unused in MI1SE and MI2SE
- error("createXWBStream: XMA codec not supported");
- case kXWBCodecADPCM: {
- const uint32 blockAlign = (entry.align + 22) * entry.channels;
- return Audio::makeADPCMStream(
- stream,
- DisposeAfterUse::YES,
- entry.length,
- Audio::kADPCMMS,
- entry.rate,
- entry.channels,
- blockAlign
- );
- }
- case kXWBCodecWMA:
- error("createXWBStream: WMA codec not implemented");
- // TODO: Implement WMA codec
- /*return new Audio::WMACodec(
- 2,
- entry.rate,
- entry.channels,
- entry.bits,
- entry.align,
- stream
- );*/
-
- }
-
- error("createXWBStream: Unknown XWB codec %d", entry.codec);
-}
-
-#endif
-
#pragma mark -
#pragma mark --- Sound resource handling ---
#pragma mark -
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 242c08a9ed9..5d481090deb 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -28,6 +28,7 @@
#include "audio/mididrv.h"
#include "backends/audiocd/audiocd.h"
#include "scumm/file.h"
+#include "scumm/soundse.h"
// The number of "ticks" (1/10th of a second) into the Overture that the
// LucasFilm logo should appear. This corresponds to a timer value of 204.
@@ -118,6 +119,8 @@ protected:
int _loomOvertureTransition;
uint32 _replacementTrackStartTime;
+ SoundSE *_soundSE = nullptr;
+
public:
Audio::SoundHandle *_talkChannelHandle; // Handle of mixer channel actor is talking on
@@ -192,41 +195,6 @@ protected:
virtual void processSoundQueues();
int getReplacementAudioTrack(int soundID);
-
-#ifdef ENABLE_DOUBLEFINE_XWB
-private:
-
- // For XWB files in Doublefine game variants
- enum XWBCodec {
- kXWBCodecPCM = 0,
- kXWBCodecXMA = 1,
- kXWBCodecADPCM = 2,
- kXWBCodecWMA = 3
- };
-
- enum XWBSegmentType {
- kXWBSegmentBankData = 0,
- kXWBSegmentEntryMetaData = 1,
- kXWBSegmentSeekTables = 2,
- kXWBSegmentEntryNames = 3,
- kXWBSegmentEntryWaveData = 4
- };
-
- struct XWBEntry {
- uint32 offset;
- uint32 length;
- XWBCodec codec;
- byte channels;
- uint16 rate;
- uint16 align;
- byte bits;
- };
-
- Common::Array<XWBEntry> _xwbEntries;
-
- void indexXWBFile(const Common::String &filename);
- Audio::SeekableAudioStream *createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry);
-#endif
};
diff --git a/engines/scumm/soundse.cpp b/engines/scumm/soundse.cpp
new file mode 100644
index 00000000000..fe75803191e
--- /dev/null
+++ b/engines/scumm/soundse.cpp
@@ -0,0 +1,250 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/timer.h"
+#include "common/util.h"
+#include "common/substream.h"
+
+#include "scumm/file.h"
+#include "scumm/scumm.h"
+#include "scumm/soundse.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/adpcm.h"
+#include "audio/decoders/mp3.h"
+#include "audio/decoders/raw.h"
+
+namespace Scumm {
+
+SoundSE::SoundSE(ScummEngine *parent, Audio::Mixer *mixer)
+ : _vm(parent),
+ _mixer(mixer) {
+
+ initSoundFiles();
+}
+
+void SoundSE::initSoundFiles() {
+ switch (_vm->_game.id) {
+ case GID_MONKEY:
+ case GID_MONKEY2:
+ _xwbMusicFilename = "MusicOriginal.xwb";
+ //_xwbMusicFilename = "MusicNew.xwb"; // TODO: allow toggle between original and new music
+ indexXWBFile(_xwbMusicFilename, &_xwbMusicEntries);
+ _xwbSfxFilename = "SFXOriginal.xwb";
+ //_xwbSfxFilename = "SFXNew.xwb"; // TODO: allow toggle between original and new SFX
+ indexXWBFile(_xwbSfxFilename, &_xwbSfxEntries);
+ _xwbSpeechFilename = "Speech.xwb";
+ indexXWBFile(_xwbSpeechFilename, &_xwbSpeechEntries);
+ break;
+ case GID_TENTACLE:
+ // TODO
+ break;
+ case GID_FT:
+ // TODO
+ break;
+ default:
+ error("initSoundFiles: unhandled game");
+ }
+}
+
+Audio::SeekableAudioStream *SoundSE::getXWBTrack(int track) {
+ Common::File *cdAudioFile = new Common::File();
+
+ if (!cdAudioFile->open(Common::Path(_xwbMusicFilename))) {
+ delete cdAudioFile;
+ return nullptr;
+ }
+
+ XWBEntry entry = _xwbMusicEntries[track];
+
+ // TODO: Remove this, once WMA streams are supported!
+ if (entry.codec == kXWBCodecWMA) {
+ delete cdAudioFile;
+ return nullptr;
+ }
+
+ auto subStream = new Common::SeekableSubReadStream(
+ cdAudioFile,
+ entry.offset,
+ entry.offset + entry.length,
+ DisposeAfterUse::YES
+ );
+
+ return createXWBStream(subStream, entry);
+}
+
+#define WARN_AND_RETURN_XWB(message) \
+ { \
+ warning("indexXWBFile: %s", message); \
+ f->close(); \
+ delete f; \
+ return; \
+ }
+
+void SoundSE::indexXWBFile(const Common::String &filename, XWBIndex *xwbIndex) {
+ // This implementation is based off unxwb: https://github.com/mariodon/unxwb/
+ // as well as xwbdump: https://raw.githubusercontent.com/wiki/Microsoft/DirectXTK/xwbdump.cpp
+ // Only the parts that apply to the Doublefine releases of
+ // MI1 and MI2 have been implemented.
+
+ struct SegmentData {
+ uint32 offset;
+ uint32 length;
+ };
+ SegmentData segments[5] = {};
+
+ Common::File *f = new Common::File();
+ f->open(Common::Path(filename));
+
+ const uint32 magic = f->readUint32BE();
+ const uint32 version = f->readUint32LE();
+ f->skip(4); // skip dwHeaderVersion
+
+ if (magic != MKTAG('W', 'B', 'N', 'D'))
+ WARN_AND_RETURN_XWB("Invalid XWB file")
+
+ if (version < 42)
+ WARN_AND_RETURN_XWB("Unsupported XWB version")
+
+ for (uint32 i = 0; i < 5; i++) {
+ segments[i].offset = f->readUint32LE();
+ segments[i].length = f->readUint32LE();
+ }
+
+ f->seek(segments[kXWBSegmentBankData].offset);
+ const uint32 flags = f->readUint32LE();
+ const uint32 entryCount = f->readUint32LE();
+ f->skip(64); // skip bank name
+ const uint32 entrySize = f->readUint32LE();
+ if (entrySize < 24)
+ WARN_AND_RETURN_XWB("Unsupported XWB entry size")
+
+ if (flags & 0x00020000)
+ WARN_AND_RETURN_XWB("XWB compact format is not supported")
+
+ f->seek(segments[kXWBSegmentEntryMetaData].offset);
+
+ for (uint32 i = 0; i < entryCount; i++) {
+ XWBEntry entry;
+ /*uint32 flagsAndDuration = */ f->readUint32LE();
+ uint32 format = f->readUint32LE();
+ entry.offset = f->readUint32LE() + segments[kXWBSegmentEntryWaveData].offset;
+ entry.length = f->readUint32LE();
+ /*uint32 loopOffset = */ f->readUint32LE();
+ /*uint32 loopLength = */ f->readUint32LE();
+
+ entry.codec = static_cast<XWBCodec>(format & ((1 << 2) - 1));
+ entry.channels = (format >> (2)) & ((1 << 3) - 1);
+ entry.rate = (format >> (2 + 3)) & ((1 << 18) - 1);
+ entry.align = (format >> (2 + 3 + 18)) & ((1 << 8) - 1);
+ entry.bits = (format >> (2 + 3 + 18 + 8)) & ((1 << 1) - 1);
+
+ xwbIndex->push_back(entry);
+ }
+
+ f->close();
+ delete f;
+}
+
+#undef WARN_AND_RETURN_XWB
+
+Audio::SeekableAudioStream *SoundSE::createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry) {
+ switch (entry.codec) {
+ case kXWBCodecPCM: {
+ byte flags = Audio::FLAG_LITTLE_ENDIAN;
+ if (entry.bits == 1) // 0: 8 bits, 1: 16 bits
+ flags |= Audio::FLAG_16BITS;
+ if (entry.channels == 2)
+ flags |= Audio::FLAG_STEREO;
+ return Audio::makeRawStream(stream, entry.rate, flags, DisposeAfterUse::YES);
+ }
+ case kXWBCodecXMA:
+ // Unused in MI1SE and MI2SE
+ error("createXWBStream: XMA codec not supported");
+ case kXWBCodecADPCM: {
+ const uint32 blockAlign = (entry.align + 22) * entry.channels;
+ return Audio::makeADPCMStream(
+ stream,
+ DisposeAfterUse::YES,
+ entry.length,
+ Audio::kADPCMMS,
+ entry.rate,
+ entry.channels,
+ blockAlign
+ );
+ }
+ case kXWBCodecWMA:
+ error("createXWBStream: WMA codec not implemented");
+ // TODO: Implement WMA codec
+ /*return new Audio::WMACodec(
+ 2,
+ entry.rate,
+ entry.channels,
+ entry.bits,
+ entry.align,
+ stream
+ );*/
+
+ }
+
+ error("createXWBStream: Unknown XWB codec %d", entry.codec);
+}
+
+#if 0
+void SoundSE::startMusic(int soundID) {
+ int entry = -1;
+
+ // HACK: Find the first entry with offset 8192 (MI2 theme)
+ // TODO: Map soundID to entry (*.xsb files)
+ for (int i = 0; i < _xwbMusicEntries.size(); i++) {
+ if (_xwbMusicEntries[i].offset == 8192) {
+ entry = i;
+ break;
+ }
+ }
+
+ if (entry == -1)
+ return;
+
+ Common::File *musicFile = new Common::File();
+
+ if (!musicFile->open(Common::Path(_xwbMusicFilename))) {
+ delete musicFile;
+ return;
+ }
+
+ XWBEntry xwbEntry = _xwbMusicEntries[entry];
+ Common::SeekableSubReadStream *stream = new Common::SeekableSubReadStream(
+ musicFile,
+ xwbEntry.offset,
+ xwbEntry.offset + xwbEntry.length,
+ DisposeAfterUse::YES
+ );
+
+ _mixer->playStream(
+ Audio::Mixer::kMusicSoundType,
+ &_musicHandle, createXWBStream(stream, xwbEntry)
+ );
+}
+#endif
+
+} // End of namespace Scumm
diff --git a/engines/scumm/soundse.h b/engines/scumm/soundse.h
new file mode 100644
index 00000000000..4540577c072
--- /dev/null
+++ b/engines/scumm/soundse.h
@@ -0,0 +1,103 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SCUMM_SOUNDSE_H
+#define SCUMM_SOUNDSE_H
+
+#include "common/scummsys.h"
+#include "audio/mixer.h"
+#include "scumm/file.h"
+
+namespace Common {
+class SeekableSubReadStream;
+}
+
+namespace Audio {
+class SeekableAudioStream;
+}
+
+namespace Scumm {
+
+class ScummEngine;
+
+class SoundSE {
+
+protected:
+ ScummEngine *_vm;
+ Audio::Mixer *_mixer;
+
+public:
+ SoundSE(ScummEngine *parent, Audio::Mixer *mixer);
+ ~SoundSE() = default;
+
+ Audio::SeekableAudioStream *getXWBTrack(int track);
+
+ //void startMusic(int soundID);
+
+private:
+ enum XWBCodec {
+ kXWBCodecPCM = 0,
+ kXWBCodecXMA = 1,
+ kXWBCodecADPCM = 2,
+ kXWBCodecWMA = 3
+ };
+
+ enum XWBSegmentType {
+ kXWBSegmentBankData = 0,
+ kXWBSegmentEntryMetaData = 1,
+ kXWBSegmentSeekTables = 2,
+ kXWBSegmentEntryNames = 3,
+ kXWBSegmentEntryWaveData = 4
+ };
+
+ struct XWBEntry {
+ uint32 offset;
+ uint32 length;
+ XWBCodec codec;
+ byte channels;
+ uint16 rate;
+ uint16 align;
+ byte bits;
+ };
+
+ typedef Common::Array<XWBEntry> XWBIndex;
+
+ XWBIndex _xwbMusicEntries;
+ Common::String _xwbMusicFilename;
+ Audio::SoundHandle _musicHandle;
+
+ XWBIndex _xwbSpeechEntries;
+ Common::String _xwbSpeechFilename;
+ Audio::SoundHandle _speechHandle;
+
+ XWBIndex _xwbSfxEntries;
+ Common::String _xwbSfxFilename;
+ Audio::SoundHandle _sfxHandle;
+
+ void initSoundFiles();
+ void indexXWBFile(const Common::String &filename, XWBIndex *xwbIndex);
+ Audio::SeekableAudioStream *createXWBStream(Common::SeekableSubReadStream *stream, XWBEntry entry);
+};
+
+
+} // End of namespace Scumm
+
+#endif
Commit: b628296f3f7e83958979b20764c13a68e2038043
https://github.com/scummvm/scummvm/commit/b628296f3f7e83958979b20764c13a68e2038043
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Remove obsolete define and TODO
Changed paths:
engines/scumm/sound.h
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 5d481090deb..ccc862006b6 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -60,11 +60,6 @@ enum {
kTalkSoundID = 10000
};
-// TODO: XWB audio packages, used in Doublefine MI1 and MI2.
-// We're still missing WMA support in SCUMM, so we can't play
-// the audio files contained in these packages.
-//#define ENABLE_DOUBLEFINE_XWB 1
-
// TODO: Consider splitting Sound into even more subclasses.
// E.g. for v1-v4, v5, v6+, ...
class Sound : public Common::Serializable {
Commit: 43c06db34acc247d35e4c002e94260a471112f03
https://github.com/scummvm/scummvm/commit/43c06db34acc247d35e4c002e94260a471112f03
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Cleanup WMA codec error handling
Changed paths:
engines/scumm/soundse.cpp
diff --git a/engines/scumm/soundse.cpp b/engines/scumm/soundse.cpp
index fe75803191e..9d2e0c97bde 100644
--- a/engines/scumm/soundse.cpp
+++ b/engines/scumm/soundse.cpp
@@ -76,12 +76,6 @@ Audio::SeekableAudioStream *SoundSE::getXWBTrack(int track) {
XWBEntry entry = _xwbMusicEntries[track];
- // TODO: Remove this, once WMA streams are supported!
- if (entry.codec == kXWBCodecWMA) {
- delete cdAudioFile;
- return nullptr;
- }
-
auto subStream = new Common::SeekableSubReadStream(
cdAudioFile,
entry.offset,
@@ -193,7 +187,6 @@ Audio::SeekableAudioStream *SoundSE::createXWBStream(Common::SeekableSubReadStre
);
}
case kXWBCodecWMA:
- error("createXWBStream: WMA codec not implemented");
// TODO: Implement WMA codec
/*return new Audio::WMACodec(
2,
@@ -203,7 +196,9 @@ Audio::SeekableAudioStream *SoundSE::createXWBStream(Common::SeekableSubReadStre
entry.align,
stream
);*/
-
+ warning("createXWBStream: WMA codec not implemented");
+ delete stream;
+ return nullptr;
}
error("createXWBStream: Unknown XWB codec %d", entry.codec);
Commit: 5661a8b4a2db5a009cb0ead99d111acfca92584a
https://github.com/scummvm/scummvm/commit/5661a8b4a2db5a009cb0ead99d111acfca92584a
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-12-20T13:20:51+02:00
Commit Message:
SCUMM: Add checksum for the GoG version of DOTT Remastered
Changed paths:
devtools/scumm-md5.txt
engines/scumm/scumm-md5.h
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 21061920c93..887d2a2f31c 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -360,6 +360,7 @@ tentacle Day of the Tentacle
4167a92a1d46baa4f4127d918d561f88 7932 en All? - CD 1.6 Fingolfin
64d07dec2bf0789c4f2a7b656cf5bb83 2731584777 en DOS SE SE Filippos Karapetis
+ 7ff69e4905f3c30f3a86ab8fb8cfe34b 2731425417 en DOS SE SE Filippos Karapetis
8aa05d3cdb0e795436043f0546af2da2 7932 fr All? - CD - Andrea Petrucci
6e959d65358eedf9b68b81e304b97fa4 7932 de All? - CD - Fingolfin
4fbbe9f64b8bc547503a379a301183ce -1 it All? - CD - Andrea Petrucci
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 740113cc3d7..d37c699bef8 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 Sun Dec 15 22:58:56 2024
+ This file was generated by the md5table tool on Fri Dec 20 09:25:44 2024
DO NOT EDIT MANUALLY!
*/
@@ -427,6 +427,7 @@ static const MD5Table md5table[] = {
{ "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", 18354, Common::FR_FRA, Common::kPlatformUnknown },
{ "7fbcff27c323499beaedd605e1ebd47d", "indy3", "Steam", "Steam", 561152, Common::EN_ANY, Common::kPlatformWindows },
{ "7fc6cdb46b4c9d384c52327f4bca6416", "football", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
+ { "7ff69e4905f3c30f3a86ab8fb8cfe34b", "tentacle", "SE", "SE", 2731425417, Common::EN_ANY, Common::kPlatformDOS },
{ "810a9da887aefa597b0cf3c77d262897", "BluesABCTime", "", "Demo", 12186, Common::EN_ANY, Common::kPlatformUnknown },
{ "813af095ff338dacf349aca377e48041", "pajama", "HE 101", "", 66878, Common::DE_DEU, Common::kPlatformWii },
{ "813fbcd24a46728cf142cb62057a69cd", "comi", "", "", 76791, Common::HE_ISR, Common::kPlatformWindows },
More information about the Scummvm-git-logs
mailing list