[Scummvm-git-logs] scummvm master -> 9db7dc73aab9f6186c1996839d511b45261ace29

bluegr noreply at scummvm.org
Sat Dec 28 20:12:25 UTC 2024


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

Summary:
5228ac4f9e SCUMM: Move debug flags definition in detection.h
9db7dc73aa SCUMM: Split file.cpp to avoid referencing ScummEngine in detection code


Commit: 5228ac4f9e4f6f8f0dd828b7d529d8cc1ae9b1af
    https://github.com/scummvm/scummvm/commit/5228ac4f9e4f6f8f0dd828b7d529d8cc1ae9b1af
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-12-28T22:12:21+02:00

Commit Message:
SCUMM: Move debug flags definition in detection.h

It's used by detection code and avoids including scumm.h in the
detection code.

Changed paths:
    engines/scumm/detection.cpp
    engines/scumm/detection.h
    engines/scumm/scumm.h


diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 08da116a268..eee748a2990 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -36,7 +36,6 @@
 #include "scumm/detection_tables.h"
 #include "scumm/file.h"
 #include "scumm/file_nes.h"
-#include "scumm/scumm.h"
 
 #pragma mark -
 #pragma mark --- Detection code ---
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index ada809dcedf..6772039774f 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -265,6 +265,22 @@ struct RuScummPatcher {
 	const char *variant;
 	const char *patcherName;
 };
