[Scummvm-git-logs] scummvm master -> 047184a1b5d8254e5ed844b9952c5595341c0c38
sev-
noreply at scummvm.org
Mon Mar 13 22:26:03 UTC 2023
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
2a2217cb46 DIRECTOR: Add ProjectorArchive
ea9d0d39f8 JANITORIAL: Fix code formatting issues in ProjectorArchive
e10f756d68 DIRECTOR: Use BufferedStream in ProjectorArchive
7ee8e6653c DIRECTOR: Return false on failure in ProjectorArchive
3f49fca324 DIRECTOR: Check for invalid seeks in ProjectorArchive
7172b7620a DIRECTOR: Prefix warnings with BUILDBOT in ProjectorArchive
58ff07f4a6 DIRECTOR: ProjectorArchive filemap offset needs to be 32 bit only
325594ab0b DIRECTOR: Offset to PJXX tags is always in fixed endian
a15208bded DIRECTOR: Fix incorrect dict parsing in ProjectorArchive
047184a1b5 DIRECTOR: Fix alignment issue during seeking in ProjectorArchive
Commit: 2a2217cb46132403bb50b529b8fe2219f795b0cb
https://github.com/scummvm/scummvm/commit/2a2217cb46132403bb50b529b8fe2219f795b0cb
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Add ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 9b27f263261..8402efc1fed 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -23,6 +23,7 @@
#include "common/error.h"
#include "common/file.h"
#include "common/macresman.h"
+#include "common/memstream.h"
#include "common/substream.h"
#include "common/formats/winexe.h"
#include "graphics/wincursor.h"
@@ -522,5 +523,173 @@ void Window::loadStartMovieXLibs() {
}
g_lingo->openXLib("SerialPort", kXObj);
}
+class ProjectorArchive : public Common::Archive {
+public:
+ ProjectorArchive(Common::String path);
+ ~ProjectorArchive() override;
+
+ 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;
+private:
+ int Load(Common::SeekableReadStream *stream);
+
+ struct Entry {
+ uint64 offset;
+ uint32 size;
+ };
+ typedef Common::HashMap<Common::String, Entry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
+ FileMap _files;
+ Common::String _path;
+};
+
+ProjectorArchive::ProjectorArchive(Common::String path)
+ : _path(path), _files() {
+
+ // We'll first build our fileMap
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(path);
+ if (!stream)
+ error("ProjectorArchive::ProjectorArchive(): Cannot open %s", path.c_str());
+ Load(stream);
+ delete stream;
+}
+
+ProjectorArchive::~ProjectorArchive() {
+ _files.clear();
+}
+
+int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
+ bool bigEndian = true, found = false;
+ uint32 off, tag, rifxOffset;
+
+ // Assume the endianness of the file and try to locate the PJXX tags
+ for(int i = 0; i < 2; i++) {
+ bigEndian = !bigEndian;
+ stream->seek(-4, SEEK_END);
+ off = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ stream->seek(off);
+ tag = stream->readUint32BE();
+
+ if (((tag & 0xffff0000) == MKTAG('P','J', 0, 0)) || ((tag & 0x0000ffff) == MKTAG(0, 0,'J','P'))) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ warning("ProjectorArchive::Load(): Projector Tag not found");
+ return true;
+ }
+ rifxOffset = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ stream->seek(rifxOffset);
+ tag = stream->readUint32BE();
+ debugC(1, kDebugLoading, "File: %s off: 0x%x, tag: %s rifx: 0x%x", _path.c_str(), off, tag2str(tag), rifxOffset);
+
+ //Try to locate the very next Dict tag
+ tag = stream->readUint32BE();
+ found = false;
+ while (!stream->eos()) {
+ if (tag == MKTAG('D', 'i', 'c', 't') || tag == MKTAG('t', 'c', 'i', 'D')) {
+ found = true;
+ break;
+ }
+ tag = stream->readUint32BE();
+ }
+
+ // Return if dict tag is not found
+ if (!found) {
+ warning("ProjectorArchive::Load(): Dict Tag not found.");
+ return true;
+ }
+
+ uint32 size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ uint32 dictOff = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+
+ // Jump to the actual dict block and begin parsing
+ stream->seek(dictOff);
+ tag = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ stream->seek(dictOff + 24);
+ uint32 cnt = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ int8 offsetDict = 0;
+ bool oBigEndian = bigEndian;
+
+ if (cnt > 0xFFFF) {
+ cnt = SWAP_BYTES_32(cnt);
+ offsetDict = 2;
+ bigEndian = true;
+ }
+
+ debugC(1, kDebugLoading, "Dict off: 0x%x, Size: 0x%x cnt: %d", dictOff, size, cnt);
+ uint32 pt = (cnt * 8) + (64 - offsetDict);
+ Common::StringArray arr(cnt);
+
+ for (uint32 i = 0; i < cnt; i++) {
+ stream->seek(dictOff + pt, SEEK_SET);
+ uint32 namelen = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ arr[i] = stream->readString(0, namelen);
+ if (i < cnt - 1) {
+ int sub = (namelen % 4) ? (namelen % 4) : 4;
+ pt += 4 + namelen + (4 - sub);
+ }
+ }
+
+ bigEndian = oBigEndian;
+
+ for (uint32 i = 0; i < cnt; i++) {
+ tag = stream->readUint32BE();
+ size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ debugC(1, kDebugLoading, "Entry: %s offset %llX tag %s size %d", arr[i].c_str(), stream->pos() - 8, tag2str(tag), size);
+ Entry entry;
+ // subtract 8 since we want to include tag and size as well
+ entry.offset = stream->pos() - 8;
+ entry.size = size + 8;
+ _files[arr[i]] = entry;
+ stream->seek(size, SEEK_CUR);
+ }
+
+ return false;
+}
+
+bool ProjectorArchive::hasFile(const Common::Path &path) const {
+ Common::String name = path.toString();
+ return (_files.find(name) != _files.end());
+}
+
+int ProjectorArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int count = 0;
+
+ for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
+ ++count;
+ }
+
+ return count;
+}
+
+const Common::ArchiveMemberPtr ProjectorArchive::getMember(const Common::Path &path) const {
+ Common::String name = path.toString();
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *ProjectorArchive::createReadStreamForMember(const Common::Path &path) const {
+ Common::String name = path.toString();
+ FileMap::const_iterator fDesc = _files.find(name);
+ if (fDesc == _files.end())
+ return nullptr;
+
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(_path);
+
+ stream->seek(fDesc->_value.offset, SEEK_SET);
+ byte *data = (byte *)malloc(fDesc->_value.size);
+ stream->read(data, fDesc->_value.size);
+ delete stream;
+
+ return new Common::MemoryReadStream(data, fDesc->_value.size, DisposeAfterUse::YES);
+}
} // End of namespace Director
Commit: ea9d0d39f81f3de01045b3362a8514d8966f70bb
https://github.com/scummvm/scummvm/commit/ea9d0d39f81f3de01045b3362a8514d8966f70bb
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
JANITORIAL: Fix code formatting issues in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 8402efc1fed..36529bc9bf5 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -523,6 +523,13 @@ void Window::loadStartMovieXLibs() {
}
g_lingo->openXLib("SerialPort", kXObj);
}
+
+/*******************************************
+ *
+ * Projector Archive
+ *
+ *******************************************/
+
class ProjectorArchive : public Common::Archive {
public:
ProjectorArchive(Common::String path);
@@ -532,8 +539,9 @@ public:
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;
+
private:
- int Load(Common::SeekableReadStream *stream);
+ bool loadArchive(Common::SeekableReadStream *stream);
struct Entry {
uint64 offset;
@@ -551,7 +559,8 @@ ProjectorArchive::ProjectorArchive(Common::String path)
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(path);
if (!stream)
error("ProjectorArchive::ProjectorArchive(): Cannot open %s", path.c_str());
- Load(stream);
+
+ loadArchive(stream);
delete stream;
}
@@ -559,35 +568,37 @@ ProjectorArchive::~ProjectorArchive() {
_files.clear();
}
-int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
+bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
bool bigEndian = true, found = false;
uint32 off, tag, rifxOffset;
- // Assume the endianness of the file and try to locate the PJXX tags
- for(int i = 0; i < 2; i++) {
+ // Assume the endianness of the file and try to locate the PJXX tag
+ for (int i = 0; i < 2; i++) {
bigEndian = !bigEndian;
stream->seek(-4, SEEK_END);
off = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
stream->seek(off);
tag = stream->readUint32BE();
- if (((tag & 0xffff0000) == MKTAG('P','J', 0, 0)) || ((tag & 0x0000ffff) == MKTAG(0, 0,'J','P'))) {
+ // Check whether we got a 'PJ' tag while ignoring the version and accounting for endianness
+ if (((tag & 0xffff0000) == MKTAG('P','J', 0, 0)) || ((tag & 0x0000ffff) == MKTAG(0, 0, 'J','P'))) {
found = true;
break;
}
}
if (!found) {
- warning("ProjectorArchive::Load(): Projector Tag not found");
+ warning("ProjectorArchive::loadArchive(): Projector Tag not found");
return true;
}
rifxOffset = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
stream->seek(rifxOffset);
tag = stream->readUint32BE();
+
debugC(1, kDebugLoading, "File: %s off: 0x%x, tag: %s rifx: 0x%x", _path.c_str(), off, tag2str(tag), rifxOffset);
- //Try to locate the very next Dict tag
+ // Try to locate the very next Dict tag
tag = stream->readUint32BE();
found = false;
while (!stream->eos()) {
@@ -600,7 +611,7 @@ int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
// Return if dict tag is not found
if (!found) {
- warning("ProjectorArchive::Load(): Dict Tag not found.");
+ warning("ProjectorArchive::loadArchive(): Dict Tag not found.");
return true;
}
@@ -623,6 +634,7 @@ int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
}
debugC(1, kDebugLoading, "Dict off: 0x%x, Size: 0x%x cnt: %d", dictOff, size, cnt);
+
uint32 pt = (cnt * 8) + (64 - offsetDict);
Common::StringArray arr(cnt);
@@ -630,6 +642,7 @@ int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
stream->seek(dictOff + pt, SEEK_SET);
uint32 namelen = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
arr[i] = stream->readString(0, namelen);
+
if (i < cnt - 1) {
int sub = (namelen % 4) ? (namelen % 4) : 4;
pt += 4 + namelen + (4 - sub);
@@ -641,12 +654,16 @@ int ProjectorArchive::Load(Common::SeekableReadStream *stream) {
for (uint32 i = 0; i < cnt; i++) {
tag = stream->readUint32BE();
size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+
debugC(1, kDebugLoading, "Entry: %s offset %llX tag %s size %d", arr[i].c_str(), stream->pos() - 8, tag2str(tag), size);
+
Entry entry;
+
// subtract 8 since we want to include tag and size as well
entry.offset = stream->pos() - 8;
entry.size = size + 8;
_files[arr[i]] = entry;
+
stream->seek(size, SEEK_CUR);
}
@@ -671,6 +688,7 @@ int ProjectorArchive::listMembers(Common::ArchiveMemberList &list) const {
const Common::ArchiveMemberPtr ProjectorArchive::getMember(const Common::Path &path) const {
Common::String name = path.toString();
+
if (!hasFile(name))
return Common::ArchiveMemberPtr();
@@ -680,6 +698,7 @@ const Common::ArchiveMemberPtr ProjectorArchive::getMember(const Common::Path &p
Common::SeekableReadStream *ProjectorArchive::createReadStreamForMember(const Common::Path &path) const {
Common::String name = path.toString();
FileMap::const_iterator fDesc = _files.find(name);
+
if (fDesc == _files.end())
return nullptr;
Commit: e10f756d6813b38c04ed6045926c1bc37709535e
https://github.com/scummvm/scummvm/commit/e10f756d6813b38c04ed6045926c1bc37709535e
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Use BufferedStream in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 36529bc9bf5..87c38afedec 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -24,6 +24,7 @@
#include "common/file.h"
#include "common/macresman.h"
#include "common/memstream.h"
+#include "common/bufferedstream.h"
#include "common/substream.h"
#include "common/formats/winexe.h"
#include "graphics/wincursor.h"
@@ -541,6 +542,7 @@ public:
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
private:
+ Common::SeekableReadStream *createBufferedReadStream();
bool loadArchive(Common::SeekableReadStream *stream);
struct Entry {
@@ -555,15 +557,25 @@ private:
ProjectorArchive::ProjectorArchive(Common::String path)
: _path(path), _files() {
- // We'll first build our fileMap
- Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(path);
- if (!stream)
- error("ProjectorArchive::ProjectorArchive(): Cannot open %s", path.c_str());
+ // Buffer 100K into memory
+ Common::SeekableReadStream *stream = createBufferedReadStream();
+ // Build our filemap using the buffered stream
loadArchive(stream);
+
delete stream;
}
+Common::SeekableReadStream *ProjectorArchive::createBufferedReadStream() {
+ const uint32 READ_BUFFER_SIZE = 1024 * 100;
+
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(_path);
+ if (!stream)
+ error("ProjectorArchive::createBufferedReadStream(): Cannot open %s", _path.c_str());
+
+ return Common::wrapBufferedSeekableReadStream(stream, READ_BUFFER_SIZE, DisposeAfterUse::NO);
+}
+
ProjectorArchive::~ProjectorArchive() {
_files.clear();
}
@@ -598,14 +610,19 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
debugC(1, kDebugLoading, "File: %s off: 0x%x, tag: %s rifx: 0x%x", _path.c_str(), off, tag2str(tag), rifxOffset);
- // Try to locate the very next Dict tag
+ // Try to locate the very next Dict tag(byte-by-byte)
tag = stream->readUint32BE();
found = false;
+
+ // This loop has neglible performance impact due to the stream being buffered.
+ // Furthermore, comparing 4 bytes at a time should be pretty fast on mordern systems.
while (!stream->eos()) {
if (tag == MKTAG('D', 'i', 'c', 't') || tag == MKTAG('t', 'c', 'i', 'D')) {
found = true;
break;
}
+
+ stream->seek(-3, SEEK_CUR);
tag = stream->readUint32BE();
}
@@ -627,6 +644,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
int8 offsetDict = 0;
bool oBigEndian = bigEndian;
+ // For 16-bit win projector
if (cnt > 0xFFFF) {
cnt = SWAP_BYTES_32(cnt);
offsetDict = 2;
Commit: 7ee8e6653c904f3c5b05b6a38dcc196de0d86303
https://github.com/scummvm/scummvm/commit/7ee8e6653c904f3c5b05b6a38dcc196de0d86303
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Return false on failure in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 87c38afedec..fa408c8ae7d 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -601,7 +601,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
if (!found) {
warning("ProjectorArchive::loadArchive(): Projector Tag not found");
- return true;
+ return false;
}
rifxOffset = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
@@ -629,7 +629,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
// Return if dict tag is not found
if (!found) {
warning("ProjectorArchive::loadArchive(): Dict Tag not found.");
- return true;
+ return false;
}
uint32 size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
@@ -685,7 +685,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
stream->seek(size, SEEK_CUR);
}
- return false;
+ return true;
}
bool ProjectorArchive::hasFile(const Common::Path &path) const {
Commit: 3f49fca324362f67e74a43a431632598969e90d8
https://github.com/scummvm/scummvm/commit/3f49fca324362f67e74a43a431632598969e90d8
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Check for invalid seeks in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index fa408c8ae7d..25e70c2eb4b 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -635,8 +635,12 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
uint32 size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
uint32 dictOff = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
- // Jump to the actual dict block and begin parsing
- stream->seek(dictOff);
+ // Jump to the actual dict block and parse it
+ if (!stream->seek(dictOff)) {
+ warning("ProjectorArchive::loadArchive(): Incorrect dict offset (0x%x)", dictOff);
+ return false;
+ }
+
tag = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
stream->seek(dictOff + 24);
@@ -657,7 +661,12 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
Common::StringArray arr(cnt);
for (uint32 i = 0; i < cnt; i++) {
- stream->seek(dictOff + pt, SEEK_SET);
+ // if this fails it likely means that the dict was invalid.
+ if (!stream->seek(dictOff + pt, SEEK_SET)) {
+ warning("ProjectorArchive::loadArchive(): Incorrect entry name offset (0x%x)", dictOff + pt);
+ return false;
+ }
+
uint32 namelen = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
arr[i] = stream->readString(0, namelen);
@@ -682,7 +691,12 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
entry.size = size + 8;
_files[arr[i]] = entry;
- stream->seek(size, SEEK_CUR);
+ // if this fails it suggests something is either wrong with the dict or the file itself.
+ if (!stream->seek(size, SEEK_CUR)) {
+ warning("ProjectorArchive::loadArchive(): Could not read next block (0x%x) Prev Block(0x%x : %d)",
+ entry.offset + entry.size, entry.offset, entry.size);
+ return false;
+ }
}
return true;
Commit: 7172b7620ad7752cdec76f5fff2728274b3aae4a
https://github.com/scummvm/scummvm/commit/7172b7620ad7752cdec76f5fff2728274b3aae4a
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Prefix warnings with BUILDBOT in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 25e70c2eb4b..bb3023aba9e 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -637,7 +637,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
// Jump to the actual dict block and parse it
if (!stream->seek(dictOff)) {
- warning("ProjectorArchive::loadArchive(): Incorrect dict offset (0x%x)", dictOff);
+ warning("BUILDBOT: ProjectorArchive::loadArchive(): Incorrect dict offset (0x%x)", dictOff);
return false;
}
Commit: 58ff07f4a67b4c1c23d6a15e92eac0a79e192ba6
https://github.com/scummvm/scummvm/commit/58ff07f4a67b4c1c23d6a15e92eac0a79e192ba6
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: ProjectorArchive filemap offset needs to be 32 bit only
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index bb3023aba9e..fdd03cd2342 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -546,7 +546,7 @@ private:
bool loadArchive(Common::SeekableReadStream *stream);
struct Entry {
- uint64 offset;
+ uint32 offset;
uint32 size;
};
typedef Common::HashMap<Common::String, Entry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
@@ -687,7 +687,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
Entry entry;
// subtract 8 since we want to include tag and size as well
- entry.offset = stream->pos() - 8;
+ entry.offset = static_cast<uint32>(stream->pos() - 8);
entry.size = size + 8;
_files[arr[i]] = entry;
Commit: 325594ab0bedd3d8384e1f91b7140dbc9782a6bc
https://github.com/scummvm/scummvm/commit/325594ab0bedd3d8384e1f91b7140dbc9782a6bc
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Offset to PJXX tags is always in fixed endian
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index fdd03cd2342..1f3d51d47b4 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -581,25 +581,16 @@ ProjectorArchive::~ProjectorArchive() {
}
bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
- bool bigEndian = true, found = false;
+ bool bigEndian = false, found = false;
uint32 off, tag, rifxOffset;
- // Assume the endianness of the file and try to locate the PJXX tag
- for (int i = 0; i < 2; i++) {
- bigEndian = !bigEndian;
- stream->seek(-4, SEEK_END);
- off = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
- stream->seek(off);
- tag = stream->readUint32BE();
-
- // Check whether we got a 'PJ' tag while ignoring the version and accounting for endianness
- if (((tag & 0xffff0000) == MKTAG('P','J', 0, 0)) || ((tag & 0x0000ffff) == MKTAG(0, 0, 'J','P'))) {
- found = true;
- break;
- }
- }
+ stream->seek(-4, SEEK_END);
+ off = stream->readUint32LE();
+ stream->seek(off);
+ tag = stream->readUint32BE();
- if (!found) {
+ // Check whether we got a 'PJ' tag while ignoring the version and accounting for endianness
+ if (((tag & 0xffff0000) != MKTAG('P','J', 0, 0)) && ((tag & 0x0000ffff) != MKTAG(0, 0, 'J','P'))) {
warning("ProjectorArchive::loadArchive(): Projector Tag not found");
return false;
}
Commit: a15208bded47e800d3f007683664c736c43ba0d7
https://github.com/scummvm/scummvm/commit/a15208bded47e800d3f007683664c736c43ba0d7
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Fix incorrect dict parsing in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 1f3d51d47b4..e44782b6271 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -595,7 +595,14 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
return false;
}
- rifxOffset = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ rifxOffset = stream->readUint32LE();
+
+ // if value is bigger than the stream size this is most likely a endianness issue.
+ if (rifxOffset > stream->size()) {
+ bigEndian = true;
+ rifxOffset = SWAP_BYTES_32(rifxOffset);
+ }
+
stream->seek(rifxOffset);
tag = stream->readUint32BE();
@@ -636,7 +643,9 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
stream->seek(dictOff + 24);
uint32 cnt = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
- int8 offsetDict = 0;
+
+ // Correction for when there is only a single element present according to the dict
+ uint8 offsetDict = bigEndian && cnt == 1 ? 2 : 0;
bool oBigEndian = bigEndian;
// For 16-bit win projector
@@ -669,6 +678,9 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
bigEndian = oBigEndian;
+ // The first block would start right after the dict.
+ stream->seek(dictOff + size + 8, SEEK_SET);
+
for (uint32 i = 0; i < cnt; i++) {
tag = stream->readUint32BE();
size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
Commit: 047184a1b5d8254e5ed844b9952c5595341c0c38
https://github.com/scummvm/scummvm/commit/047184a1b5d8254e5ed844b9952c5595341c0c38
Author: hax0kartik (agarwala.kartik at gmail.com)
Date: 2023-03-13T23:25:55+01:00
Commit Message:
DIRECTOR: Fix alignment issue during seeking in ProjectorArchive
Changed paths:
engines/director/resource.cpp
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index e44782b6271..c2803f1ac9d 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -678,13 +678,20 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
bigEndian = oBigEndian;
- // The first block would start right after the dict.
+ // Jump to the first block which should start right after the dict while making sure size is aligned.
+ size += (size % 2);
stream->seek(dictOff + size + 8, SEEK_SET);
for (uint32 i = 0; i < cnt; i++) {
tag = stream->readUint32BE();
size = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
+ // endianness issue, swap size and continue
+ if (size > stream->pos()) {
+ bigEndian = !bigEndian;
+ size = SWAP_BYTES_32(size);
+ }
+
debugC(1, kDebugLoading, "Entry: %s offset %llX tag %s size %d", arr[i].c_str(), stream->pos() - 8, tag2str(tag), size);
Entry entry;
@@ -694,6 +701,9 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
entry.size = size + 8;
_files[arr[i]] = entry;
+ // Align size for the next seek.
+ size += (size % 2);
+
// if this fails it suggests something is either wrong with the dict or the file itself.
if (!stream->seek(size, SEEK_CUR)) {
warning("ProjectorArchive::loadArchive(): Could not read next block (0x%x) Prev Block(0x%x : %d)",
More information about the Scummvm-git-logs
mailing list