[Scummvm-git-logs] scummvm master -> 7ef2db032ee3e2ef54d427ddbc9a8d0653b1598b

bluegr noreply at scummvm.org
Sun Nov 13 22:14:02 UTC 2022


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

Summary:
a48b8dab49 COMMON: Add deleter for arrays
806144202c MADS: Add Archive for MPSLAB installer
fa5596e20f MADS: Enable in-memory unpacking of DOS Rex Nebular installer
ac0fa51d1c COMMON: Add mention of Rex Nebular in dcl.
d2ea82ca41 MADS: Uncomment and update original floppy installer detection entry
daa263b34a MADS: Remove obsolete comment
1367c3820e MADS: Use ArchiveMemberPtr constructor
41dab15c41 MADS: Add a typedef for simpilicity and add a missing underscore
7ef2db032e MADS: Don't use intermediary struct


Commit: a48b8dab492777bd42327e184564a51e98f3040d
    https://github.com/scummvm/scummvm/commit/a48b8dab492777bd42327e184564a51e98f3040d
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
COMMON: Add deleter for arrays

Changed paths:
    common/ptr.h


diff --git a/common/ptr.h b/common/ptr.h
index 9a043f224c0..9193b9b1051 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -560,6 +560,14 @@ struct DefaultDeleter {
 	}
 };
 