+
+enum {
+	DEBUG_GENERAL	=	1 << 0,		// General debug
+	DEBUG_SCRIPTS	=	1 << 2,		// Track script execution (start/stop/pause)
+	DEBUG_OPCODES	=	1 << 3,		// Track opcode invocations
+	DEBUG_VARS	=	1 << 4,		// Track variable changes
+	DEBUG_RESOURCE	=	1 << 5,		// Track resource loading / allocation
+	DEBUG_IMUSE	=	1 << 6,		// Track iMUSE events
+	DEBUG_SOUND	=	1 << 7,		// General Sound Debug
+	DEBUG_ACTORS	=	1 << 8,		// General Actor Debug
+	DEBUG_INSANE	=	1 << 9,		// Track INSANE
+	DEBUG_SMUSH	=	1 << 10,		// Track SMUSH
+	DEBUG_MOONBASE_AI = 1 << 11,		// Moonbase AI
+	DEBUG_NETWORK = 1 << 12		// Track Networking
+};
+
 } // End of namespace Scumm
 
 
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 52904266e0f..7a7152b2ce9 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -116,21 +116,6 @@ enum {
 /* SCUMM Debug Channels */
 void debugC(int level, MSVC_PRINTF const char *s, ...) GCC_PRINTF(2, 3);
 
-enum {
-	DEBUG_GENERAL	=	1 << 0,		// General debug
-	DEBUG_SCRIPTS	=	1 << 2,		// Track script execution (start/stop/pause)
-	DEBUG_OPCODES	=	1 << 3,		// Track opcode invocations
-	DEBUG_VARS	=	1 << 4,		// Track variable changes
-	DEBUG_RESOURCE	=	1 << 5,		// Track resource loading / allocation
-	DEBUG_IMUSE	=	1 << 6,		// Track iMUSE events
-	DEBUG_SOUND	=	1 << 7,		// General Sound Debug
-	DEBUG_ACTORS	=	1 << 8,		// General Actor Debug
-	DEBUG_INSANE	=	1 << 9,		// Track INSANE
-	DEBUG_SMUSH	=	1 << 10,		// Track SMUSH
-	DEBUG_MOONBASE_AI = 1 << 11,		// Moonbase AI
-	DEBUG_NETWORK = 1 << 12		// Track Networking
-};
-
 struct VerbSlot;
 struct ObjectData;
 


Commit: 9db7dc73aab9f6186c1996839d511b45261ace29
    https://github.com/scummvm/scummvm/commit/9db7dc73aab9f6186c1996839d511b45261ace29
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-12-28T22:12:21+02:00

Commit Message:
SCUMM: Split file.cpp to avoid referencing ScummEngine in detection code

This creates a specific translation unit for the code making use of
ScummEngine while keeping file.cpp for the classes needed for the
detection code.

This allows to build with UBSan while the Scumm engine is disabled.

Changed paths:
  A engines/scumm/file_engine.cpp
    engines/scumm/file.cpp
    engines/scumm/file.h
    engines/scumm/module.mk


diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 9403b572b51..2e57fbe46b4 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -20,304 +20,21 @@
  */
 
 #include "scumm/file.h"
-#include "scumm/scumm.h"
 
-#include "common/macresman.h"
 #include "common/memstream.h"
-#include "common/substream.h"
 
 namespace Scumm {
 
+/**
+ * This file must only contain file reading classes needed for the detection code.
+ * These classes must not reference the ScummEngine class.
+ */
+
 void BaseScummFile::close() {
   _baseStream.reset();
   _debugName.clear();
 }
 
-#pragma mark -
-#pragma mark --- ScummFile ---
-#pragma mark -
-
-ScummFile::ScummFile(const ScummEngine *vm) : _subFileStart(0), _subFileLen(0), _myEos(false), _isMac(vm->_game.platform == Common::kPlatformMacintosh) {
-}
-
-void ScummFile::setSubfileRange(int64 start, int32 len) {
-	// TODO: Add sanity checks
-	const int64 fileSize = _baseStream->size();
-	assert(start <= fileSize);
-	assert(start + len <= fileSize);
-	_subFileStart = start;
-	_subFileLen = len;
-	seek(0, SEEK_SET);
-}
-
-void ScummFile::resetSubfile() {
-	_subFileStart = 0;
-	_subFileLen = 0;
-	seek(0, SEEK_SET);
-}
-
-bool ScummFile::open(const Common::Path &filename) {
-	_baseStream.reset(_isMac ?
-			  Common::MacResManager::openFileOrDataFork(filename) :
-			  SearchMan.createReadStreamForMember(filename));
-	_debugName = filename.toString();
-	if (_baseStream) {
-		resetSubfile();
-		return true;
-	} else {
-		return false;
-	}
-}
-
-bool ScummFile::openSubFile(const Common::Path &filename) {
-	assert(_baseStream);
-
-	// Disable the XOR encryption and reset any current subfile range
-	setEnc(0);
-	resetSubfile();
-
-	// Read in the filename table and look for the specified file
-
-	unsigned long file_off, file_len;
-	char file_name[0x20+1];
-	unsigned long i;
-
-	// Get the length of the data file to use for consistency checks
-	const uint32 data_file_len = size();
-
-	// Read offset and length to the file records */
-	const uint32 file_record_off = readUint32BE();
-	const uint32 file_record_len = readUint32BE();
-
-	// Do a quick check to make sure the offset and length are good
-	if (file_record_off + file_record_len > data_file_len) {
-		return false;
-	}
-
-	// Do a little consistancy check on file_record_length
-	if (file_record_len % 0x28) {
-		return false;
-	}
-
-	Common::String matchname = filename.toString('/');
-	// Scan through the files
-	for (i = 0; i < file_record_len; i += 0x28) {
-		// read a file record
-		seek(file_record_off + i, SEEK_SET);
-		file_off = readUint32BE();
-		file_len = readUint32BE();
-		read(file_name, 0x20);
-		file_name[0x20] = 0;
-
-		assert(file_name[0]);
-		//debug(7, "  extracting \'%s\'", file_name);
-
-		// Consistency check. make sure the file data is in the file
-		if (file_off + file_len > data_file_len) {
-			return false;
-		}
-
-		if (scumm_stricmp(file_name, matchname.c_str()) == 0) {
-			// We got a match!
-			setSubfileRange(file_off, file_len);
-			return true;
-		}
-	}
-
-	return false;
-}
-
-
-bool ScummFile::eos() const {
-	return _subFileLen ? _myEos : _baseStream->eos();
-}
-
-int64 ScummFile::pos() const {
-	return _baseStream->pos() - _subFileStart;
-}
-
-int64 ScummFile::size() const {
-	return _subFileLen ? _subFileLen : _baseStream->size();
-}
-
-bool ScummFile::seek(int64 offs, int whence) {
-	if (_subFileLen) {
-		// Constrain the seek to the subfile
-		switch (whence) {
-		case SEEK_END:
-			offs = _subFileStart + _subFileLen + offs;
-			break;
-		case SEEK_SET:
-		default:
-			offs += _subFileStart;
-			break;
-		case SEEK_CUR:
-			offs += _baseStream->pos();
-			break;
-		}
-		assert(_subFileStart <= offs && offs <= _subFileStart + _subFileLen);
-		whence = SEEK_SET;
-	}
-	bool ret = _baseStream->seek(offs, whence);
-	if (ret)
-		_myEos = false;
-	return ret;
-}
-
-uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
-	uint32 realLen;
-
-	if (_subFileLen) {
-		// Limit the amount we read by the subfile boundaries.
-		const int32 curPos = pos();
-		assert(_subFileLen >= curPos);
-		int32 newPos = curPos + dataSize;
-		if (newPos > _subFileLen) {
-			dataSize = _subFileLen - curPos;
-			_myEos = true;
-		}
-	}
-
-	realLen = _baseStream->read(dataPtr, dataSize);
-
-
-	// If an encryption byte was specified, XOR the data we just read by it.
-	// This simple kind of "encryption" was used by some of the older SCUMM
-	// games.
-	if (_encbyte) {
-		byte *p = (byte *)dataPtr;
-		byte *end = p + realLen;
-		while (p < end)
-			*p++ ^= _encbyte;
-	}
-
-	return realLen;
-}
-
-#pragma mark -
-#pragma mark --- ScummSteamFile ---
-#pragma mark -
-
-bool ScummSteamFile::open(const Common::Path &filename) {
-	if (filename.equalsIgnoreCase(_indexFile.indexFileName)) {
-		return openWithSubRange(_indexFile.executableName, _indexFile.start, _indexFile.len);
-	} else {
-		// Regular non-bundled file
-		return ScummFile::open(filename);
-	}
-}
-
-bool ScummSteamFile::openWithSubRange(const Common::Path &filename, int32 subFileStart, int32 subFileLen) {
-	if (ScummFile::open(filename)) {
-		_subFileStart = subFileStart;
-		_subFileLen = subFileLen;
-		seek(0, SEEK_SET);
-		return true;
-	} else {
-		return false;
-	}
-}
-
-#pragma mark -
-#pragma mark--- ScummPAKFile ---
-#pragma mark -
-
-ScummPAKFile::ScummPAKFile(const ScummEngine *vm, bool indexFiles) : ScummFile(vm) {
-	if (indexFiles)
-		readIndex(vm->_containerFile, vm->_game.id == GID_FT);
-}
-
-void ScummPAKFile::readIndex(const Common::Path &containerFile, bool isFT) {
-	// Based off DoubleFine Explorer: https://github.com/bgbennyboy/DoubleFine-Explorer/blob/master/uDFExplorer_LPAKManager.pas
-	ScummFile::open(containerFile);
-
-	const uint32 magic = _baseStream->readUint32BE();
-	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("maniac/") ||   // DOTT MM easter egg
-			fileName.hasPrefixIgnoreCase("data/") ||     // FT data folder
-			fileName.hasPrefixIgnoreCase("video/") ||    // FT video folder
-			fileName.hasPrefixIgnoreCase("audio/") ||    // DOTT and FT SE audio folder
-			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();
-			_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;
-	}
-}
-
-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 5dd0a15251f..4e90cbcd292 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -29,7 +29,9 @@
 
 namespace Scumm {
 
+#ifdef ENABLE_SCUMM
 class ScummEngine;
+#endif
 
 class BaseScummFile : public Common::SeekableReadStream {
 protected:
@@ -60,6 +62,8 @@ public:
 #endif
 };
 
+#ifdef ENABLE_SCUMM
+
 class ScummFile : public BaseScummFile {
 protected:
 	int64	_subFileStart;
@@ -85,6 +89,8 @@ public:
 	uint32 read(void *dataPtr, uint32 dataSize) override;
 };
 
+#endif
+
 class ScummDiskImage : public BaseScummFile {
 private:
 	Common::SeekableReadStream *_stream;
@@ -139,6 +145,8 @@ struct SteamIndexFile {
 	int32 len;
 };
 
+#ifdef ENABLE_SCUMM
+
 class ScummSteamFile : public ScummFile {
 private:
 	const SteamIndexFile &_indexFile;
@@ -172,6 +180,8 @@ public:
 	void setPAKFileIndex(Common::String fileName, const PAKFile &pakFile);
 };
 
+#endif
+
 } // End of namespace Scumm
 
 #endif
diff --git a/engines/scumm/file_engine.cpp b/engines/scumm/file_engine.cpp
new file mode 100644
index 00000000000..d79a43d0a49
--- /dev/null
+++ b/engines/scumm/file_engine.cpp
@@ -0,0 +1,318 @@
+/* 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 "scumm/file.h"
+#include "scumm/scumm.h"
+
+#include "common/macresman.h"
+
+namespace Scumm {
+
+/**
+ * This file contains all file reading classes requiring a ScummEngine object.
+ */
+
+#pragma mark -
+#pragma mark --- ScummFile ---
+#pragma mark -
+
+ScummFile::ScummFile(const ScummEngine *vm) : _subFileStart(0), _subFileLen(0), _myEos(false), _isMac(vm->_game.platform == Common::kPlatformMacintosh) {
+}
+
+void ScummFile::setSubfileRange(int64 start, int32 len) {
+	// TODO: Add sanity checks
+	const int64 fileSize = _baseStream->size();
+	assert(start <= fileSize);
+	assert(start + len <= fileSize);
+	_subFileStart = start;
+	_subFileLen = len;
+	seek(0, SEEK_SET);
+}
+
+void ScummFile::resetSubfile() {
+	_subFileStart = 0;
+	_subFileLen = 0;
+	seek(0, SEEK_SET);
+}
+
+bool ScummFile::open(const Common::Path &filename) {
+	_baseStream.reset(_isMac ?
+			  Common::MacResManager::openFileOrDataFork(filename) :
+			  SearchMan.createReadStreamForMember(filename));
+	_debugName = filename.toString();
+	if (_baseStream) {
+		resetSubfile();
+		return true;
+	} else {
+		return false;
+	}
+}
+
+bool ScummFile::openSubFile(const Common::Path &filename) {
+	assert(_baseStream);
+
+	// Disable the XOR encryption and reset any current subfile range
+	setEnc(0);
+	resetSubfile();
+
+	// Read in the filename table and look for the specified file
+
+	unsigned long file_off, file_len;
+	char file_name[0x20+1];
+	unsigned long i;
+
+	// Get the length of the data file to use for consistency checks
+	const uint32 data_file_len = size();
+
+	// Read offset and length to the file records */
+	const uint32 file_record_off = readUint32BE();
+	const uint32 file_record_len = readUint32BE();
+
+	// Do a quick check to make sure the offset and length are good
+	if (file_record_off + file_record_len > data_file_len) {
+		return false;
+	}
+
+	// Do a little consistancy check on file_record_length
+	if (file_record_len % 0x28) {
+		return false;
+	}
+
+	Common::String matchname = filename.toString('/');
+	// Scan through the files
+	for (i = 0; i < file_record_len; i += 0x28) {
+		// read a file record
+		seek(file_record_off + i, SEEK_SET);
+		file_off = readUint32BE();
+		file_len = readUint32BE();
+		read(file_name, 0x20);
+		file_name[0x20] = 0;
+
+		assert(file_name[0]);
+		//debug(7, "  extracting \'%s\'", file_name);
+
+		// Consistency check. make sure the file data is in the file
+		if (file_off + file_len > data_file_len) {
+			return false;
+		}
+
+		if (scumm_stricmp(file_name, matchname.c_str()) == 0) {
+			// We got a match!
+			setSubfileRange(file_off, file_len);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
+bool ScummFile::eos() const {
+	return _subFileLen ? _myEos : _baseStream->eos();
+}
+
+int64 ScummFile::pos() const {
+	return _baseStream->pos() - _subFileStart;
+}
+
+int64 ScummFile::size() const {
+	return _subFileLen ? _subFileLen : _baseStream->size();
+}
+
+bool ScummFile::seek(int64 offs, int whence) {
+	if (_subFileLen) {
+		// Constrain the seek to the subfile
+		switch (whence) {
+		case SEEK_END:
+			offs = _subFileStart + _subFileLen + offs;
+			break;
+		case SEEK_SET:
+		default:
+			offs += _subFileStart;
+			break;
+		case SEEK_CUR:
+			offs += _baseStream->pos();
+			break;
+		}
+		assert(_subFileStart <= offs && offs <= _subFileStart + _subFileLen);
+		whence = SEEK_SET;
+	}
+	bool ret = _baseStream->seek(offs, whence);
+	if (ret)
+		_myEos = false;
+	return ret;
+}
+
+uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
+	uint32 realLen;
+
+	if (_subFileLen) {
+		// Limit the amount we read by the subfile boundaries.
+		const int32 curPos = pos();
+		assert(_subFileLen >= curPos);
+		int32 newPos = curPos + dataSize;
+		if (newPos > _subFileLen) {
+			dataSize = _subFileLen - curPos;
+			_myEos = true;
+		}
+	}
+
+	realLen = _baseStream->read(dataPtr, dataSize);
+
+
+	// If an encryption byte was specified, XOR the data we just read by it.
+	// This simple kind of "encryption" was used by some of the older SCUMM
+	// games.
+	if (_encbyte) {
+		byte *p = (byte *)dataPtr;
+		byte *end = p + realLen;
+		while (p < end)
+			*p++ ^= _encbyte;
+	}
+
+	return realLen;
+}
+
+#pragma mark -
+#pragma mark --- ScummSteamFile ---
+#pragma mark -
+
+bool ScummSteamFile::open(const Common::Path &filename) {
+	if (filename.equalsIgnoreCase(_indexFile.indexFileName)) {
+		return openWithSubRange(_indexFile.executableName, _indexFile.start, _indexFile.len);
+	} else {
+		// Regular non-bundled file
+		return ScummFile::open(filename);
+	}
+}
+
+bool ScummSteamFile::openWithSubRange(const Common::Path &filename, int32 subFileStart, int32 subFileLen) {
+	if (ScummFile::open(filename)) {
+		_subFileStart = subFileStart;
+		_subFileLen = subFileLen;
+		seek(0, SEEK_SET);
+		return true;
+	} else {
+		return false;
+	}
+}
+
+#pragma mark -
+#pragma mark--- ScummPAKFile ---
+#pragma mark -
+
+ScummPAKFile::ScummPAKFile(const ScummEngine *vm, bool indexFiles) : ScummFile(vm) {
+	if (indexFiles)
+		readIndex(vm->_containerFile, vm->_game.id == GID_FT);
+}
+
+void ScummPAKFile::readIndex(const Common::Path &containerFile, bool isFT) {
+	// Based off DoubleFine Explorer: https://github.com/bgbennyboy/DoubleFine-Explorer/blob/master/uDFExplorer_LPAKManager.pas
+	ScummFile::open(containerFile);
+
+	const uint32 magic = _baseStream->readUint32BE();
+	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("maniac/") ||   // DOTT MM easter egg
+			fileName.hasPrefixIgnoreCase("data/") ||     // FT data folder
+			fileName.hasPrefixIgnoreCase("video/") ||    // FT video folder
+			fileName.hasPrefixIgnoreCase("audio/") ||    // DOTT and FT SE audio folder
+			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();
+			_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;
+	}
+}
+
+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;
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 5c1edf0996e..9741f967bc5 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS := \
 	debugger.o \
 	dialogs.o \
 	file.o \
+	file_engine.o \
 	file_nes.o \
 	gfx_gui.o \
 	gfx_mac.o \




More information about the Scummvm-git-logs mailing list