[Scummvm-git-logs] scummvm master -> ffdea87367105ecfcbd7722a3804cfa2cded523d
bluegr
noreply at scummvm.org
Thu Aug 27 12:08:55 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
fbe6a8f465 NANCY: Hide the cursor glow when the MouseLightPuzzle AR is hidden
ffdea87367 NANCY: Close CIF streams after reading data
Commit: fbe6a8f4650e3253551fb0997a202e77b60e6707
https://github.com/scummvm/scummvm/commit/fbe6a8f4650e3253551fb0997a202e77b60e6707
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-08-27T15:08:35+03:00
Commit Message:
NANCY: Hide the cursor glow when the MouseLightPuzzle AR is hidden
Also, fix the Z-order of the mouse cursor glow
Fix #16936
Changed paths:
engines/nancy/action/puzzle/mouselightpuzzle.cpp
engines/nancy/action/puzzle/mouselightpuzzle.h
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.cpp b/engines/nancy/action/puzzle/mouselightpuzzle.cpp
index 21457f0a6a7..8b15e41853d 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.cpp
@@ -65,6 +65,15 @@ void MouseLightPuzzle::init() {
}
}
+void MouseLightPuzzle::updateGraphics() {
+ // The light only exists while the player holds the light source. The record stops
+ // receiving input as soon as its cursor dependency stops being satisfied, so hide
+ // it instead of leaving the last drawn circle on screen.
+ if (_state == kRun && isVisible() != _isActive) {
+ setVisible(_isActive);
+ }
+}
+
void MouseLightPuzzle::execute() {
if (_state == kBegin) {
init();
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.h b/engines/nancy/action/puzzle/mouselightpuzzle.h
index d8960f52941..b91d0370cae 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.h
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.h
@@ -35,10 +35,11 @@ namespace Action {
// TODO: Add noise to the circle mask; there are artifacts at low brightness
class MouseLightPuzzle : public RenderActionRecord {
public:
- MouseLightPuzzle() : RenderActionRecord(7) {}
+ MouseLightPuzzle() : RenderActionRecord(10) {}
virtual ~MouseLightPuzzle() {}
void init() override;
+ void updateGraphics() override;
void readData(Common::SeekableReadStream &stream) override;
void execute() override;
Commit: ffdea87367105ecfcbd7722a3804cfa2cded523d
https://github.com/scummvm/scummvm/commit/ffdea87367105ecfcbd7722a3804cfa2cded523d
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-08-27T15:08:36+03:00
Commit Message:
NANCY: Close CIF streams after reading data
Avoids keeping a lot of file handles open, which is a problem in
platforms that support only a limited number of concurrent open file
handles, such as the PSP, which supports up to 8.
Fix #16947
Changed paths:
engines/nancy/cif.cpp
engines/nancy/cif.h
diff --git a/engines/nancy/cif.cpp b/engines/nancy/cif.cpp
index 76c0aa48e66..1fe36d1eb64 100644
--- a/engines/nancy/cif.cpp
+++ b/engines/nancy/cif.cpp
@@ -24,6 +24,7 @@
#include "engines/nancy/util.h"
#include "engines/nancy/nancy.h"
+#include "common/fs.h"
#include "common/memstream.h"
#include "common/substream.h"
#include "common/serializer.h"
@@ -204,13 +205,28 @@ bool CifFile::sync(Common::Serializer &ser) {
}
CifTree::CifTree(Common::SeekableReadStream *stream, const Common::Path &name) :
- _stream(stream),
- _name(name) {}
+ _name(name),
+ _stream(stream) {}
+
+CifTree::CifTree(const Common::ArchiveMemberPtr &member, const Common::Path &name) :
+ _name(name),
+ _stream(nullptr),
+ _member(member) {}
CifTree::~CifTree() {
delete _stream;
}
+Common::SeekableReadStream *CifTree::openStream() const {
+ return _member ? _member->createReadStream() : _stream;
+}
+
+void CifTree::closeStream(Common::SeekableReadStream *stream) const {
+ if (_member) {
+ delete stream;
+ }
+}
+
const CifInfo &CifTree::getCifInfo(const Common::Path &name) const {
return _fileMap[name];
}
@@ -241,22 +257,28 @@ Common::SeekableReadStream *CifTree::createReadStreamForMember(const Common::Pat
}
const CifInfo &info = _fileMap[path];
+ Common::SeekableReadStream *stream = openStream();
+ if (!stream) {
+ warning("Failed to open CifTree '%s'", _name.toString().c_str());
+ return nullptr;
+ }
+
byte *buf = (byte *)malloc(info.size);
bool success = true;
if (info.comp == CifInfo::kResCompression) {
// Decompress the data into the buffer
- if (_stream->seek(info.dataOffset)) {
+ if (stream->seek(info.dataOffset)) {
Common::MemoryWriteStream write(buf, info.size);
- Common::SeekableSubReadStream read(_stream, info.dataOffset, info.dataOffset + info.compressedSize);
+ Common::SeekableSubReadStream read(stream, info.dataOffset, info.dataOffset + info.compressedSize);
Decompressor dec;
success = dec.decompress(read, write);
} else {
success = false;
}
} else {
- if (!_stream->seek(info.dataOffset) || _stream->read(buf, info.size) < info.size) {
+ if (!stream->seek(info.dataOffset) || stream->read(buf, info.size) < info.size) {
success = false;
}
}
@@ -265,10 +287,12 @@ Common::SeekableReadStream *CifTree::createReadStreamForMember(const Common::Pat
warning("Failed to read data for '%s' from CifTree '%s'", info.name.toString().c_str(), _name.toString().c_str());
free(buf);
buf = nullptr;
- _stream->clearErr();
+ stream->clearErr();
+ closeStream(stream);
return nullptr;
}
+ closeStream(stream);
return new Common::MemoryReadStream(buf, info.size, DisposeAfterUse::YES);
}
@@ -278,13 +302,20 @@ Common::SeekableReadStream *CifTree::createReadStreamRaw(const Common::Path &pat
}
const CifInfo &info = _fileMap[path];
+ Common::SeekableReadStream *stream = openStream();
+ if (!stream) {
+ warning("Failed to open CifTree '%s'", _name.toString().c_str());
+ return nullptr;
+ }
+
uint32 size = (info.comp == CifInfo::kResCompression ? info.compressedSize : info.size);
byte *buf = new byte[size];
- if (!_stream->seek(info.dataOffset) || _stream->read(buf, size) < size) {
+ if (!stream->seek(info.dataOffset) || stream->read(buf, size) < size) {
warning("Failed to read data for '%s' from CifTree '%s'", info.name.toString().c_str(), _name.toString().c_str());
}
+ closeStream(stream);
return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
}
@@ -292,16 +323,36 @@ CifTree *CifTree::makeCifTreeArchive(const Common::String &name, const Common::S
Common::Path path(name);
path.appendInPlace('.' + ext);
- auto *stream = SearchMan.createReadStreamForMember(path);
+ Common::Archive *container = nullptr;
+ Common::ArchiveMemberPtr member = SearchMan.getMember(path, &container);
- if (!stream) {
+ if (!member) {
return nullptr;
}
- CifTree *ret = new CifTree(stream, path);
- Common::Serializer ser(stream, nullptr);
+ CifTree *ret = nullptr;
+ if (dynamic_cast<Common::FSDirectory *>(container)) {
+ ret = new CifTree(member, path);
+ } else {
+ Common::SeekableReadStream *stream = member->createReadStream();
+ if (!stream) {
+ return nullptr;
+ }
+
+ ret = new CifTree(stream, path);
+ }
+
+ Common::SeekableReadStream *headerStream = ret->openStream();
+ if (!headerStream) {
+ delete ret;
+ return nullptr;
+ }
+
+ Common::Serializer ser(headerStream, nullptr);
+ bool synced = ret->sync(ser);
+ ret->closeStream(headerStream);
- if (!ret->sync(ser)) {
+ if (!synced) {
delete ret;
return nullptr;
}
diff --git a/engines/nancy/cif.h b/engines/nancy/cif.h
index 8a30df2036f..bbbc8c7e03f 100644
--- a/engines/nancy/cif.h
+++ b/engines/nancy/cif.h
@@ -81,6 +81,7 @@ class CifTree : public Common::Archive {
public:
CifTree() : _stream(nullptr) {}
CifTree(Common::SeekableReadStream *stream, const Common::Path &name);
+ CifTree(const Common::ArchiveMemberPtr &member, const Common::Path &name);
virtual ~CifTree();
// Used for extracting additional image data for conversation cels (nancy2 and up)
@@ -107,8 +108,16 @@ public:
Common::Array<Common::Path> getPathsForType(CifInfo::ResType type = CifInfo::kResTypeAny) const;
private:
+ // Trees backed by a plain file are opened only for as long as a read takes, since
+ // some platforms allow very few files to be open at the same time, and a game can
+ // load a lot of trees. Trees living inside another archive keep their stream, as
+ // reopening those means extracting them all over again.
+ Common::SeekableReadStream *openStream() const;
+ void closeStream(Common::SeekableReadStream *stream) const;
+
Common::Path _name;
Common::SeekableReadStream *_stream;
+ Common::ArchiveMemberPtr _member;
Common::HashMap<Common::Path, CifInfo, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> _fileMap;
Common::Array<CifInfo> _writeFileMap;
};
More information about the Scummvm-git-logs
mailing list