+template <typename T>
+struct ArrayDeleter {
+	inline void operator()(T *object) {
+		STATIC_ASSERT(sizeof(T) > 0, cannot_delete_incomplete_type);
+		delete[] object;
+	}
+};
+
 template<typename T, class DL = DefaultDeleter<T> >
 class ScopedPtr : private NonCopyable, public SafeBool<ScopedPtr<T, DL> > {
 public:


Commit: 806144202cae2291bbc61d4ee67ab613684217cd
    https://github.com/scummvm/scummvm/commit/806144202cae2291bbc61d4ee67ab613684217cd
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Add Archive for MPSLAB installer

Changed paths:
  A engines/mads/mps_installer.cpp
  A engines/mads/mps_installer.h
    engines/mads/module.mk


diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index 2093fcb71fb..9d80ac35ff6 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -48,6 +48,7 @@ MODULE_OBJS := \
 	messages.o \
 	msurface.o \
 	metaengine.o \
+	mps_installer.o \
 	palette.o \
 	player.o \
 	rails.o \
diff --git a/engines/mads/mps_installer.cpp b/engines/mads/mps_installer.cpp
new file mode 100644
index 00000000000..2ad8c4e3490
--- /dev/null
+++ b/engines/mads/mps_installer.cpp
@@ -0,0 +1,160 @@
+/* ScummVM Tools
+ *
+ * ScummVM Tools 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/endian.h"
+#include "common/debug.h"
+#include "common/str.h"
+#include "common/file.h"
+#include "common/util.h"
+#include "common/memstream.h"
+#include "common/dcl.h"
+#include "mps_installer.h"
+
+namespace MADS {
+
+MpsInstaller* MpsInstaller::open(const Common::Path& baseName) {
+	Common::File indexFile;
+	Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> files;
+
+	if (!indexFile.open(baseName.append(".IDX")))
+		return nullptr;
+
+	uint32 filecnt = indexFile.readUint16LE();
+
+	indexFile.skip(10);
+
+	uint32 indexSize = indexFile.size();
+
+	if (filecnt > (indexSize - 12) / sizeof(FileDescriptorBin))
+		filecnt = (indexSize - 12) / sizeof(FileDescriptorBin);
+
+	for (uint i = 0; i < filecnt; i++) {
+		FileDescriptorBin descBin;
+		indexFile.read(&descBin, sizeof(descBin));
+		FileDescriptor desc(descBin);
+		files[desc._fileName] = desc;
+	}
+
+	return new MpsInstaller(files, baseName);
+}
+
+// Use of \\ as path separator is a guess. Never seen an archive with subfolders
+static Common::String translateName(const Common::Path &path) {
+	return Common::normalizePath(path.toString('\\'), '\\');
+}
+
+bool MpsInstaller::hasFile(const Common::Path &path) const {
+	return _files.contains(translateName(path));
+}
+
+int MpsInstaller::listMembers(Common::ArchiveMemberList &list) const {
+	int members = 0;
+
+	for (Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::const_iterator i = _files.begin(), end = _files.end();
+	     i != end; ++i) {
+		list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
+		++members;
+	}
+
+	return members;
+}
+
+const Common::ArchiveMemberPtr MpsInstaller::getMember(const Common::Path &path) const {
+	Common::String translated = translateName(path);
+	if (!_files.contains(translated))
+		return nullptr;
+
+	return Common::SharedPtr<Common::ArchiveMember>(new Common::GenericArchiveMember(_files.getVal(translated)._fileName, this));
+}
+
+// TODO: Make streams stay valid after destruction of archive
+Common::SeekableReadStream *MpsInstaller::createReadStreamForMember(const Common::Path &path) const {
+	Common::String translated = translateName(path);
+	if (!_files.contains(translated))
+		return nullptr;
+	FileDescriptor desc = _files.getVal(translated);
+	if (_cache.contains(desc._fileName)) {
+		return new Common::MemoryReadStream(_cache[desc._fileName].get(), desc._uncompressedSize, DisposeAfterUse::NO);
+	}
+
+	if (desc._compressionAlgo != 0 && desc._compressionAlgo != 1) {
+		debug ("Unsupported compression algorithm %d for %s", desc._compressionAlgo, desc._fileName.c_str());
+		return nullptr;
+	}
+
+       
+	uint32 off = desc._offsetInVolume;
+	uint vol = desc._volumeNumber;
+	uint32 rem = desc._compressedSize;
+	byte *compressedBuf = new byte[rem];
+	byte *outptr = compressedBuf;
+	while (rem > 0) {
+		Common::File fvol;
+		Common::Path volumePath = _baseName.append(Common::String::format(".%03d", vol));
+		if (!fvol.open(volumePath)) {
+			error("Failed to open volume %s.%03d", volumePath.toString().c_str(), vol);
+			delete[] compressedBuf;
+			return nullptr;
+		}
+		fvol.seek(off);
+		int32 actual = fvol.read(outptr, rem);
+		if (actual <= 0) {
+			warning("Read failure in volume %s.%03d", volumePath.toString().c_str(), vol);
+			delete[] compressedBuf;
+			return nullptr;
+		}
+	       
+		rem -= actual;
+		outptr += actual;
+		if (actual == 0)
+			break;
+		vol++;
+		off = 0;
+	}
+
+	byte *uncompressedBuf;
+	uint32 uncompressedSize = desc._uncompressedSize;
+	switch (desc._compressionAlgo) {
+	case 0:
+		uncompressedBuf = compressedBuf;
+		uncompressedSize = desc._compressedSize;
+		compressedBuf = nullptr;
+		break;
+	case 1:
+		Common::MemoryReadStream compressedReadStream(compressedBuf, desc._compressedSize);
+		uncompressedBuf = new byte[uncompressedSize];
+		if (!Common::decompressDCL(&compressedReadStream, uncompressedBuf, desc._compressedSize, uncompressedSize)) {
+			delete[] compressedBuf;
+			delete[] uncompressedBuf;
+			error("Unable to decompress %s", desc._fileName.c_str());
+			return nullptr;
+		}
+		delete[] compressedBuf;
+		compressedBuf = nullptr;
+				
+		break;
+	}
+
+	_cache[desc._fileName].reset(uncompressedBuf);
+	// TODO: Make it configurable to read directly from disk, at least in the uncompressed case
+	return new Common::MemoryReadStream(uncompressedBuf, desc._uncompressedSize, DisposeAfterUse::NO);
+}
+}
diff --git a/engines/mads/mps_installer.h b/engines/mads/mps_installer.h
new file mode 100644
index 00000000000..f0a45686269
--- /dev/null
+++ b/engines/mads/mps_installer.h
@@ -0,0 +1,92 @@
+/* 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 MADS_MPS_INSTALLER_H
+#define MADS_MPS_INSTALLER_H
+
+#include "common/archive.h"
+#include "common/ptr.h"
+#include "common/stream.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+namespace MADS {
+
+#include "common/pack-start.h"  // START STRUCT PACKING
+
+struct FileDescriptorBin {
+	char name[0x52]; // zero-terminated, rest is filled with what looks like garbage
+	uint16 compression;
+	uint16 volumeNumber;
+	uint32 offsetInVolume;
+	uint32 compressedSize;
+	uint32 uncompressedSize;
+} PACKED_STRUCT;
+
+#include "common/pack-end.h"    // END STRUCT PACKING
+
+class MpsInstaller : public Common::Archive {
+public:
+	bool hasFile(const Common::Path &path) const override;
+	int listMembers(Common::ArchiveMemberList&) const override;
+	const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
+	Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+
+	static MpsInstaller* open(const Common::Path& baseName);
+
+private:
+	// Similar to FileDescriptionBin but in native-endian and native strings.
+	class FileDescriptor {
+	public:
+		// Public for hashmap
+		FileDescriptor() : _compressedSize(0),
+				   _uncompressedSize(),
+				   _compressionAlgo(0),
+				   _offsetInVolume(0),
+				   _volumeNumber(0) {}
+	protected:
+		FileDescriptor(const FileDescriptorBin &raw) : _fileName(raw.name),
+							       _compressedSize(FROM_LE_32(raw.compressedSize)),
+							       _uncompressedSize(FROM_LE_32(raw.uncompressedSize)),
+							       _compressionAlgo(FROM_LE_16(raw.compression)),
+							       _offsetInVolume(FROM_LE_32(raw.offsetInVolume)),
+							       _volumeNumber(FROM_LE_16(raw.volumeNumber)) {}
+		
+		Common::String _fileName;
+		uint _compressionAlgo;
+		uint _volumeNumber;
+		uint32 _offsetInVolume;
+		uint32 _compressedSize;
+		uint32 _uncompressedSize;
+
+		friend class MpsInstaller;
+	};
+
+	MpsInstaller(const Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>& files,
+		     const Common::Path& baseName) : _files(files), _baseName(baseName) {}
+
+	Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _files;
+	mutable Common::HashMap<Common::String, Common::ScopedPtr<byte, Common::ArrayDeleter<byte>>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache;
+	Common::Path _baseName;
+};
+}
+
+#endif


Commit: fa5596e20fc40ec7fa777de855669b54334b4f43
    https://github.com/scummvm/scummvm/commit/fa5596e20fc40ec7fa777de855669b54334b4f43
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Enable in-memory unpacking of DOS Rex Nebular installer

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


diff --git a/engines/mads/detection.h b/engines/mads/detection.h
index da2f560ec73..e9785884a71 100644
--- a/engines/mads/detection.h
+++ b/engines/mads/detection.h
@@ -33,6 +33,10 @@ enum {
 	GType_Phantom = 2
 };
 
+enum {
+	GF_INSTALLER = 1
+};
+
 struct MADSGameDescription {
 	ADGameDescription desc;
 
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index c2294d8fe49..a7403547815 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -32,6 +32,7 @@
 #include "mads/resources.h"
 #include "mads/sound.h"
 #include "mads/sprites.h"
+#include "mads/mps_installer.h"
 
 namespace MADS {
 
@@ -77,6 +78,13 @@ MADSEngine::~MADSEngine() {
 }
 
 void MADSEngine::initialize() {
+	if (_gameDescription->desc.flags & GF_INSTALLER) {
+		// Right now used only by Rex Nebular
+		Common::Archive* arch = MpsInstaller::open("MPSLABS");
+		if (arch)
+			SearchMan.add("mpslabs", arch);
+	}
+
 	// Initial sub-system engine references
 	MSurface::setVm(this);
 	MSprite::setVm(this);


Commit: ac0fa51d1c3ebc52b7ee6248f86ee1ecb77f448c
    https://github.com/scummvm/scummvm/commit/ac0fa51d1c3ebc52b7ee6248f86ee1ecb77f448c
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
COMMON: Add mention of Rex Nebular in dcl.

Changed paths:
    common/dcl.h


diff --git a/common/dcl.h b/common/dcl.h
index acdc5fe52ed..bd2fcd4d4fd 100644
--- a/common/dcl.h
+++ b/common/dcl.h
@@ -37,6 +37,7 @@ namespace Common {
  *          - Mohawk
  *          - Neverhood
  *          - SCI
+ *          - MADS (exclusively for the Rex Nebular installer) 
  * @{
  */
 


Commit: d2ea82ca41527f7790497cd7326af43bae2ca4c4
    https://github.com/scummvm/scummvm/commit/d2ea82ca41527f7790497cd7326af43bae2ca4c4
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Uncomment and update original floppy installer detection entry

Changed paths:
    engines/mads/detection_tables.h


diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h
index da2244014de..dc25531ed6e 100644
--- a/engines/mads/detection_tables.h
+++ b/engines/mads/detection_tables.h
@@ -22,23 +22,25 @@
 namespace MADS {
 
 static const MADSGameDescription gameDescriptions[] = {
-#if 0
 	{
 		// Rex Nebular and the Cosmic Gender Bender DOS English (compressed)
 		// Removed for now, until the original floppy compression is supported
 		{
 			"nebular",
 			0,
-			AD_ENTRY1s("mpslabs.001", "4df5c557b52abb5b661cf4befe5ae301", 1315354),
+			AD_ENTRY2s("mpslabs.001", "4df5c557b52abb5b661cf4befe5ae301", 1315354, "mpslabs.idx", "d74bed6513d0a5d514269750f574a23b", 5598),
 			Common::EN_ANY,
 			Common::kPlatformDOS,
-			ADGF_NO_FLAGS,
+			GF_INSTALLER,
+#ifdef USE_TTS
+			GUIO6(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE, GAMEOPTION_TTS_NARRATOR)
+#else
 			GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE)
+#endif
 		},
 		GType_RexNebular,
 		0
 	},
-#endif
 
 	{
 		// Rex Nebular and the Cosmic Gender Bender DOS English


Commit: daa263b34a3bca2e2253dcb0658efe2b221f8e66
    https://github.com/scummvm/scummvm/commit/daa263b34a3bca2e2253dcb0658efe2b221f8e66
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Remove obsolete comment

Changed paths:
    engines/mads/detection_tables.h


diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h
index dc25531ed6e..894a496b20e 100644
--- a/engines/mads/detection_tables.h
+++ b/engines/mads/detection_tables.h
@@ -24,7 +24,6 @@ namespace MADS {
 static const MADSGameDescription gameDescriptions[] = {
 	{
 		// Rex Nebular and the Cosmic Gender Bender DOS English (compressed)
-		// Removed for now, until the original floppy compression is supported
 		{
 			"nebular",
 			0,


Commit: 1367c3820e7473fad0e00668bbfb41c7dfca93b6
    https://github.com/scummvm/scummvm/commit/1367c3820e7473fad0e00668bbfb41c7dfca93b6
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Use ArchiveMemberPtr constructor

Co-authored-by: Filippos Karapetis <bluegr at gmail.com>

Changed paths:
    engines/mads/mps_installer.cpp


diff --git a/engines/mads/mps_installer.cpp b/engines/mads/mps_installer.cpp
index 2ad8c4e3490..b22fcf8cb80 100644
--- a/engines/mads/mps_installer.cpp
+++ b/engines/mads/mps_installer.cpp
@@ -82,7 +82,7 @@ const Common::ArchiveMemberPtr MpsInstaller::getMember(const Common::Path &path)
 	if (!_files.contains(translated))
 		return nullptr;
 
-	return Common::SharedPtr<Common::ArchiveMember>(new Common::GenericArchiveMember(_files.getVal(translated)._fileName, this));
+	return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(_files.getVal(translated)._fileName, this));
 }
 
 // TODO: Make streams stay valid after destruction of archive


Commit: 41dab15c411f197e847e1960d79a1ab25ab9c503
    https://github.com/scummvm/scummvm/commit/41dab15c411f197e847e1960d79a1ab25ab9c503
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Add a typedef for simpilicity and add a missing underscore

Co-authored-by: Filippos Karapetis <bluegr at gmail.com>

Changed paths:
    engines/mads/mps_installer.cpp
    engines/mads/mps_installer.h


diff --git a/engines/mads/mps_installer.cpp b/engines/mads/mps_installer.cpp
index b22fcf8cb80..e8dc0a96ad4 100644
--- a/engines/mads/mps_installer.cpp
+++ b/engines/mads/mps_installer.cpp
@@ -32,7 +32,7 @@ namespace MADS {
 
 MpsInstaller* MpsInstaller::open(const Common::Path& baseName) {
 	Common::File indexFile;
-	Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> files;
+	FileMap _files;
 
 	if (!indexFile.open(baseName.append(".IDX")))
 		return nullptr;
@@ -50,10 +50,10 @@ MpsInstaller* MpsInstaller::open(const Common::Path& baseName) {
 		FileDescriptorBin descBin;
 		indexFile.read(&descBin, sizeof(descBin));
 		FileDescriptor desc(descBin);
-		files[desc._fileName] = desc;
+		_files[desc._fileName] = desc;
 	}
 
-	return new MpsInstaller(files, baseName);
+	return new MpsInstaller(_files, baseName);
 }
 
 // Use of \\ as path separator is a guess. Never seen an archive with subfolders
@@ -66,15 +66,11 @@ bool MpsInstaller::hasFile(const Common::Path &path) const {
 }
 
 int MpsInstaller::listMembers(Common::ArchiveMemberList &list) const {
-	int members = 0;
-
-	for (Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::const_iterator i = _files.begin(), end = _files.end();
-	     i != end; ++i) {
+	for (FileMap::const_iterator i = _files.begin(), end = _files.end(); i != end; ++i) {
 		list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
-		++members;
 	}
 
-	return members;
+	return _files.size();
 }
 
 const Common::ArchiveMemberPtr MpsInstaller::getMember(const Common::Path &path) const {
diff --git a/engines/mads/mps_installer.h b/engines/mads/mps_installer.h
index f0a45686269..297f2bcd315 100644
--- a/engines/mads/mps_installer.h
+++ b/engines/mads/mps_installer.h
@@ -80,10 +80,12 @@ private:
 		friend class MpsInstaller;
 	};
 
-	MpsInstaller(const Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>& files,
+    	typedef Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
+
+	MpsInstaller(const FileMap& files,
 		     const Common::Path& baseName) : _files(files), _baseName(baseName) {}
 
-	Common::HashMap<Common::String, FileDescriptor, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _files;
+	FileMap _files;
 	mutable Common::HashMap<Common::String, Common::ScopedPtr<byte, Common::ArrayDeleter<byte>>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _cache;
 	Common::Path _baseName;
 };


Commit: 7ef2db032ee3e2ef54d427ddbc9a8d0653b1598b
    https://github.com/scummvm/scummvm/commit/7ef2db032ee3e2ef54d427ddbc9a8d0653b1598b
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-11-14T00:13:54+02:00

Commit Message:
MADS: Don't use intermediary struct

Changed paths:
    engines/mads/mps_installer.cpp
    engines/mads/mps_installer.h


diff --git a/engines/mads/mps_installer.cpp b/engines/mads/mps_installer.cpp
index e8dc0a96ad4..121324a6a91 100644
--- a/engines/mads/mps_installer.cpp
+++ b/engines/mads/mps_installer.cpp
@@ -43,13 +43,29 @@ MpsInstaller* MpsInstaller::open(const Common::Path& baseName) {
 
 	uint32 indexSize = indexFile.size();
 
-	if (filecnt > (indexSize - 12) / sizeof(FileDescriptorBin))
-		filecnt = (indexSize - 12) / sizeof(FileDescriptorBin);
+	static const int kNameFieldLength = 0x52;
+	static const int kEntryLength = kNameFieldLength + 0x10;
+
+	if (filecnt > (indexSize - 12) / kEntryLength)
+		filecnt = (indexSize - 12) / kEntryLength;
 
 	for (uint i = 0; i < filecnt; i++) {
-		FileDescriptorBin descBin;
-		indexFile.read(&descBin, sizeof(descBin));
-		FileDescriptor desc(descBin);
+		char nameField[kNameFieldLength];
+		int nameLen = kNameFieldLength;
+		indexFile.read(nameField, kNameFieldLength);
+		for (uint j = 0; j < kNameFieldLength; j++) {
+			if (!nameField[j]) {
+				nameLen = j;
+				break;
+			}
+		}
+		uint16 compression = indexFile.readUint16LE();
+		uint16 volumeNumber = indexFile.readUint16LE();
+		uint32 offsetInVolume = indexFile.readUint32LE();
+		uint32 compressedSize = indexFile.readUint32LE();
+		uint32 uncompressedSize = indexFile.readUint32LE();
+		Common::String name(nameField, nameLen);
+		FileDescriptor desc(name, compression, volumeNumber, offsetInVolume, compressedSize, uncompressedSize);
 		_files[desc._fileName] = desc;
 	}
 
diff --git a/engines/mads/mps_installer.h b/engines/mads/mps_installer.h
index 297f2bcd315..630ed8c3ca0 100644
--- a/engines/mads/mps_installer.h
+++ b/engines/mads/mps_installer.h
@@ -30,19 +30,6 @@
 
 namespace MADS {
 
-#include "common/pack-start.h"  // START STRUCT PACKING
-
-struct FileDescriptorBin {
-	char name[0x52]; // zero-terminated, rest is filled with what looks like garbage
-	uint16 compression;
-	uint16 volumeNumber;
-	uint32 offsetInVolume;
-	uint32 compressedSize;
-	uint32 uncompressedSize;
-} PACKED_STRUCT;
-
-#include "common/pack-end.h"    // END STRUCT PACKING
-
 class MpsInstaller : public Common::Archive {
 public:
 	bool hasFile(const Common::Path &path) const override;
@@ -63,12 +50,18 @@ private:
 				   _offsetInVolume(0),
 				   _volumeNumber(0) {}
 	protected:
-		FileDescriptor(const FileDescriptorBin &raw) : _fileName(raw.name),
-							       _compressedSize(FROM_LE_32(raw.compressedSize)),
-							       _uncompressedSize(FROM_LE_32(raw.uncompressedSize)),
-							       _compressionAlgo(FROM_LE_16(raw.compression)),
-							       _offsetInVolume(FROM_LE_32(raw.offsetInVolume)),
-							       _volumeNumber(FROM_LE_16(raw.volumeNumber)) {}
+		FileDescriptor(const Common::String& name,
+			       uint16 compression,
+			       uint16 volumeNumber,
+			       uint32 offsetInVolume,
+			       uint32 compressedSize,
+			       uint32 uncompressedSize) :
+			_fileName(name),
+			_compressionAlgo(compression),
+			_volumeNumber(volumeNumber),
+			_offsetInVolume(offsetInVolume),
+			_compressedSize(compressedSize),
+			_uncompressedSize(uncompressedSize) {}
 		
 		Common::String _fileName;
 		uint _compressionAlgo;




More information about the Scummvm-git-logs mailing list