[Scummvm-git-logs] scummvm master -> d7aa54bf30df79e84a27d0358c736601d2a9d04f
phcoder
noreply at scummvm.org
Wed Dec 7 23:02:45 UTC 2022
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
571a807257 COMMON: Switch stuffit to MemcachingCaseInsensitiveArchive
d9888b9ac6 COMMON: Support stuffit-13 algorithm
2c8fd71b47 KYRA: Switch to openFileOrDataFork
9f4d744b46 KYRA: Store cached installer mac archive as its simple name
1b90cea645 KYRA: Support loading stuffit archive from abstract stream
d7aa54bf30 KYRA: Support multi-floppy installer
Commit: 571a80725730eab0f81c8a2e0a16630196419ec1
https://github.com/scummvm/scummvm/commit/571a80725730eab0f81c8a2e0a16630196419ec1
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
COMMON: Switch stuffit to MemcachingCaseInsensitiveArchive
Changed paths:
common/compression/stuffit.cpp
diff --git a/common/compression/stuffit.cpp b/common/compression/stuffit.cpp
index e2d6e436444..f36e0964ff8 100644
--- a/common/compression/stuffit.cpp
+++ b/common/compression/stuffit.cpp
@@ -37,7 +37,7 @@ namespace Common {
struct SIT14Data;
-class StuffItArchive : public Common::Archive {
+class StuffItArchive : public Common::MemcachingCaseInsensitiveArchive {
public:
StuffItArchive();
~StuffItArchive() override;
@@ -51,7 +51,10 @@ public:
bool hasFile(const Common::Path &path) const override;
int listMembers(Common::ArchiveMemberList &list) const override;
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
- Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
+ Common::SharedArchiveContents readContentsForPath(const Common::String& name) const override;
+ Common::String translatePath(const Common::Path &path) const override {
+ return path.toString();
+ }
private:
struct FileEntry {
@@ -70,14 +73,14 @@ private:
MetadataMap _metadataMap;
// Decompression Functions
- Common::SeekableReadStream *decompress14(Common::SeekableReadStream *src, uint32 uncompressedSize) const;
+ void decompress14(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const;
// Decompression Helpers
void update14(uint16 first, uint16 last, byte *code, uint16 *freq) const;
void readTree14(Common::BitStream8LSB *bits, SIT14Data *dat, uint16 codesize, uint16 *result) const;
};
-StuffItArchive::StuffItArchive() : Common::Archive() {
+StuffItArchive::StuffItArchive() : Common::MemcachingCaseInsensitiveArchive() {
_stream = nullptr;
}
@@ -230,15 +233,15 @@ const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::Path &pat
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
-Common::SeekableReadStream *StuffItArchive::createReadStreamForMember(const Common::Path &path) const {
- Common::String name = path.toString();
-
+Common::SharedArchiveContents StuffItArchive::readContentsForPath(const Common::String& name) const {
if (!_stream || !_map.contains(name)) {
if (_metadataMap.contains(name)) {
const Common::MacFinderInfoData &metadata = _metadataMap[name];
- return new Common::MemoryReadStream(reinterpret_cast<const byte *>(&metadata), sizeof(Common::MacFinderInfoData), DisposeAfterUse::NO);
+ byte *copy = new byte[sizeof(Common::MacFinderInfoData)];
+ memcpy(copy, reinterpret_cast<const byte *>(&metadata), sizeof(Common::MacFinderInfoData));
+ return Common::SharedArchiveContents(copy, sizeof(Common::MacFinderInfoData));
}
- return nullptr;
+ return Common::SharedArchiveContents();
}
const FileEntry &entry = _map[name];
@@ -248,17 +251,22 @@ Common::SeekableReadStream *StuffItArchive::createReadStreamForMember(const Comm
Common::SeekableSubReadStream subStream(_stream, entry.offset, entry.offset + entry.compressedSize);
+ byte *uncompressedBlock = new byte[entry.uncompressedSize];
+
// We currently only support type 14 compression
switch (entry.compression) {
case 0: // Uncompressed
- return subStream.readStream(subStream.size());
+ subStream.read(uncompressedBlock, entry.uncompressedSize);
+ break;
case 14: // Installer
- return decompress14(&subStream, entry.uncompressedSize);
+ decompress14(&subStream, uncompressedBlock, entry.uncompressedSize);
+ break;
default:
error("Unhandled StuffIt compression %d", entry.compression);
+ return Common::SharedArchiveContents();
}
- return nullptr;
+ return Common::SharedArchiveContents(uncompressedBlock, entry.uncompressedSize);
}
void StuffItArchive::update14(uint16 first, uint16 last, byte *code, uint16 *freq) const {
@@ -448,8 +456,7 @@ void StuffItArchive::readTree14(Common::BitStream8LSB *bits, SIT14Data *dat, uin
dat->window[j++] = x; \
j &= 0x3FFFF
-Common::SeekableReadStream *StuffItArchive::decompress14(Common::SeekableReadStream *src, uint32 uncompressedSize) const {
- byte *dst = (byte *)malloc(uncompressedSize);
+void StuffItArchive::decompress14(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const {
Common::MemoryWriteStream out(dst, uncompressedSize);
Common::BitStream8LSB *bits = new Common::BitStream8LSB(src);
@@ -539,8 +546,6 @@ Common::SeekableReadStream *StuffItArchive::decompress14(Common::SeekableReadStr
delete dat;
delete bits;
-
- return new Common::MemoryReadStream(dst, uncompressedSize, DisposeAfterUse::YES);
}
#undef OUTPUT_VAL
Commit: d9888b9ac6cb41ef438c6e98f5e4a771810f030e
https://github.com/scummvm/scummvm/commit/d9888b9ac6cb41ef438c6e98f5e4a771810f030e
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
COMMON: Support stuffit-13 algorithm
Changed paths:
common/compression/stuffit.cpp
diff --git a/common/compression/stuffit.cpp b/common/compression/stuffit.cpp
index f36e0964ff8..bf7852c0b2f 100644
--- a/common/compression/stuffit.cpp
+++ b/common/compression/stuffit.cpp
@@ -20,7 +20,7 @@
*/
// StuffIt parsing based on https://github.com/mietek/theunarchiver/wiki/StuffItFormat
-// Compression 14 based on libxad (http://sourceforge.net/projects/libxad/)
+// Compressions 13 and 14 based on libxad (http://sourceforge.net/projects/libxad/)
#include "common/compression/stuffit.h"
@@ -73,6 +73,7 @@ private:
MetadataMap _metadataMap;
// Decompression Functions
+ bool decompress13(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const;
void decompress14(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const;
// Decompression Helpers
@@ -258,6 +259,10 @@ Common::SharedArchiveContents StuffItArchive::readContentsForPath(const Common::
case 0: // Uncompressed
subStream.read(uncompressedBlock, entry.uncompressedSize);
break;
+ case 13: // TableHuff
+ if (!decompress13(&subStream, uncompressedBlock, entry.uncompressedSize))
+ error("SIT-13 decompression failed");
+ break;
case 14: // Installer
decompress14(&subStream, uncompressedBlock, entry.uncompressedSize);
break;
@@ -451,6 +456,473 @@ void StuffItArchive::readTree14(Common::BitStream8LSB *bits, SIT14Data *dat, uin
ALIGN_BITS(bits);
}
+struct SIT13Buffer {
+ uint16 data;
+ int8 bits;
+
+ SIT13Buffer() : data(0), bits(0) {}
+};
+
+struct SIT13Store {
+ int16 freq;
+ uint16 d1;
+ uint16 d2;
+
+ SIT13Store() : freq(0), d1(0), d2(0) {}
+};
+
+struct SIT13Data {
+ uint16 MaxBits;
+ struct SIT13Store Buffer4[0xE08];
+ struct SIT13Buffer Buffer1[0x1000];
+ struct SIT13Buffer Buffer2[0x1000];
+ struct SIT13Buffer Buffer3[0x1000];
+ struct SIT13Buffer Buffer3b[0x1000];
+ struct SIT13Buffer Buffer5[0x141];
+ uint8 TextBuf[658];
+ uint8 Window[0x10000];
+
+ SIT13Data() : MaxBits(0) {
+ memset(TextBuf, 0, sizeof(TextBuf));
+ memset(Window, 0, sizeof(Window));
+ }
+};
+
+static const uint8 SIT13Bits[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
+static const uint16 SIT13Info[37] = {
+ 0x5D8, 0x058, 0x040, 0x0C0, 0x000, 0x078, 0x02B, 0x014,
+ 0x00C, 0x01C, 0x01B, 0x00B, 0x010, 0x020, 0x038, 0x018,
+ 0x0D8, 0xBD8, 0x180, 0x680, 0x380, 0xF80, 0x780, 0x480,
+ 0x080, 0x280, 0x3D8, 0xFD8, 0x7D8, 0x9D8, 0x1D8, 0x004,
+ 0x001, 0x002, 0x007, 0x003, 0x008
+};
+static const uint16 SIT13InfoBits[37] = {
+ 11, 8, 8, 8, 8, 7, 6, 5, 5, 5, 5, 6, 5, 6, 7, 7,
+ 9, 12, 10, 11, 11, 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 5,
+ 2, 2, 3, 4, 5
+};
+static const uint16 SIT13StaticPos[5] = {0, 330, 661, 991, 1323};
+static const uint8 SIT13StaticBits[5] = {11, 13, 14, 11, 11};
+static const uint8 SIT13Static[1655] = {
+ 0xB8,0x98,0x78,0x77,0x75,0x97,0x76,0x87,0x77,0x77,0x77,0x78,0x67,0x87,0x68,0x67,0x3B,0x77,0x78,0x67,
+ 0x77,0x77,0x77,0x59,0x76,0x87,0x77,0x77,0x77,0x77,0x77,0x77,0x76,0x87,0x67,0x87,0x77,0x77,0x75,0x88,
+ 0x59,0x75,0x79,0x77,0x78,0x68,0x77,0x67,0x73,0xB6,0x65,0xB6,0x76,0x97,0x67,0x47,0x9A,0x2A,0x4A,0x87,
+ 0x77,0x78,0x67,0x86,0x78,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
+ 0x68,0x77,0x77,0x77,0x67,0x87,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x68,0x77,0x77,0x77,
+ 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x67,0x87,
+ 0x68,0x77,0x77,0x77,0x68,0x77,0x68,0x63,0x86,0x7A,0x87,0x77,0x77,0x87,0x76,0x87,0x77,0x77,0x77,0x77,
+ 0x77,0x77,0x77,0x77,0x77,0x76,0x86,0x77,0x86,0x86,0x86,0x86,0x87,0x76,0x86,0x87,0x67,0x74,0xA7,0x86,
+ 0x36,0x88,0x78,0x76,0x87,0x76,0x96,0x87,0x77,0x84,0xA6,0x86,0x87,0x76,0x92,0xB5,0x94,0xA6,0x96,0x85,
+ 0x78,0x75,0x96,0x86,0x86,0x75,0xA7,0x67,0x87,0x85,0x87,0x85,0x95,0x77,0x77,0x85,0xA3,0xA7,0x93,0x87,
+ 0x86,0x94,0x85,0xA8,0x67,0x85,0xA5,0x95,0x86,0x68,0x67,0x77,0x96,0x78,0x75,0x86,0x77,0xA5,0x67,0x87,
+ 0x85,0xA6,0x75,0x96,0x85,0x87,0x95,0x95,0x87,0x86,0x94,0xA5,0x86,0x85,0x87,0x86,0x86,0x86,0x86,0x77,
+ 0x67,0x76,0x66,0x9A,0x75,0xA5,0x94,0x97,0x76,0x96,0x76,0x95,0x86,0x77,0x86,0x87,0x75,0xA5,0x96,0x85,
+ 0x86,0x96,0x86,0x86,0x85,0x96,0x86,0x76,0x95,0x86,0x95,0x95,0x95,0x87,0x76,0x87,0x76,0x96,0x85,0x78,
+ 0x75,0xA6,0x85,0x86,0x95,0x86,0x95,0x86,0x45,0x69,0x78,0x77,0x87,0x67,0x69,0x58,0x79,0x68,0x78,0x87,
+ 0x78,0x66,0x88,0x68,0x68,0x77,0x76,0x87,0x68,0x68,0x69,0x58,0x5A,0x4B,0x76,0x88,0x69,0x67,0xA7,0x70,
+ 0x9F,0x90,0xA4,0x84,0x77,0x77,0x77,0x89,0x17,0x77,0x7B,0xA7,0x86,0x87,0x77,0x68,0x68,0x69,0x67,0x78,
+ 0x77,0x78,0x76,0x87,0x77,0x76,0x73,0xB6,0x87,0x96,0x66,0x87,0x76,0x85,0x87,0x78,0x77,0x77,0x86,0x77,
+ 0x86,0x78,0x66,0x76,0x77,0x87,0x86,0x78,0x76,0x76,0x86,0xA5,0x67,0x97,0x77,0x87,0x87,0x76,0x66,0x59,
+ 0x67,0x59,0x77,0x6A,0x65,0x86,0x78,0x94,0x77,0x88,0x77,0x78,0x86,0x86,0x76,0x88,0x76,0x87,0x67,0x87,
+ 0x77,0x77,0x76,0x87,0x86,0x77,0x77,0x77,0x86,0x86,0x76,0x96,0x77,0x77,0x76,0x78,0x86,0x86,0x86,0x95,
+ 0x86,0x96,0x85,0x95,0x86,0x87,0x75,0x88,0x77,0x87,0x57,0x78,0x76,0x86,0x76,0x96,0x86,0x87,0x76,0x87,
+ 0x86,0x76,0x77,0x86,0x78,0x78,0x57,0x87,0x86,0x76,0x85,0xA5,0x87,0x76,0x86,0x86,0x85,0x86,0x53,0x98,
+ 0x78,0x78,0x77,0x87,0x79,0x67,0x79,0x85,0x87,0x69,0x67,0x68,0x78,0x69,0x68,0x69,0x58,0x87,0x66,0x97,
+ 0x68,0x68,0x76,0x85,0x78,0x87,0x67,0x97,0x67,0x74,0xA2,0x28,0x77,0x78,0x77,0x77,0x78,0x68,0x67,0x78,
+ 0x77,0x78,0x68,0x68,0x77,0x59,0x67,0x5A,0x68,0x68,0x68,0x68,0x68,0x68,0x67,0x77,0x78,0x68,0x68,0x78,
+ 0x59,0x58,0x76,0x77,0x68,0x78,0x68,0x59,0x69,0x58,0x68,0x68,0x67,0x78,0x77,0x78,0x69,0x58,0x68,0x57,
+ 0x78,0x67,0x78,0x76,0x88,0x58,0x67,0x7A,0x46,0x88,0x77,0x78,0x68,0x68,0x66,0x78,0x78,0x68,0x68,0x59,
+ 0x68,0x69,0x68,0x59,0x67,0x78,0x59,0x58,0x69,0x59,0x67,0x68,0x67,0x69,0x69,0x57,0x79,0x68,0x59,0x59,
+ 0x59,0x68,0x68,0x68,0x58,0x78,0x67,0x59,0x68,0x78,0x59,0x58,0x78,0x58,0x76,0x78,0x68,0x68,0x68,0x69,
+ 0x59,0x67,0x68,0x69,0x59,0x59,0x58,0x69,0x59,0x59,0x58,0x5A,0x58,0x68,0x68,0x59,0x58,0x68,0x66,0x47,
+ 0x88,0x77,0x87,0x77,0x87,0x76,0x87,0x87,0x87,0x77,0x77,0x87,0x67,0x96,0x78,0x76,0x87,0x68,0x77,0x77,
+ 0x76,0x86,0x96,0x86,0x88,0x77,0x85,0x86,0x8B,0x76,0x0A,0xF9,0x07,0x38,0x57,0x67,0x77,0x78,0x77,0x91,
+ 0x77,0xD7,0x77,0x7A,0x67,0x3C,0x68,0x68,0x77,0x68,0x78,0x59,0x77,0x68,0x77,0x68,0x76,0x77,0x69,0x68,
+ 0x68,0x68,0x68,0x67,0x68,0x68,0x77,0x87,0x77,0x67,0x78,0x68,0x67,0x58,0x78,0x68,0x77,0x68,0x78,0x67,
+ 0x68,0x68,0x67,0x78,0x77,0x77,0x87,0x77,0x76,0x67,0x86,0x85,0x87,0x86,0x97,0x58,0x67,0x79,0x57,0x77,
+ 0x87,0x77,0x87,0x77,0x76,0x59,0x78,0x77,0x77,0x68,0x77,0x77,0x76,0x78,0x77,0x77,0x77,0x76,0x87,0x77,
+ 0x77,0x68,0x77,0x77,0x77,0x67,0x78,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x76,0x68,0x87,0x77,
+ 0x77,0x77,0x77,0x68,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x77,0x76,0x78,0x77,0x77,0x76,0x87,0x77,0x77,
+ 0x67,0x78,0x77,0x77,0x76,0x78,0x67,0x68,0x68,0x29,0x77,0x88,0x78,0x78,0x77,0x68,0x77,0x77,0x77,0x77,
+ 0x77,0x77,0x77,0x77,0x4A,0x77,0x4A,0x74,0x77,0x77,0x68,0xA4,0x7A,0x47,0x76,0x86,0x78,0x76,0x7A,0x4A,
+ 0x83,0xB2,0x87,0x77,0x87,0x76,0x96,0x86,0x96,0x76,0x78,0x87,0x77,0x85,0x87,0x85,0x96,0x65,0xB5,0x95,
+ 0x96,0x77,0x77,0x86,0x76,0x86,0x86,0x87,0x86,0x86,0x76,0x96,0x96,0x57,0x77,0x85,0x97,0x85,0x86,0xA5,
+ 0x86,0x85,0x87,0x77,0x68,0x78,0x77,0x95,0x86,0x75,0x87,0x76,0x86,0x79,0x68,0x84,0x96,0x76,0xB3,0x87,
+ 0x77,0x68,0x86,0xA5,0x77,0x56,0xB6,0x68,0x85,0x93,0xB6,0x95,0x95,0x85,0x95,0xA5,0x95,0x95,0x69,0x85,
+ 0x95,0x85,0x86,0x86,0x97,0x84,0x85,0xB6,0x84,0xA5,0x95,0xA4,0x95,0x95,0x95,0x68,0x95,0x66,0xA6,0x95,
+ 0x95,0x95,0x86,0x93,0xB5,0x86,0x77,0x94,0x96,0x95,0x96,0x85,0x68,0x94,0x87,0x95,0x86,0x86,0x93,0xB4,
+ 0xA3,0xB3,0xA6,0x86,0x85,0x85,0x96,0x76,0x86,0x64,0x69,0x78,0x68,0x78,0x78,0x77,0x67,0x79,0x68,0x79,
+ 0x59,0x56,0x87,0x98,0x68,0x78,0x76,0x88,0x68,0x68,0x67,0x76,0x87,0x68,0x78,0x76,0x78,0x77,0x78,0xA6,
+ 0x80,0xAF,0x81,0x38,0x47,0x67,0x77,0x78,0x77,0x89,0x07,0x79,0xB7,0x87,0x86,0x86,0x87,0x86,0x87,0x76,
+ 0x78,0x77,0x87,0x66,0x96,0x86,0x86,0x74,0xA6,0x87,0x86,0x77,0x86,0x77,0x76,0x77,0x77,0x87,0x77,0x77,
+ 0x77,0x77,0x87,0x65,0x78,0x77,0x78,0x75,0x88,0x85,0x76,0x87,0x95,0x77,0x86,0x87,0x86,0x96,0x85,0x76,
+ 0x69,0x67,0x59,0x77,0x6A,0x65,0x86,0x78,0x94,0x77,0x88,0x77,0x78,0x85,0x96,0x65,0x98,0x77,0x87,0x67,
+ 0x86,0x77,0x87,0x66,0x87,0x86,0x86,0x86,0x77,0x86,0x86,0x76,0x87,0x86,0x77,0x76,0x87,0x77,0x86,0x86,
+ 0x86,0x87,0x76,0x95,0x86,0x86,0x87,0x65,0x97,0x86,0x87,0x76,0x86,0x86,0x87,0x75,0x88,0x76,0x87,0x76,
+ 0x87,0x76,0x77,0x77,0x86,0x78,0x76,0x76,0x96,0x78,0x76,0x77,0x86,0x77,0x77,0x76,0x96,0x75,0x95,0x56,
+ 0x87,0x87,0x87,0x78,0x88,0x67,0x87,0x87,0x58,0x87,0x77,0x87,0x77,0x76,0x87,0x96,0x59,0x88,0x37,0x89,
+ 0x69,0x69,0x84,0x96,0x67,0x77,0x57,0x4B,0x58,0xB7,0x80,0x8E,0x0D,0x78,0x87,0x77,0x87,0x68,0x79,0x49,
+ 0x76,0x78,0x77,0x5A,0x67,0x69,0x68,0x68,0x68,0x4A,0x68,0x69,0x67,0x69,0x59,0x58,0x68,0x67,0x69,0x77,
+ 0x77,0x69,0x68,0x68,0x66,0x68,0x87,0x68,0x77,0x5A,0x68,0x67,0x68,0x68,0x67,0x78,0x78,0x67,0x6A,0x59,
+ 0x67,0x57,0x95,0x78,0x77,0x86,0x88,0x57,0x77,0x68,0x67,0x79,0x76,0x76,0x98,0x68,0x75,0x68,0x88,0x58,
+ 0x87,0x5A,0x57,0x79,0x67,0x59,0x78,0x49,0x58,0x77,0x79,0x49,0x68,0x59,0x77,0x68,0x78,0x48,0x79,0x67,
+ 0x68,0x59,0x68,0x68,0x59,0x75,0x6A,0x68,0x76,0x4C,0x67,0x77,0x78,0x59,0x69,0x56,0x96,0x68,0x68,0x68,
+ 0x77,0x69,0x67,0x68,0x67,0x78,0x69,0x68,0x58,0x59,0x68,0x68,0x69,0x49,0x77,0x59,0x67,0x69,0x67,0x68,
+ 0x65,0x48,0x77,0x87,0x86,0x96,0x88,0x75,0x87,0x96,0x87,0x95,0x87,0x77,0x68,0x86,0x77,0x77,0x96,0x68,
+ 0x86,0x77,0x85,0x5A,0x81,0xD5,0x95,0x68,0x99,0x74,0x98,0x77,0x09,0xF9,0x0A,0x5A,0x66,0x58,0x77,0x87,
+ 0x91,0x77,0x77,0xE9,0x77,0x77,0x77,0x76,0x87,0x75,0x97,0x77,0x77,0x77,0x78,0x68,0x68,0x68,0x67,0x3B,
+ 0x59,0x77,0x77,0x57,0x79,0x57,0x86,0x87,0x67,0x97,0x77,0x57,0x79,0x77,0x77,0x75,0x95,0x77,0x79,0x75,
+ 0x97,0x57,0x77,0x79,0x58,0x69,0x77,0x77,0x77,0x77,0x77,0x75,0x86,0x77,0x87,0x58,0x95,0x78,0x65,0x8A,
+ 0x39,0x58,0x87,0x96,0x87,0x77,0x77,0x77,0x86,0x87,0x76,0x78,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,
+ 0x77,0x68,0x77,0x68,0x77,0x67,0x86,0x77,0x78,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x68,
+ 0x77,0x68,0x77,0x67,0x78,0x77,0x77,0x68,0x68,0x76,0x87,0x68,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,
+ 0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x68,0x68,0x68,0x76,0x38,0x97,0x67,0x79,0x77,0x77,0x77,0x77,0x77,
+ 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,
+ 0x72,0xC5,0x86,0x86,0x98,0x77,0x86,0x78,0x1C,0x85,0x2E,0x77,0x77,0x77,0x87,0x86,0x76,0x86,0x86,0xA0,
+ 0xBD,0x49,0x97,0x66,0x48,0x88,0x48,0x68,0x86,0x78,0x77,0x77,0x78,0x66,0xA6,0x87,0x83,0x85,0x88,0x78,
+ 0x66,0xA7,0x56,0x87,0x6A,0x46,0x89,0x76,0xA7,0x76,0x87,0x74,0xA2,0x86,0x77,0x79,0x66,0xB6,0x48,0x67,
+ 0x8A,0x36,0x88,0x77,0xA5,0xA5,0xB1,0xE9,0x39,0x78,0x78,0x75,0x87,0x77,0x77,0x77,0x68,0x58,0x79,0x69,
+ 0x4A,0x59,0x29,0x6A,0x3C,0x3B,0x46,0x78,0x75,0x89,0x76,0x89,0x4A,0x56,0x88,0x3B,0x66,0x88,0x68,0x87,
+ 0x57,0x97,0x38,0x87,0x56,0xB7,0x84,0x88,0x67,0x57,0x95,0xA8,0x59,0x77,0x68,0x4A,0x49,0x69,0x57,0x6A,
+ 0x59,0x58,0x67,0x87,0x5A,0x75,0x78,0x69,0x56,0x97,0x77,0x73,0x08,0x78,0x78,0x77,0x87,0x78,0x77,0x78,
+ 0x77,0x77,0x87,0x78,0x68,0x77,0x77,0x87,0x78,0x76,0x86,0x97,0x58,0x77,0x78,0x58,0x78,0x77,0x68,0x78,
+ 0x75,0x95,0xB7,0x70,0x8F,0x80,0xA6,0x87,0x65,0x66,0x78,0x7A,0x17,0x77,0x70,
+};
+
+static void SIT13_Func1(struct SIT13Data *s, struct SIT13Buffer *buf, uint32 info, uint16 bits, uint16 num)
+{
+ uint32 i, j;
+
+ if(bits <= 12)
+ {
+ for(i = 0; i < (1<<12); i += (1<<bits))
+ {
+ buf[info+i].data = num;
+ buf[info+i].bits = bits;
+ }
+ }
+ else
+ {
+ j = bits-12;
+
+ if(buf[info & 0xFFF].bits != 0x1F)
+ {
+ buf[info & 0xFFF].bits = 0x1F;
+ buf[info & 0xFFF].data = s->MaxBits++;
+ }
+ bits = buf[info & 0xFFF].data;
+ info >>= 12;
+
+ while(j--)
+ {
+ uint16 *a;
+
+ a = info & 1 ? &s->Buffer4[bits].d2 : &s->Buffer4[bits].d1;
+ if(!*a)
+ *a = s->MaxBits++;
+ bits = *a;
+ info >>= 1;
+ }
+ s->Buffer4[bits].freq = num;
+ }
+}
+
+static void SIT13_SortTree(struct SIT13Data *s, struct SIT13Buffer *buf, struct SIT13Buffer *buf2)
+{
+ uint16 td;
+ int8 tb;
+
+ struct SIT13Buffer *a, *b;
+
+ while(buf2-1 > buf)
+ {
+ a = buf;
+ b = buf2;
+
+ for(;;)
+ {
+ while(++a < buf2)
+ {
+ tb = a->bits - buf->bits;
+ if(tb > 0 || (!tb && (a->data >= buf->data)))
+ break;
+ }
+ while(--b > buf)
+ {
+ tb = b->bits - buf->bits;
+ if(tb < 0 || (!tb && (b->data <= buf->data)))
+ break;
+ }
+ if(b < a)
+ break;
+ else
+ {
+ tb = a->bits;
+ td = a->data;
+ a->bits = b->bits;
+ a->data = b->data;
+ b->bits = tb;
+ b->data = td;
+ }
+ }
+ if(b == buf)
+ ++buf;
+ else
+ {
+ tb = buf->bits;
+ td = buf->data;
+ buf->bits = b->bits;
+ buf->data = b->data;
+ b->bits = tb;
+ b->data = td;
+ if(buf2-b-1 > b-buf)
+ {
+ SIT13_SortTree(s, buf, b);
+ buf = b+1;
+ }
+ else
+ {
+ SIT13_SortTree(s, b+1, buf2);
+ buf2 = b;
+ }
+ }
+ }
+}
+
+static void SIT13_Func2(struct SIT13Data *s, struct SIT13Buffer *buf, uint16 bits, struct SIT13Buffer *buf2)
+{
+ int32 i, j, k, l, m, n;
+
+ SIT13_SortTree(s, buf2, buf2 + bits);
+
+ l = k = j = 0;
+ for(i = 0; i < bits; ++i)
+ {
+ l += k;
+ m = buf2[i].bits;
+ if(m != j)
+ {
+ if((j = m) == -1)
+ k = 0;
+ else
+ k = 1 << (32-j);
+ }
+ if(j > 0)
+ {
+ for(n = m = 0; n < 8*4; n += 4)
+ m += SIT13Bits[(l>>n)&0xF]<<(7*4-n);
+ SIT13_Func1(s, buf, m, j, buf2[i].data);
+ }
+ }
+}
+
+static void SIT13_CreateStaticTree(struct SIT13Data *s, struct SIT13Buffer *buf, uint16 bits, uint8 *bitsbuf)
+{
+ uint32 i;
+
+ for(i = 0; i < bits; ++i)
+ {
+ s->Buffer5[i].data = i;
+ s->Buffer5[i].bits = bitsbuf[i];
+ }
+ SIT13_Func2(s, buf, bits, s->Buffer5);
+}
+
+static void SIT13InitInfo(struct SIT13Data *s, uint8 id)
+{
+ int32 i;
+ uint8 k, l = 0, *a;
+ const uint8 *b;
+
+ a = s->TextBuf;
+ b = (const uint8 *) SIT13Static+SIT13StaticPos[id-1];
+ id &= 1;
+
+ for(i = 658; i; --i)
+ {
+ k = id ? *b >> 4 : *(b++) & 0xF; id ^=1;
+
+ if(!k)
+ {
+ l -= id ? *b >> 4 : *(b++) & 0xF; id ^= 1;
+ }
+ else
+ {
+ if(k == 15)
+ {
+ l += id ? *b >> 4 : *(b++) & 0xF; id ^= 1;
+ }
+ else
+ l += k-7;
+ }
+ *(a++) = l;
+ }
+}
+
+static bool SIT13_Extract(struct SIT13Data *s, Common::BitStream8LSB *bits, Common::MemoryWriteStream& out)
+{
+ uint32 wpos = 0, j, k, l, size;
+ struct SIT13Buffer *buf = s->Buffer3;
+
+ while(!bits->eos())
+ {
+ k = bits->peekBits<12>();
+ if((j = buf[k].bits) <= 12)
+ {
+ l = buf[k].data;
+ if (j == 0)
+ return false;
+ bits->getBits(j);
+ }
+ else
+ {
+ bits->getBits<12>();
+
+ j = buf[k].data;
+ while(s->Buffer4[j].freq == -1)
+ j = bits->getBit() ? s->Buffer4[j].d2 : s->Buffer4[j].d1;
+ l = s->Buffer4[j].freq;
+ }
+ if(l < 0x100)
+ {
+ s->Window[wpos++] = l;
+ out.writeByte(l);
+ wpos &= 0xFFFF;
+ buf = s->Buffer3;
+ }
+ else
+ {
+ buf = s->Buffer3b;
+ if(l < 0x13E)
+ size = l - 0x100 + 3;
+ else
+ {
+ if(l == 0x13E)
+ size = bits->getBits<10>();
+ else
+ {
+ if(l == 0x140)
+ return true;
+ size = bits->getBits<15>();
+ }
+ size += 65;
+ }
+ j = bits->peekBits<12>();
+ k = s->Buffer2[j].bits;
+ if(k <= 12)
+ {
+ l = s->Buffer2[j].data;
+ bits->getBits(k);
+ }
+ else
+ {
+ bits->getBits<12>();
+ j = s->Buffer2[j].data;
+ while(s->Buffer4[j].freq == -1)
+ j = bits->getBit() ? s->Buffer4[j].d2 : s->Buffer4[j].d1;
+ l = s->Buffer4[j].freq;
+ }
+ k = 0;
+ if(l--)
+ k = (1 << l) | bits->getBits(l);
+ l = wpos+0x10000-(k+1);
+ while(size--)
+ {
+ l &= 0xFFFF;
+ byte b = s->Window[l++];
+ out.writeByte(b);
+ s->Window[wpos++] = b;
+ wpos &= 0xFFFF;
+ }
+ } /* l >= 0x100 */
+ }
+
+ return false;
+}
+
+static void SIT13_CreateTree(struct SIT13Data *s, Common::BitStream8LSB *bits, struct SIT13Buffer *buf, uint16 num)
+{
+ struct SIT13Buffer *b;
+ uint32 i;
+ uint16 data;
+ int8 bi = 0;
+
+ for(i = 0; i < num; ++i)
+ {
+ b = &s->Buffer1[bits->peekBits<12>()];
+ data = b->data;
+ bits->getBits(b->bits);
+
+ switch(data-0x1F)
+ {
+ case 0: bi = -1; break;
+ case 1: ++bi; break;
+ case 2: --bi; break;
+ case 3:
+ if(bits->getBit())
+ s->Buffer5[i++].bits = bi;
+ break;
+ case 4:
+ data = bits->getBits<3>()+2;
+ while(data--)
+ s->Buffer5[i++].bits = bi;
+ break;
+ case 5:
+ data = bits->getBits<6>()+10;
+ while(data--)
+ s->Buffer5[i++].bits = bi;
+ break;
+ default: bi = data+1; break;
+ }
+ s->Buffer5[i].bits = bi;
+ }
+ for(i = 0; i < num; ++i)
+ s->Buffer5[i].data = i;
+ SIT13_Func2(s, buf, num, s->Buffer5);
+}
+
+bool StuffItArchive::decompress13(Common::SeekableReadStream *src, byte *dst, uint32 uncompressedSize) const {
+ Common::MemoryWriteStream out(dst, uncompressedSize);
+
+ Common::BitStream8LSB *bits = new Common::BitStream8LSB(src);
+
+ uint32 i, j;
+
+ SIT13Data *s = new SIT13Data();
+
+ s->MaxBits = 1;
+ for(i = 0; i < 37; ++i)
+ SIT13_Func1(s, s->Buffer1, SIT13Info[i], SIT13InfoBits[i], i);
+ for(i = 1; i < 0x704; ++i)
+ {
+ /* s->Buffer4[i].d1 = s->Buffer4[i].d2 = 0; */
+ s->Buffer4[i].freq = -1;
+ }
+
+ j = bits->getBits<8>();
+ i = j>>4;
+ if(i > 5)
+ return false;
+ if(i)
+ {
+ SIT13InitInfo(s, i--);
+ SIT13_CreateStaticTree(s, s->Buffer3, 0x141, s->TextBuf);
+ SIT13_CreateStaticTree(s, s->Buffer3b, 0x141, s->TextBuf+0x141);
+ SIT13_CreateStaticTree(s, s->Buffer2, SIT13StaticBits[i], s->TextBuf+0x282);
+ }
+ else
+ {
+ SIT13_CreateTree(s, bits, s->Buffer3, 0x141);
+ if(j&8)
+ memcpy(s->Buffer3b, s->Buffer3, 0x1000*sizeof(struct SIT13Buffer));
+ else
+ SIT13_CreateTree(s, bits, s->Buffer3b, 0x141);
+ j = (j&7)+10;
+ SIT13_CreateTree(s, bits, s->Buffer2, j);
+ }
+ return SIT13_Extract(s, bits, out);
+}
+
#define OUTPUT_VAL(x) \
out.writeByte(x); \
dat->window[j++] = x; \
Commit: 2c8fd71b479de32ba60f89fbc2fdf468cdd223f6
https://github.com/scummvm/scummvm/commit/2c8fd71b479de32ba60f89fbc2fdf468cdd223f6
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
KYRA: Switch to openFileOrDataFork
Changed paths:
engines/kyra/resource/resource.cpp
engines/kyra/resource/resource.h
engines/kyra/resource/resource_intern.cpp
engines/kyra/resource/resource_intern.h
diff --git a/engines/kyra/resource/resource.cpp b/engines/kyra/resource/resource.cpp
index 772b790e7c3..bde1adbf1f0 100644
--- a/engines/kyra/resource/resource.cpp
+++ b/engines/kyra/resource/resource.cpp
@@ -28,12 +28,9 @@
namespace Kyra {
-Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _macResMan(), _loaders(), _vm(vm), _bigEndianPlatForm(vm->gameFlags().platform == Common::kPlatformAmiga || vm->gameFlags().platform == Common::kPlatformSegaCD) {
+Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm), _bigEndianPlatForm(vm->gameFlags().platform == Common::kPlatformAmiga || vm->gameFlags().platform == Common::kPlatformSegaCD) {
initializeLoaders();
- if (_vm->gameFlags().useInstallerPackage)
- _macResMan = new Common::MacResManager();
-
// Initialize directories for playing from CD or with original
// directory structure
if (_vm->game() == GI_KYRA3)
@@ -55,7 +52,6 @@ Resource::~Resource() {
for (ArchiveMap::iterator i = _archiveCache.begin(); i != _archiveCache.end(); ++i)
delete i->_value;
_archiveCache.clear();
- delete _macResMan;
}
bool Resource::reset() {
@@ -406,7 +402,7 @@ Common::Archive *Resource::loadStuffItArchive(const Common::String &file) {
if (cachedArchive != _archiveCache.end())
return cachedArchive->_value;
- Common::Archive *archive = StuffItLoader::load(this, file, _macResMan);
+ Common::Archive *archive = StuffItLoader::load(this, file);
if (!archive)
return nullptr;
diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h
index 11604872489..b2460a97055 100644
--- a/engines/kyra/resource/resource.h
+++ b/engines/kyra/resource/resource.h
@@ -95,8 +95,6 @@ protected:
Common::SearchSet _archiveFiles;
Common::SearchSet _protectedFiles;
- Common::MacResManager *_macResMan;
-
Common::Archive *loadArchive(const Common::String &name, Common::ArchiveMemberPtr member);
Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
Common::Archive *loadStuffItArchive(const Common::String &file);
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index 2c520527666..b3b0d595f17 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -1217,13 +1217,11 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
return new CachedArchive(fileList);
}
-Common::Archive *StuffItLoader::load(Resource *owner, const Common::String &filename, Common::MacResManager *macResMan) {
- if (macResMan->open(filename)) {
- Common::SeekableReadStream *stream = macResMan->getDataFork();
- if (stream) {
- Common::Archive *archive = Common::createStuffItArchive(stream);
- return archive;
- }
+Common::Archive *StuffItLoader::load(Resource *owner, const Common::String &filename) {
+ Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(filename);
+ if (stream) {
+ Common::Archive *archive = Common::createStuffItArchive(stream);
+ return archive;
}
error("StuffItLoader::load: Could not load %s", filename.c_str());
diff --git a/engines/kyra/resource/resource_intern.h b/engines/kyra/resource/resource_intern.h
index cf8c1ff7ca1..216a76c7916 100644
--- a/engines/kyra/resource/resource_intern.h
+++ b/engines/kyra/resource/resource_intern.h
@@ -144,7 +144,7 @@ public:
class StuffItLoader {
public:
- static Common::Archive *load(Resource *owner, const Common::String &filename, Common::MacResManager *macResMan);
+ static Common::Archive *load(Resource *owner, const Common::String &filename);
};
} // End of namespace Kyra
Commit: 9f4d744b46509174c37b74039dee1b7a2a02547a
https://github.com/scummvm/scummvm/commit/9f4d744b46509174c37b74039dee1b7a2a02547a
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
KYRA: Store cached installer mac archive as its simple name
This avoids the complexity of discovering its name again.
It makes supporting multi-floppy installer much less hairy as well
Changed paths:
engines/kyra/resource/resource.cpp
engines/kyra/resource/resource.h
engines/kyra/sound/sound_mac_lok.cpp
diff --git a/engines/kyra/resource/resource.cpp b/engines/kyra/resource/resource.cpp
index bde1adbf1f0..fabefedaee7 100644
--- a/engines/kyra/resource/resource.cpp
+++ b/engines/kyra/resource/resource.cpp
@@ -69,7 +69,7 @@ bool Resource::reset() {
error("Could not find Legend of Kyrandia installer file");
}
- Common::Archive *archive = loadStuffItArchive(kyraInstaller);
+ Common::Archive *archive = loadStuffItArchive(kyraInstaller, "Install Legend of Kyrandia");
if (!archive)
error("Failed to load Legend of Kyrandia installer file");
@@ -397,8 +397,8 @@ Common::Archive *Resource::loadInstallerArchive(const Common::String &file, cons
return archive;
}
-Common::Archive *Resource::loadStuffItArchive(const Common::String &file) {
- ArchiveMap::iterator cachedArchive = _archiveCache.find(file);
+Common::Archive *Resource::loadStuffItArchive(const Common::String &file, const Common::String& canonicalName) {
+ ArchiveMap::iterator cachedArchive = _archiveCache.find(canonicalName);
if (cachedArchive != _archiveCache.end())
return cachedArchive->_value;
@@ -406,7 +406,7 @@ Common::Archive *Resource::loadStuffItArchive(const Common::String &file) {
if (!archive)
return nullptr;
- _archiveCache[file] = archive;
+ _archiveCache[canonicalName] = archive;
return archive;
}
diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h
index b2460a97055..61d61ad81c7 100644
--- a/engines/kyra/resource/resource.h
+++ b/engines/kyra/resource/resource.h
@@ -97,7 +97,7 @@ protected:
Common::Archive *loadArchive(const Common::String &name, Common::ArchiveMemberPtr member);
Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
- Common::Archive *loadStuffItArchive(const Common::String &file);
+ Common::Archive *loadStuffItArchive(const Common::String &file, const Common::String& canonicalName);
bool loadProtectedFiles(const char *const * list);
diff --git a/engines/kyra/sound/sound_mac_lok.cpp b/engines/kyra/sound/sound_mac_lok.cpp
index abf5985a7c3..52819e54b4e 100644
--- a/engines/kyra/sound/sound_mac_lok.cpp
+++ b/engines/kyra/sound/sound_mac_lok.cpp
@@ -40,10 +40,7 @@ SoundMacRes::SoundMacRes(KyraEngine_v1 *vm) : _resMan(0), _stuffItArchive(nullpt
_resMan = new Common::MacResManager[2];
if (vm->gameFlags().useInstallerPackage) {
- Common::String str = Util::findMacResourceFile("Install Legend of Kyrandia");
- if (str.empty())
- error("SoundMacRes::SoundMacRes(): Could not find Legend of Kyrandia installer file");
- _stuffItArchive = vm->resource()->getCachedArchive(str);
+ _stuffItArchive = vm->resource()->getCachedArchive("Install Legend of Kyrandia");
if (!_stuffItArchive)
error("SoundMacRes::SoundMacRes(): Failed to load Legend of Kyrandia installer file");
}
Commit: 1b90cea645b86887c815b21b3873ccf6fec9a80f
https://github.com/scummvm/scummvm/commit/1b90cea645b86887c815b21b3873ccf6fec9a80f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
KYRA: Support loading stuffit archive from abstract stream
Multi-floppy installer needs to use a fake stream composed from several
real files.
Changed paths:
engines/kyra/resource/resource.cpp
engines/kyra/resource/resource.h
engines/kyra/resource/resource_intern.cpp
engines/kyra/resource/resource_intern.h
diff --git a/engines/kyra/resource/resource.cpp b/engines/kyra/resource/resource.cpp
index fabefedaee7..b8f85c18763 100644
--- a/engines/kyra/resource/resource.cpp
+++ b/engines/kyra/resource/resource.cpp
@@ -410,6 +410,21 @@ Common::Archive *Resource::loadStuffItArchive(const Common::String &file, const
return archive;
}
+Common::Archive *Resource::loadStuffItArchive(Common::SeekableReadStream *stream, const Common::String& canonicalName, const Common::String& debugName) {
+ ArchiveMap::iterator cachedArchive = _archiveCache.find(canonicalName);
+ if (cachedArchive != _archiveCache.end()) {
+ delete stream;
+ return cachedArchive->_value;
+ }
+
+ Common::Archive *archive = StuffItLoader::load(this, stream, debugName);
+ if (!archive)
+ return nullptr;
+
+ _archiveCache[canonicalName] = archive;
+ return archive;
+}
+
#pragma mark -
void Resource::initializeLoaders() {
diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h
index 61d61ad81c7..e4bbdf63b30 100644
--- a/engines/kyra/resource/resource.h
+++ b/engines/kyra/resource/resource.h
@@ -98,6 +98,7 @@ protected:
Common::Archive *loadArchive(const Common::String &name, Common::ArchiveMemberPtr member);
Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
Common::Archive *loadStuffItArchive(const Common::String &file, const Common::String& canonicalName);
+ Common::Archive *loadStuffItArchive(Common::SeekableReadStream *stream, const Common::String& canonicalName, const Common::String& debugName);
bool loadProtectedFiles(const char *const * list);
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index b3b0d595f17..64a53ac553b 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -1218,13 +1218,16 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
}
Common::Archive *StuffItLoader::load(Resource *owner, const Common::String &filename) {
- Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(filename);
+ return load(owner, Common::MacResManager::openFileOrDataFork(filename), filename);
+}
+
+Common::Archive *StuffItLoader::load(Resource *owner, Common::SeekableReadStream *stream, const Common::String& debugName) {
if (stream) {
Common::Archive *archive = Common::createStuffItArchive(stream);
return archive;
}
- error("StuffItLoader::load: Could not load %s", filename.c_str());
+ error("StuffItLoader::load: Could not load %s", debugName.c_str());
}
CmpVocDecoder::CmpVocDecoder() {
diff --git a/engines/kyra/resource/resource_intern.h b/engines/kyra/resource/resource_intern.h
index 216a76c7916..be17623fac1 100644
--- a/engines/kyra/resource/resource_intern.h
+++ b/engines/kyra/resource/resource_intern.h
@@ -145,6 +145,7 @@ public:
class StuffItLoader {
public:
static Common::Archive *load(Resource *owner, const Common::String &filename);
+ static Common::Archive *load(Resource *owner, Common::SeekableReadStream *stream, const Common::String &debugName);
};
} // End of namespace Kyra
Commit: d7aa54bf30df79e84a27d0358c736601d2a9d04f
https://github.com/scummvm/scummvm/commit/d7aa54bf30df79e84a27d0358c736601d2a9d04f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2022-12-08T00:02:39+01:00
Commit Message:
KYRA: Support multi-floppy installer
Changed paths:
engines/kyra/detection_tables.h
engines/kyra/engine/util.cpp
engines/kyra/engine/util.h
engines/kyra/resource/resource.cpp
engines/kyra/resource/resource.h
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 41972c8851f..88010519c15 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -312,6 +312,19 @@ const KYRAGameDescription adGameDescs[] = {
KYRA1_FLOPPY_FLAGS
},
+ {
+ {
+ "kyra1",
+ "StuffIt multi-floppy",
+ AD_ENTRY1s("xn--Legend of Kyrandia Installer-o11r", "83d0f8e8c44a0aaa92b06081c40cd3c2", 69726),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_MACRESFORK,
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIGM, GUIO_RENDERVGA)
+ },
+ KYRA1_FLOPPY_CMP_FLAGS
+ },
+
{
{
"kyra1",
diff --git a/engines/kyra/engine/util.cpp b/engines/kyra/engine/util.cpp
index 4e451484f25..01931848f33 100644
--- a/engines/kyra/engine/util.cpp
+++ b/engines/kyra/engine/util.cpp
@@ -289,7 +289,7 @@ Common::String Util::decodeString2(const Common::String &src) {
return reslt;
}
-Common::String Util::findMacResourceFile(const char *baseName) {
+Common::String Util::findMacResourceFile(const char *baseName, const char *suffix) {
// The original executable has a TM char as its last character (character
// 0xAA from Mac code page). Depending on the emulator or platform used to
// copy the file it might have been reencoded to something else. So I look
@@ -308,7 +308,7 @@ Common::String Util::findMacResourceFile(const char *baseName) {
for (int i = 0; i < 2; ++i) {
for (int ii = 0; ii < ARRAYSIZE(tryCodePages); ++ii) {
- Common::U32String fn(tryName, tryCodePages[ii]);
+ Common::U32String fn(tryName + suffix, tryCodePages[ii]);
fileName = fn.encode(Common::kUtf8);
if (resource.exists(fileName))
return fileName;
diff --git a/engines/kyra/engine/util.h b/engines/kyra/engine/util.h
index 80aa9741210..fb6fc2c6229 100644
--- a/engines/kyra/engine/util.h
+++ b/engines/kyra/engine/util.h
@@ -48,7 +48,7 @@ public:
// e. g. when typing a one-byte character, like a digit).
static void mergeUpdateJohabChars(uint16 &destJohabChar0, uint16 &destJohabChar1, char asciiInput, bool reset);
- static Common::String findMacResourceFile(const char *baseName);
+ static Common::String findMacResourceFile(const char *baseName, const char *suffix = "");
private:
struct DOS2JOHABEntry {
diff --git a/engines/kyra/resource/resource.cpp b/engines/kyra/resource/resource.cpp
index b8f85c18763..70eeac7d77c 100644
--- a/engines/kyra/resource/resource.cpp
+++ b/engines/kyra/resource/resource.cpp
@@ -23,11 +23,44 @@
#include "kyra/resource/resource.h"
#include "kyra/resource/resource_intern.h"
+#include "common/macresman.h"
+#include "common/compression/stuffit.h"
+#include "common/concatstream.h"
#include "common/config-manager.h"
#include "common/fs.h"
+#include "common/substream.h"
namespace Kyra {
+Common::Archive *Resource::loadKyra1MacInstaller() {
+ Common::String kyraInstaller = Util::findMacResourceFile("Install Legend of Kyrandia");
+
+ if (!kyraInstaller.empty()) {
+ Common::Archive *archive = loadStuffItArchive(kyraInstaller, "Install Legend of Kyrandia");
+ if (!archive)
+ error("Failed to load Legend of Kyrandia installer file");
+ return archive;
+ }
+
+ kyraInstaller = Util::findMacResourceFile("Legend of Kyrandia", " Installer");
+
+ if (!kyraInstaller.empty()) {
+ Common::Array<Common::SharedPtr<Common::SeekableReadStream>> parts;
+ for (int i = 1; i <= 5; i++) {
+ Common::String partName = i == 1 ? kyraInstaller : Common::String::format("%s.%d", kyraInstaller.c_str(), i);
+ Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(partName);
+ if (!stream)
+ error("Failed to load Legend of Kyrandia installer file part %s", partName.c_str());
+ if (stream->size() <= 100)
+ error("Legend of Kyrandia installer file part %s is too short", partName.c_str());
+ parts.push_back(Common::SharedPtr<Common::SeekableReadStream>(new Common::SeekableSubReadStream(stream, 100, stream->size(), DisposeAfterUse::YES)));
+ }
+ return loadStuffItArchive(new Common::ConcatReadStream(parts), "Install Legend of Kyrandia", "Legend of Kyrandia(TM) Installer.*");
+ }
+
+ return nullptr;
+}
+
Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm), _bigEndianPlatForm(vm->gameFlags().platform == Common::kPlatformAmiga || vm->gameFlags().platform == Common::kPlatformSegaCD) {
initializeLoaders();
@@ -63,15 +96,9 @@ bool Resource::reset() {
error("invalid game path '%s'", dir.getPath().c_str());
if (_vm->game() == GI_KYRA1 && _vm->gameFlags().platform == Common::kPlatformMacintosh && _vm->gameFlags().useInstallerPackage) {
- Common::String kyraInstaller = Util::findMacResourceFile("Install Legend of Kyrandia");
-
- if (kyraInstaller.empty()) {
- error("Could not find Legend of Kyrandia installer file");
- }
-
- Common::Archive *archive = loadStuffItArchive(kyraInstaller, "Install Legend of Kyrandia");
+ Common::Archive *archive = loadKyra1MacInstaller();
if (!archive)
- error("Failed to load Legend of Kyrandia installer file");
+ error("Could not find Legend of Kyrandia installer file");
_files.add("installer", archive, 0, false);
diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h
index e4bbdf63b30..407b73c5253 100644
--- a/engines/kyra/resource/resource.h
+++ b/engines/kyra/resource/resource.h
@@ -99,6 +99,7 @@ protected:
Common::Archive *loadInstallerArchive(const Common::String &file, const Common::String &ext, const uint8 offset);
Common::Archive *loadStuffItArchive(const Common::String &file, const Common::String& canonicalName);
Common::Archive *loadStuffItArchive(Common::SeekableReadStream *stream, const Common::String& canonicalName, const Common::String& debugName);
+ Common::Archive *loadKyra1MacInstaller();
bool loadProtectedFiles(const char *const * list);
More information about the Scummvm-git-logs
mailing list