[Scummvm-git-logs] scummvm master -> 6f9992addced4b095f00446d164981b725373dff

tnm23 noreply at scummvm.org
Thu Jul 24 18:13:21 UTC 2025


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

Summary:
95440c2bf1 ZVISION: Rework engine to use standard SearchMan functionality.
7c5ab5844f ZVISION: Code cleanup & additional comment.
f4881416f9 ZVISION: Code cleanup.
193358a035 ZVISION: Add FileManager class to automatically handle loading of alternate .raw files.
34d0904e2f ZVISION: Move getVobAmplification() to VolumeManager to improve encapsulation.
0f6c5d6ba4 ZVISION: Fix incorrect FileManager::open() functionality.
879dad1aad ZVISION: Improve debug messaging in RLFDecoder
3be4d17e11 ZVISION: convert makeRawZorkStream() & loadAnimation() to make use of FileManager.open()
abf8175311 ZVISION: Fix bug from previous commit; .zfs files in addon load correctly now.
15574c613b ZVISION: Fix bug in video playback causing audio channels not to be freed upon video completion.
a3066eccf5 ZVISION: Add missing header inclusion.
6f9992addc ZVISION: Code formatting compliance.


Commit: 95440c2bf145f8cb9529761e04632691fb635f62
    https://github.com/scummvm/scummvm/commit/95440c2bf145f8cb9529761e04632691fb635f62
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Rework engine to use standard SearchMan functionality.
Remove local SearchManager implementation.

Changed paths:
  R engines/zvision/file/search_manager.cpp
  R engines/zvision/file/search_manager.h
    common/archive.cpp
    engines/zvision/core/console.cpp
    engines/zvision/core/events.cpp
    engines/zvision/file/save_manager.cpp
    engines/zvision/graphics/cursors/cursor.cpp
    engines/zvision/graphics/effects/fog.cpp
    engines/zvision/graphics/render_manager.cpp
    engines/zvision/module.mk
    engines/zvision/scripting/actions.cpp
    engines/zvision/scripting/controls/fist_control.cpp
    engines/zvision/scripting/controls/hotmov_control.cpp
    engines/zvision/scripting/controls/lever_control.cpp
    engines/zvision/scripting/controls/paint_control.cpp
    engines/zvision/scripting/controls/titler_control.cpp
    engines/zvision/scripting/controls/titler_control.h
    engines/zvision/scripting/effects/music_effect.cpp
    engines/zvision/scripting/effects/syncsound_effect.cpp
    engines/zvision/scripting/effects/ttytext_effect.cpp
    engines/zvision/scripting/scr_file_handling.cpp
    engines/zvision/sound/zork_raw.cpp
    engines/zvision/text/string_manager.cpp
    engines/zvision/text/subtitle_manager.cpp
    engines/zvision/text/truetype_font.cpp
    engines/zvision/video/video.cpp
    engines/zvision/zvision.cpp
    engines/zvision/zvision.h


diff --git a/common/archive.cpp b/common/archive.cpp
index 27494b41dd2..b30f62d8653 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -358,8 +358,10 @@ void SearchSet::addDirectory(const String &name, const Path &directory, int prio
 }
 
 void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority, int depth, bool flat) {
-	if (!dir.exists() || !dir.isDirectory())
+	if (!dir.exists() || !dir.isDirectory()) {
+		error("Failed to add directory %s", name.c_str());
 		return;
+	}
 
 	add(name, new FSDirectory(dir, depth, flat, _ignoreClashes), priority);
 }
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index a2a3af22675..9e064eed1ca 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -80,7 +80,7 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
 		int isStereo = atoi(argv[3]);
 
 		Common::File *file = new Common::File();
-		if (!_engine->getSearchManager()->openFile(*file, argv[1])) {
+		if (!file->open(argv[1])) {
 			warning("File not found: %s", argv[1]);
 			return true;
 		}
@@ -103,7 +103,7 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
 	}
 
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, argv[1])) {
+	if (!file.open(argv[1])) {
 		warning("File not found: %s", argv[1]);
 		return true;
 	}
@@ -232,7 +232,7 @@ bool Console::cmdDumpFile(int argc, const char **argv) {
 	}
 
 	Common::File f;
-	if (!_engine->getSearchManager()->openFile(f, argv[1])) {
+	if (!f.open(argv[1])) {
 		warning("File not found: %s", argv[1]);
 		return true;
 	}
@@ -251,16 +251,20 @@ bool Console::cmdDumpFiles(int argc, const char **argv) {
 		return true;
 	}
 
-	SearchManager::MatchList fileList;
-	_engine->getSearchManager()->listMembersWithExtension(fileList, argv[1]);
-
-	for (SearchManager::MatchList::iterator iter = fileList.begin(); iter != fileList.end(); ++iter) {
-		fileName = iter->_value.name;
+	Common::ArchiveMemberList fileList;
+	Common::Path pattern;
+	pattern = Common::Path(Common::String::format("*.%s", argv[1]));
+	SearchMan.listMatchingMembers(fileList, pattern);
+	
+	for (auto iter = fileList.begin(); iter != fileList.end(); ++iter) {
+		fileName = iter->get()->getFileName();
 		debugPrintf("Dumping %s\n", fileName.toString().c_str());
 
-		in = iter->_value.arch->createReadStreamForMember(iter->_value.name);
+		in = iter->get()->createReadStream();
 		if (in)
 			dumpFile(in, fileName);
+		else
+			debugPrintf("Failed to dump!");
 		delete in;
 	}
 
@@ -280,7 +284,7 @@ bool Console::cmdDumpImage(int argc, const char **argv) {
 	}
 
 	Common::File f;
-	if (!_engine->getSearchManager()->openFile(f, fileName)) {
+	if (!f.open(fileName)) {
 		warning("File not found: %s", argv[1]);
 		return true;
 	}
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
index 2a4254d0c46..efb1ed4bca3 100644
--- a/engines/zvision/core/events.cpp
+++ b/engines/zvision/core/events.cpp
@@ -23,6 +23,7 @@
 #include "common/config-manager.h"
 #include "common/events.h"
 #include "common/scummsys.h"
+#include "common/stream.h"
 #include "common/system.h"
 #include "common/rational.h"
 #include "engines/util.h"
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
index 32599b93535..d190d177a77 100644
--- a/engines/zvision/file/save_manager.cpp
+++ b/engines/zvision/file/save_manager.cpp
@@ -21,6 +21,7 @@
 
 
 #include "common/config-manager.h"
+#include "common/file.h"
 #include "common/scummsys.h"
 #include "common/system.h"
 #include "common/translation.h"
@@ -245,18 +246,12 @@ Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
 		else if (_engine->getGameId() == GID_NEMESIS)
 			filename = Common::Path(Common::String::format("nemsav%u.sav", slot));
 
-		saveFile = _engine->getSearchManager()->openFile(filename);
-		if (saveFile == NULL) {
-			Common::File *tmpFile = new Common::File;
-			if (!tmpFile->open(filename)) {
-				delete tmpFile;
-			} else {
-				saveFile = tmpFile;
-			}
-		}
-
+		Common::File *tmpFile = new Common::File;
+		if (!tmpFile->open(filename))
+			delete tmpFile;
+		else
+			saveFile = tmpFile;
 	}
-
 	return saveFile;
 }
 
diff --git a/engines/zvision/file/search_manager.cpp b/engines/zvision/file/search_manager.cpp
deleted file mode 100644
index 61ea272bda2..00000000000
--- a/engines/zvision/file/search_manager.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "common/debug.h"
-#include "common/fs.h"
-#include "common/stream.h"
-#include "zvision/file/search_manager.h"
-#include "zvision/file/zfs_archive.h"
-
-namespace ZVision {
-
-SearchManager::SearchManager(const Common::Path &rootPath, int depth) {
-	Common::FSNode fsNode(rootPath);
-
-	// Retrieve the root path from the FSNode, since it may not be the
-	// same as rootPath any more, e.g. if we're doing auto-detection on
-	// the current directory.
-
-	_root = fsNode.getPath();
-
-	listDirRecursive(_dirList, fsNode, depth);
-
-	for (Common::List<Common::Path>::iterator it = _dirList.begin(); it != _dirList.end();) {
-		*it = it->relativeTo(_root);
-		if (it->empty()) {
-			it = _dirList.erase(it);
-		} else {
-			it++;
-		}
-	}
-}
-
-SearchManager::~SearchManager() {
-	Common::List<Common::Archive *>::iterator it = _archList.begin();
-	while (it != _archList.end()) {
-		delete *it;
-		it++;
-	}
-
-	_archList.clear();
-}
-
-void SearchManager::addFile(const Common::Path &name, Common::Archive *arch) {
-	bool addArch = true;
-	Common::List<Common::Archive *>::iterator it = _archList.begin();
-	while (it != _archList.end()) {
-		if (*it == arch) {
-			addArch = false;
-			break;
-		}
-		it++;
-	}
-	if (addArch)
-		_archList.push_back(arch);
-
-	Common::Path lowerCaseName = name;
-	lowerCaseName.toLowercase();
-
-	SearchManager::Node nod;
-	nod.name = lowerCaseName;
-	nod.arch = arch;
-
-	SearchManager::MatchList::iterator fit = _files.find(lowerCaseName);
-
-	if (fit == _files.end()) {
-		_files[lowerCaseName] = nod;
-	} else {
-		Common::SeekableReadStream *stream = fit->_value.arch->createReadStreamForMember(fit->_value.name);
-		if (stream) {
-			if (stream->size() < 10)
-				fit->_value.arch = arch;
-			delete stream;
-		} else {
-			_files[lowerCaseName] = nod;
-		}
-	}
-}
-
-Common::File *SearchManager::openFile(const Common::Path &name) {
-	SearchManager::MatchList::iterator fit = _files.find(name);
-
-	if (fit != _files.end()) {
-		Common::File *tmp = new Common::File();
-		tmp->open(fit->_value.name, *fit->_value.arch);
-		return tmp;
-	}
-	return NULL;
-}
-
-bool SearchManager::openFile(Common::File &file, const Common::Path &name) {
-	SearchManager::MatchList::iterator fit = _files.find(name);
-
-	if (fit != _files.end())
-		return file.open(fit->_value.name, *fit->_value.arch);
-	return false;
-}
-
-bool SearchManager::hasFile(const Common::Path &name) {
-	SearchManager::MatchList::iterator fit = _files.find(name);
-
-	if (fit != _files.end())
-		return true;
-	return false;
-}
-
-bool SearchManager::loadZix(const Common::Path &name) {
-	Common::File file;
-	if (!file.open(name))
-		return false;
-
-	Common::String line;
-
-	while (!file.eos()) {
-		line = file.readLine();
-		if (line.matchString("----------*", true))
-			break;
-	}
-
-	if (file.eos())
-		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
-
-	Common::Array<Common::Archive *> archives;
-
-	while (!file.eos()) {
-		line = file.readLine();
-		line.trim();
-		if (line.matchString("----------*", true))
-			break;
-		else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
-			Common::Archive *arc;
-
-			Common::String path(line.c_str() + 5);
-			for (uint i = 0; i < path.size(); i++)
-				if (path[i] == '\\')
-					path.setChar('/', i);
-
-			// Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
-			// check the game root folder instead
-			if (path.hasPrefix("znemesis/"))
-				path = Common::String(path.c_str() + 9);
-
-			// Check if INQUIS.ZIX refers to the ZGI folder, and check the game
-			// root folder instead
-			if (path.hasPrefix("zgi/"))
-				path = Common::String(path.c_str() + 4);
-			if (path.hasPrefix("zgi_e/"))
-				path = Common::String(path.c_str() + 6);
-
-			if (path.size() && path[0] == '.')
-				path.deleteChar(0);
-			if (path.size() && path[0] == '/')
-				path.deleteChar(0);
-			if (path.size() && path.hasSuffix("/"))
-				path.deleteLastChar();
-
-			// Handle paths in case-sensitive file systems (bug #6775)
-			Common::Path path_(path);
-			if (!path_.empty()) {
-				for (Common::List<Common::Path>::iterator it = _dirList.begin(); it != _dirList.end(); ++it) {
-					if (path_.equalsIgnoreCase(*it)) {
-						path_ = *it;
-						break;
-					}
-				}
-			}
-
-			if (path.matchString("*.zfs", true)) {
-				arc = new ZfsArchive(path_);
-			} else {
-				path_ = _root.join(path_);
-				arc = new Common::FSDirectory(path_);
-			}
-			archives.push_back(arc);
-		}
-	}
-
-	if (file.eos())
-		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
-
-	while (!file.eos()) {
-		line = file.readLine();
-		line.trim();
-		uint dr = 0;
-		char buf[32];
-		if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
-			if (dr <= archives.size() && dr > 0) {
-				addFile(buf, archives[dr - 1]);
-			}
-		}
-	}
-
-	return true;
-}
-
-void SearchManager::addDir(const Common::Path &name) {
-	Common::Path path;
-	for (Common::List<Common::Path>::iterator it = _dirList.begin(); it != _dirList.end(); ++it)
-		if (name.equalsIgnoreCase(*it)) {
-			path = *it;
-			break;
-		}
-
-	if (path.empty())
-		return;
-
-
-	path = _root.join(path);
-	Common::FSDirectory *dir = new Common::FSDirectory(path);
-
-	Common::ArchiveMemberList list;
-	dir->listMatchingMembers(list, "*.zfs");
-
-	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
-		Common::String flname = (*iter)->getName();
-
-		ZfsArchive *zfs = new ZfsArchive(name.join(flname));
-
-		Common::ArchiveMemberList zfslist;
-		zfs->listMembers(zfslist);
-
-		for (Common::ArchiveMemberList::iterator ziter = zfslist.begin(); ziter != zfslist.end(); ++ziter) {
-			Common::Path zfsFileName = (*ziter)->getPathInArchive();
-			addFile(zfsFileName, zfs);
-		}
-	}
-
-	list.clear();
-	dir->listMembers(list);
-
-	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
-		Common::Path flname = (*iter)->getPathInArchive();
-		addFile(flname, dir);
-	}
-}
-
-void SearchManager::listDirRecursive(Common::List<Common::Path> &_list, const Common::FSNode &fsNode, int depth) {
-	Common::FSList fsList;
-	if (fsNode.getChildren(fsList)) {
-
-		_list.push_back(fsNode.getPath().normalize());
-
-		if (depth > 1)
-			for (Common::FSList::const_iterator it = fsList.begin(); it != fsList.end(); ++it)
-				listDirRecursive(_list, *it, depth - 1);
-	}
-}
-
-void SearchManager::listMembersWithExtension(MatchList &fileList, Common::String extension) {
-	for (SearchManager::MatchList::iterator it = _files.begin(); it != _files.end(); ++it) {
-		if (it->_key.baseName().hasSuffix(extension))
-			fileList[it->_key] = it->_value;
-	}
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/file/search_manager.h b/engines/zvision/file/search_manager.h
deleted file mode 100644
index 122ff7b1988..00000000000
--- a/engines/zvision/file/search_manager.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* 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 ZVISION_SEARCH_MANAGER_H
-#define ZVISION_SEARCH_MANAGER_H
-
-#include "common/archive.h"
-#include "common/file.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/list.h"
-#include "common/str.h"
-
-namespace ZVision {
-
-class SearchManager {
-public:
-	SearchManager(const Common::Path &rootPath, int depth);
-	~SearchManager();
-
-	void addFile(const Common::Path &name, Common::Archive *arch);
-	void addDir(const Common::Path &name);
-
-	Common::File *openFile(const Common::Path &name);
-	bool openFile(Common::File &file, const Common::Path &name);
-	bool hasFile(const Common::Path &name);
-
-	bool loadZix(const Common::Path &name);
-
-	struct Node {
-		Common::Path name;
-		Common::Archive *arch;
-	};
-
-	typedef Common::HashMap<Common::Path, Node, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> MatchList;
-
-	void listMembersWithExtension(MatchList &fileList, Common::String extension);
-
-private:
-
-	void listDirRecursive(Common::List<Common::Path> &dirList, const Common::FSNode &fsNode, int depth);
-
-	Common::List<Common::Path> _dirList;
-	Common::List<Common::Archive *> _archList;
-	Common::Path _root;
-	MatchList _files;
-};
-
-}
-
-#endif // ZVISION_SEARCH_MANAGER_H
diff --git a/engines/zvision/graphics/cursors/cursor.cpp b/engines/zvision/graphics/cursors/cursor.cpp
index 1030dfd01d6..3806f9cc34e 100644
--- a/engines/zvision/graphics/cursors/cursor.cpp
+++ b/engines/zvision/graphics/cursors/cursor.cpp
@@ -39,7 +39,7 @@ ZorkCursor::ZorkCursor(ZVision *engine, const Common::Path &fileName)
 	  _hotspotX(0),
 	  _hotspotY(0) {
 	Common::File file;
-	if (!engine->getSearchManager()->openFile(file, fileName))
+	if (!file.open(fileName))
 		error("Cursor file %s does not exist", fileName.toString().c_str());
 
 	uint32 magic = file.readUint32BE();
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
index c2f2eb49626..d366985e2cd 100644
--- a/engines/zvision/graphics/effects/fog.cpp
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -38,7 +38,7 @@ FogFx::FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, Effe
 
 	_pos = 0;
 
-	if (_engine->getSearchManager()->hasFile(clouds))
+	if (SearchMan.hasFile(clouds))
 		_engine->getRenderManager()->readImageToSurface(clouds, _fog);
 	else
 		_engine->getRenderManager()->readImageToSurface("cloud.tga", _fog);
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index c436892b905..9431a5b3d88 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -295,7 +295,7 @@ void RenderManager::readImageToSurface(const Common::Path &fileName, Graphics::S
 void RenderManager::readImageToSurface(const Common::Path &fileName, Graphics::Surface &destination, bool transposed) {
 	Common::File file;
 
-	if (!_engine->getSearchManager()->openFile(file, fileName)) {
+	if (!file.open(fileName)) {
 		warning("Could not open file %s", fileName.toString().c_str());
 		return;
 	}
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index ebc12af5393..eb56f74d4c2 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -7,7 +7,6 @@ MODULE_OBJS := \
 	core/events.o \
 	file/lzss_read_stream.o \
 	file/save_manager.o \
-	file/search_manager.o \
 	file/zfs_archive.o \
 	graphics/cursors/cursor.o \
 	graphics/cursors/cursor_manager.o \
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 7d646019d4c..8905a633994 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -576,9 +576,6 @@ bool ActionMusic::execute() {
 	if (_midi) {
 		_scriptManager->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, volume));
 	} else {
-		if (!_engine->getSearchManager()->hasFile(_fileName))
-			return true;
-
 		_scriptManager->addSideFX(new MusicNode(_engine, _slotKey, _fileName, _loop, volume));
 	}
 
@@ -1113,7 +1110,7 @@ bool ActionStreamVideo::execute() {
 	subname.setChar('u', subname.size() - 2);
 	subname.setChar('b', subname.size() - 1);
 	Common::Path subpath(_fileName.getParent().appendComponent(subname));
-	bool subtitleExists = _engine->getSearchManager()->hasFile(subpath);
+	bool subtitleExists = SearchMan.hasFile(subpath);
 	bool switchToHires = false;
 
 // NOTE: We only show the hires MPEG2 videos when libmpeg2 and liba52 are compiled in,
@@ -1127,13 +1124,13 @@ bool ActionStreamVideo::execute() {
 
 	Common::Path hiresPath(_fileName.getParent().appendComponent(hiresFileName));
 
-	if (_scriptManager->getStateValue(StateKey_MPEGMovies) == 1 &&_engine->getSearchManager()->hasFile(hiresPath)) {
+	if (_scriptManager->getStateValue(StateKey_MPEGMovies) == 1 && SearchMan.hasFile(hiresPath)) {
 		_fileName = hiresPath;
 		switchToHires = true;
-	} else if (!_engine->getSearchManager()->hasFile(_fileName))
+	} else if (!SearchMan.hasFile(_fileName))
 		return true;
 #else
-	if (!_engine->getSearchManager()->hasFile(_fileName))
+	if (!SearchMan.hasFile(_fileName))
 		return true;
 #endif
 
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
index 055fb3cc79a..26ec40a783f 100644
--- a/engines/zvision/scripting/controls/fist_control.cpp
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -160,7 +160,7 @@ bool FistControl::onMouseUp(const Common::Point &screenSpacePos, const Common::P
 
 void FistControl::readDescFile(const Common::Path &fileName) {
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, fileName)) {
+	if (!file.open(fileName)) {
 		warning("Desc file %s could could be opened", fileName.toString().c_str());
 		return;
 	}
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
index 4f6ea40ddb4..76ce894cf13 100644
--- a/engines/zvision/scripting/controls/hotmov_control.cpp
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -155,7 +155,7 @@ void HotMovControl::readHsFile(const Common::Path &fileName) {
 		return;
 
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, fileName)) {
+	if (!file.open(fileName)) {
 		warning("HS file %s could could be opened", fileName.toString().c_str());
 		return;
 	}
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index 3ef02c5a65c..4ddb711cb4e 100644
--- a/engines/zvision/scripting/controls/lever_control.cpp
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -85,7 +85,7 @@ LeverControl::~LeverControl() {
 
 void LeverControl::parseLevFile(const Common::Path &fileName) {
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, fileName)) {
+	if (!file.open(fileName)) {
 		warning("LEV file %s could could be opened", fileName.toString().c_str());
 		return;
 	}
diff --git a/engines/zvision/scripting/controls/paint_control.cpp b/engines/zvision/scripting/controls/paint_control.cpp
index 5edb9554dda..8a2fcb84edf 100644
--- a/engines/zvision/scripting/controls/paint_control.cpp
+++ b/engines/zvision/scripting/controls/paint_control.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/scummsys.h"
+#include "common/stream.h"
 #include "zvision/zvision.h"
 #include "zvision/graphics/cursors/cursor_manager.h"
 #include "zvision/graphics/render_manager.h"
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
index 9f93ec2040e..77b086259b6 100644
--- a/engines/zvision/scripting/controls/titler_control.cpp
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -85,7 +85,7 @@ void TitlerControl::setString(int strLine) {
 
 void TitlerControl::readStringsFile(const Common::Path &fileName) {
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, fileName)) {
+	if (!file.open(fileName)) {
 		warning("String_resource_file %s could could be opened", fileName.toString().c_str());
 		return;
 	}
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
index 5d8926e4a3a..af0a71d4caa 100644
--- a/engines/zvision/scripting/controls/titler_control.h
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -23,8 +23,10 @@
 #define ZVISION_TITLER_CONTROL_H
 
 #include "common/array.h"
+#include "common/file.h"
 #include "common/path.h"
 #include "common/rect.h"
+#include "common/stream.h"
 #include "graphics/surface.h"
 #include "zvision/scripting/control.h"
 
diff --git a/engines/zvision/scripting/effects/music_effect.cpp b/engines/zvision/scripting/effects/music_effect.cpp
index f0276e73eeb..dd179358954 100644
--- a/engines/zvision/scripting/effects/music_effect.cpp
+++ b/engines/zvision/scripting/effects/music_effect.cpp
@@ -79,7 +79,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::Path &filename, bool l
 
 	if (filename.baseName().contains(".wav")) {
 		Common::File *file = new Common::File();
-		if (_engine->getSearchManager()->openFile(*file, filename)) {
+		if (file->open(filename)) {
 			audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
 		}
 	} else {
@@ -108,7 +108,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::Path &filename, bool l
 		subname.setChar('b', subname.size() - 1);
 
 		Common::Path subpath(filename.getParent().appendComponent(subname));
-		if (_engine->getSearchManager()->hasFile(subpath))
+		if (SearchMan.hasFile(subpath))
 			_sub = _engine->getSubtitleManager()->create(subpath, _handle); // NB automatic subtitle!
 
 		_loaded = true;
diff --git a/engines/zvision/scripting/effects/syncsound_effect.cpp b/engines/zvision/scripting/effects/syncsound_effect.cpp
index 67537981fad..2010a9aa3a8 100644
--- a/engines/zvision/scripting/effects/syncsound_effect.cpp
+++ b/engines/zvision/scripting/effects/syncsound_effect.cpp
@@ -41,7 +41,7 @@ SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::Path &filename
 
 	if (filename.baseName().contains(".wav")) {
 		Common::File *file = new Common::File();
-		if (_engine->getSearchManager()->openFile(*file, filename)) {
+		if (file->open(filename)) {
 			audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
 		}
 	} else {
@@ -56,7 +56,7 @@ SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::Path &filename
 	subname.setChar('b', subname.size() - 1);
 
 	Common::Path subpath(filename.getParent().appendComponent(subname));
-	if (_engine->getSearchManager()->hasFile(subpath))
+	if (SearchMan.hasFile(subpath))
 		_sub = _engine->getSubtitleManager()->create(subpath, _handle); // NB automatic subtitle!
 }
 
diff --git a/engines/zvision/scripting/effects/ttytext_effect.cpp b/engines/zvision/scripting/effects/ttytext_effect.cpp
index 2829f0652b1..1d2c9a81262 100644
--- a/engines/zvision/scripting/effects/ttytext_effect.cpp
+++ b/engines/zvision/scripting/effects/ttytext_effect.cpp
@@ -43,7 +43,8 @@ ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::Path &file,
 	_lineStartPos = 0;
 	_startX = 0;
 
-	Common::File *infile = _engine->getSearchManager()->openFile(file);
+	Common::File *infile = new Common::File;
+	infile->open(file);
 	if (infile) {
 		while (!infile->eos()) {
 			Common::U32String asciiLine = readWideLine(*infile);
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 61d1baf3fe7..fdee25c4d2f 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -77,7 +77,7 @@ void ScriptManager::parseScrFile(const Common::Path &fileName, ScriptScope &scop
 	Common::Path auxFilePath(auxFileName);
 	debugC(1, kDebugFile, "Auxiliary path %s", auxFilePath.toString().c_str());
 
-	if (!_engine->getSearchManager()->openFile(mainFile, fileName))
+	if (!mainFile.open(fileName))
 		error("Script file not found: %s", fileName.toString().c_str());
 	else {
 		debugC(1, kDebugScript, "Parsing primary script file %s", fileName.toString().c_str());
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index 32f9d92752d..e2685db69a8 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -242,7 +242,7 @@ Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stre
 
 Audio::RewindableAudioStream *makeRawZorkStream(const Common::Path &filePath, ZVision *engine) {
 	Common::File *file = new Common::File();
-	bool found = engine->getSearchManager()->openFile(*file, filePath);
+	bool found = file->open(filePath);
 	Common::String baseName = filePath.baseName();
 	bool isRaw = baseName.hasSuffix(".raw");
 
@@ -251,13 +251,17 @@ Audio::RewindableAudioStream *makeRawZorkStream(const Common::Path &filePath, ZV
 			file->close();
 
 		// Check for an audio patch (.src)
-		baseName.setChar('s', baseName.size() - 3);
-		baseName.setChar('r', baseName.size() - 2);
-		baseName.setChar('c', baseName.size() - 1);
+		Common::String patchName = baseName;
+		patchName.setChar('s', baseName.size() - 3);
+		patchName.setChar('r', baseName.size() - 2);
+		patchName.setChar('c', baseName.size() - 1);
 
-		if (!engine->getSearchManager()->openFile(*file, filePath.getParent().appendComponent(baseName)))
+		if (!file->open(filePath.getParent().appendComponent(patchName))) {
+			warning("Audio file %s AND audio patch %s not found", baseName.c_str(), patchName.c_str());
 			return NULL;
+			}
 	} else if (!found && !isRaw) {
+		warning("Audio file %s not found", baseName.c_str());
 		return NULL;
 	}
 
diff --git a/engines/zvision/text/string_manager.cpp b/engines/zvision/text/string_manager.cpp
index 7019ef458ee..c83f4d09074 100644
--- a/engines/zvision/text/string_manager.cpp
+++ b/engines/zvision/text/string_manager.cpp
@@ -25,7 +25,6 @@
 #include "common/tokenizer.h"
 #include "graphics/fontman.h"
 #include "zvision/zvision.h"
-#include "zvision/file/search_manager.h"
 #include "zvision/text/string_manager.h"
 #include "zvision/text/text.h"
 
@@ -48,7 +47,7 @@ void StringManager::initialize(ZVisionGameId gameId) {
 
 void StringManager::loadStrFile(const Common::Path &fileName) {
 	Common::File file;
-	if (!_engine->getSearchManager()->openFile(file, fileName))
+	if (!file.open(fileName))
 		error("%s does not exist. String parsing failed", fileName.toString().c_str());
 
 	uint lineNumber = 0;
diff --git a/engines/zvision/text/subtitle_manager.cpp b/engines/zvision/text/subtitle_manager.cpp
index 1616ff764ce..d4d1e155fbc 100644
--- a/engines/zvision/text/subtitle_manager.cpp
+++ b/engines/zvision/text/subtitle_manager.cpp
@@ -20,9 +20,9 @@
  */
 
 #include "common/config-manager.h"
+#include "common/file.h"
 #include "common/system.h"
 #include "zvision/detection.h"
-#include "zvision/file/search_manager.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/scripting/script_manager.h"
 #include "zvision/text/subtitle_manager.h"
@@ -291,7 +291,7 @@ Subtitle::Subtitle(ZVision *engine, const Common::Path &subname, bool vob) :
 	_redraw(false) {
 	Common::File subFile;
 	Common::Point _textOffset = _engine->getSubtitleManager()->getTextOffset();
-	if (!_engine->getSearchManager()->openFile(subFile, subname)) {
+	if (!subFile.open(subname)) {
 		warning("Failed to open subtitle %s", subname.toString().c_str());
 		_toDelete = true;
 		return;
@@ -318,7 +318,7 @@ Subtitle::Subtitle(ZVision *engine, const Common::Path &subname, bool vob) :
 			char filename[64];
 			if (sscanf(str.c_str(), "%*[^:]:%s", filename) == 1) {
 				Common::File txtFile;
-				if (_engine->getSearchManager()->openFile(txtFile, Common::Path(filename))) {
+				if (txtFile.open(Common::Path(filename))) {
 					while (!txtFile.eos()) {
 						Common::String txtline = readWideLine(txtFile).encode();
 						Line curLine;
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index 875c117a6c5..d0e6064e7e6 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -110,8 +110,8 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint st
 
 	Common::File *file = new Common::File();
 	Graphics::Font *newFont;
-	if (!file->open(Common::Path(newFontName)) && !_engine->getSearchManager()->openFile(*file, Common::Path(newFontName)) &&
-	        !file->open(Common::Path(liberationFontName)) && !_engine->getSearchManager()->openFile(*file, Common::Path(liberationFontName))) {
+	if (!file->open(Common::Path(newFontName)) && !file->open(Common::Path(newFontName)) &&
+	        !file->open(Common::Path(liberationFontName)) && !file->open(Common::Path(liberationFontName))) {
 		newFont = Graphics::loadTTFFontFromArchive(liberationFontName, point, Graphics::kTTFSizeModeCell, 0, 0, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal));
 		delete file;
 	} else {
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index e5c2ffba9c5..ced144c4d38 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -58,7 +58,8 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::Path &fileName) {
 	else
 		error("Unknown suffix for animation %s", fileName.toString().c_str());
 
-	Common::File *_file = getSearchManager()->openFile(fileName);
+	Common::File *_file = new Common::File();	//TODO - verify that this is safely deleted when done with
+	_file->open(fileName);
 	if (!_file)
 		error("Error opening %s", fileName.toString().c_str());
 
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index f7ab493fad6..737bd8e771b 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -38,7 +38,7 @@
 #include "zvision/zvision.h"
 #include "zvision/core/console.h"
 #include "zvision/file/save_manager.h"
-#include "zvision/file/search_manager.h"
+#include "zvision/file/zfs_archive.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/graphics/cursors/cursor_manager.h"
 #include "zvision/scripting/menu.h"
@@ -97,7 +97,6 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
 	  _menu(nullptr),
 	  _subtitleManager(nullptr),
 	  _volumeManager(nullptr),
-	  _searchManager(nullptr),
 	  _textRenderer(nullptr),
 	  _doubleFPS(false),
 	  _widescreen(false),
@@ -176,30 +175,6 @@ void ZVision::saveSettings() {
 }
 
 void ZVision::initialize() {
-	// File Paths
-	const Common::FSNode gameDataDir(ConfMan.getPath("path"));
-
-	_searchManager = new SearchManager(ConfMan.getPath("path"), 6);
-
-	_searchManager->addDir("FONTS");
-	_searchManager->addDir("addon");
-	switch (getGameId()) {
-	case GID_GRANDINQUISITOR:
-		if (!_searchManager->loadZix("INQUIS.ZIX"))
-			error("Unable to load file INQUIS.ZIX");
-		break;
-	case GID_NEMESIS:
-		if (!_searchManager->loadZix("NEMESIS.ZIX"))
-			// The game might not be installed, try MEDIUM.ZIX instead
-			if (!_searchManager->loadZix("ZNEMSCR/MEDIUM.ZIX"))
-				error("Unable to load the file ZNEMSCR/MEDIUM.ZIX");
-		break;
-	case GID_NONE:
-	default:
-		error("Unknown/unspecified GameId");
-		break;
-	}
-
 	// Graphics
 	_widescreen = ConfMan.getBool("widescreen");
 	_doubleFPS = ConfMan.getBool("doublefps");
@@ -302,9 +277,9 @@ Common::Error ZVision::run() {
 			liberationFontName += liberationFontSuffixes[j];
 			liberationFontName += ".ttf";
 
-			if (!Common::File::exists(Common::Path(fontName)) && !_searchManager->hasFile(Common::Path(fontName)) &&
-				!Common::File::exists(Common::Path(liberationFontName)) && !_searchManager->hasFile(Common::Path(liberationFontName)) &&
-				!Common::File::exists("fonts.dat") && !_searchManager->hasFile("fonts.dat")) {
+			if (!Common::File::exists(Common::Path(fontName)) && !SearchMan.hasFile(Common::Path(fontName)) &&
+				!Common::File::exists(Common::Path(liberationFontName)) && !SearchMan.hasFile(Common::Path(liberationFontName)) &&
+				!Common::File::exists("fonts.dat") && !SearchMan.hasFile("fonts.dat")) {
 				foundAllFonts = false;
 				break;
 			}
@@ -331,14 +306,14 @@ Common::Error ZVision::run() {
 	}
 	if (getGameId() == GID_NEMESIS && !_midiManager->isAvailable()) {
 		GUI::MessageDialog MIDIdialog(_(
-		                                  "MIDI playback is not available, or else improperly configured. "
-		                                  "Zork Nemesis contains several music puzzles which require "
-		                                  "MIDI audio in order to be solved.  These puzzles may alternatively "
-		                                  "be solved using subtitles, if supported. Continue launching game?"
-		                              ),
-		                              _("Yes"),
-		                              _("No")
-		                             );
+				"MIDI playback is not available, or else improperly configured. "
+				"Zork Nemesis contains several music puzzles which require "
+				"MIDI audio in order to be solved.  These puzzles may alternatively "
+				"be solved using subtitles, if supported. Continue launching game?"
+				),
+				_("Yes"),
+				_("No")
+			);
 		if (MIDIdialog.runModal() != GUI::kMessageOK)
 			quitGame();
 	}
@@ -411,4 +386,154 @@ void ZVision::fpsTimer() {
 	_renderedFrameCount = 0;
 }
 
+void ZVision::initializePath(const Common::FSNode &gamePath) {
+	// File Paths
+	const Common::FSNode gameDataDir(gamePath);
+	SearchMan.setIgnoreClashes(true);
+	SearchMan.addDirectory(gamePath, 0, 5, true);
+	SearchMan.addSubDirectoryMatching(gameDataDir, "FONTS");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "addon");
+	
+	if (ConfMan.hasKey("extrapath")) {
+		Common::Path gameExtraPath = ConfMan.getPath("extrapath");
+		const Common::FSNode gameExtraDir(gameExtraPath);
+		SearchMan.addDirectory(gameExtraPath, 0, 1, true);
+		SearchMan.addSubDirectoryMatching(gameExtraDir, "auxvid");
+		SearchMan.addSubDirectoryMatching(gameExtraDir, "auxscr");
+	}
+	
+	switch (getGameId()) {
+	case GID_GRANDINQUISITOR:
+		if (!loadZix("INQUIS.ZIX"))
+			error("Unable to load file INQUIS.ZIX");
+		break;
+	case GID_NEMESIS:
+		if (!loadZix("NEMESIS.ZIX"))
+			// The game might not be installed, try MEDIUM.ZIX instead
+			if (!loadZix("ZNEMSCR/MEDIUM.ZIX"))
+				error("Unable to load the file ZNEMSCR/MEDIUM.ZIX");
+		break;
+	case GID_NONE:
+	default:
+		error("Unknown/unspecified GameId");
+		break;
+	}
+}
+
+bool ZVision::loadZix(const Common::Path &name) {
+	Common::File file;
+	if (!file.open(name))
+		return false;
+
+	Common::String line;
+
+	//Skip first block
+	while (!file.eos()) {
+		line = file.readLine();
+		if (line.matchString("----------*", true))
+			break;
+	}
+	
+	if (file.eos())
+		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
+
+	uint8 archives = 0;
+
+	//Parse subdirectories & archives
+	debugC(1, kDebugFile, "Parsing list of subdirectories & archives in %s", name.toString(Common::Path::kNativeSeparator).c_str());
+	while (!file.eos()) {
+		line = file.readLine();
+		line.trim();
+		if (line.matchString("----------*", true))
+			break;
+		else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
+			line = Common::String(line.c_str() + 5);
+			for (uint i = 0; i < line.size(); i++)
+				if (line[i] == '\\')
+					line.setChar('/', i);
+
+			// Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
+			// check the game root folder instead
+			if (line.hasPrefix("znemesis/"))
+				line = Common::String(line.c_str() + 9);
+
+			// Check if INQUIS.ZIX refers to the ZGI folder, and check the game
+			// root folder instead
+			if (line.hasPrefix("zgi/"))
+				line = Common::String(line.c_str() + 4);
+			if (line.hasPrefix("zgi_e/"))
+				line = Common::String(line.c_str() + 6);
+
+			if (line.size() && line[0] == '.')
+				line.deleteChar(0);
+			if (line.size() && line[0] == '/')
+				line.deleteChar(0);
+			if (line.size() && line.hasSuffix("/"))
+				line.deleteLastChar();
+
+			Common::Path path(line, '/');
+			path = path.getLastComponent();	//We are using the search manager in "flat" mode, so only filenames are needed
+
+			if (line.matchString("*.zfs", true)) {
+				debugC(1, kDebugFile, "Adding archive %s to search manager.", path.toString().c_str());
+				Common::Archive *arc;
+				arc = new ZfsArchive(path);
+				SearchMan.add(line, arc);
+			}
+			archives++;
+		}
+	}
+
+	if (file.eos())
+		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
+	
+	const char* genExcluded[] {"*.dll", "*.ini", "*.exe", "*.isu", "*.inf", "*path*.txt", "r.svr", "*.zix"};
+	const char* zgiExcluded[] {
+		"c000h01q.raw", "cm00h01q.raw", "dm00h01q.raw", "e000h01q.raw", "em00h11p.raw", "em00h50q.raw", "gjnph65p.raw", 
+		"gjnph72p.raw", "h000h01q.raw", "m000h01q.raw", "p000h01q.raw", "q000h01q.raw", "sw00h01q.raw", "t000h01q.raw", 
+		"u000h01q.raw"
+		};
+
+	//Parse files
+	debugC(1, kDebugFile, "Parsing list of individual resource files in %s", name.toString(Common::Path::kNativeSeparator).c_str());
+	while (!file.eos()) {
+		line = file.readLine();
+		line.trim();
+		uint dr = 0;
+		char buf[32];
+		if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
+			if (dr <= archives && dr > 0) {
+				Common::String path(buf);
+				bool exclude = false;
+				for(auto filename : genExcluded)
+					if(path.matchString(filename, true)) {
+						exclude = true;
+						break;
+					}
+				for(auto filename : zgiExcluded)
+					if(path.matchString(filename, true)) {
+						//exclude = true;
+						break;
+					}
+				if(!exclude) {
+					//No need to add file, just verify that it exists
+					Common::File resource;
+					if(!resource.exists(buf))
+						warning("Missing file %s", path.c_str());
+					else
+						debugC(5, kDebugFile, "File found: %s", path.c_str());
+					if(path.matchString("*.zfs", true)) {
+						Common::Path path_(path);
+						debugC(kDebugFile, "Adding archive %s to search manager.", path.c_str());
+						Common::Archive *arc;
+						arc = new ZfsArchive(path_);
+						SearchMan.add(path, arc);
+					}
+				}
+			}
+		}
+	}
+	return true;
+}
+
 } // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index b212ea169a8..3a7f26a7dfb 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -30,7 +30,6 @@
 #include "gui/debugger.h"
 #include "zvision/detection.h"
 #include "zvision/core/clock.h"
-#include "zvision/file/search_manager.h"
 
 namespace Common {
 class Keymap;
@@ -142,7 +141,6 @@ private:
 	RenderManager *_renderManager;
 	CursorManager *_cursorManager;
 	StringManager *_stringManager;
-	SearchManager *_searchManager;
 	TextRenderer *_textRenderer;
 	MidiManager *_midiManager;
 	SaveManager *_saveManager;
@@ -196,9 +194,6 @@ public:
 	StringManager *getStringManager() const {
 		return _stringManager;
 	}
-	SearchManager *getSearchManager() const {
-		return _searchManager;
-	}
 	TextRenderer *getTextRenderer() const {
 		return _textRenderer;
 	}
@@ -281,6 +276,8 @@ public:
 private:
 	void initialize();
 	void initFonts();
+	
+	void initializePath(const Common::FSNode &gamePath) override;
 
 	void parseStrFile(const Common::String &fileName);
 
@@ -297,6 +294,7 @@ private:
 	uint8 getBufferedKey(uint8 pos);
 
 	double getVobAmplification(Common::String fileName) const;
+	bool loadZix(const Common::Path &name);
 };
 
 } // End of namespace ZVision


Commit: 7c5ab5844f16d0441e78d1503a8af99b599aecdc
    https://github.com/scummvm/scummvm/commit/7c5ab5844f16d0441e78d1503a8af99b599aecdc
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Code cleanup & additional comment.

Changed paths:
    engines/zvision/scripting/actions.h
    engines/zvision/zvision.cpp


diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
index 137d89732d6..2b75141f6ea 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -402,10 +402,6 @@ public:
 	bool execute() override;
 
 private:
-	enum {
-		DIFFERENT_DIMENSIONS = 0x1 // 0x1 flags that the destRect dimensions are different from the original video dimensions
-	};
-
 	Common::Path _fileName;
 	uint _x1;
 	uint _y1;
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 737bd8e771b..583068e3691 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -488,6 +488,7 @@ bool ZVision::loadZix(const Common::Path &name) {
 		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
 	
 	const char* genExcluded[] {"*.dll", "*.ini", "*.exe", "*.isu", "*.inf", "*path*.txt", "r.svr", "*.zix"};
+	//TODO - change this to a list of alternate pairs; only throw an error if both alternatives are unavailable
 	const char* zgiExcluded[] {
 		"c000h01q.raw", "cm00h01q.raw", "dm00h01q.raw", "e000h01q.raw", "em00h11p.raw", "em00h50q.raw", "gjnph65p.raw", 
 		"gjnph72p.raw", "h000h01q.raw", "m000h01q.raw", "p000h01q.raw", "q000h01q.raw", "sw00h01q.raw", "t000h01q.raw", 


Commit: f4881416f93ccc00afd3c8f5fd5ac0255f093b5a
    https://github.com/scummvm/scummvm/commit/f4881416f93ccc00afd3c8f5fd5ac0255f093b5a
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Code cleanup.

Changed paths:
    engines/zvision/sound/volume_manager.cpp


diff --git a/engines/zvision/sound/volume_manager.cpp b/engines/zvision/sound/volume_manager.cpp
index e44061e7039..2f7347286de 100644
--- a/engines/zvision/sound/volume_manager.cpp
+++ b/engines/zvision/sound/volume_manager.cpp
@@ -135,15 +135,15 @@ static constexpr uint8 directionalAmplitude[181] = {
 VolumeManager::VolumeManager(ZVision *engine, volumeScaling mode) :
 	_engine(engine),
 	_mode(mode) {
-};
+}
 
 uint8 VolumeManager::convert(uint8 inputValue) {
 	return convert(inputValue, _mode);
-};
+}
 
 uint8 VolumeManager::convert(uint8 inputValue, Math::Angle azimuth, uint8 directionality) {
 	return convert(inputValue, _mode, azimuth, directionality);
-};
+}
 
 uint8 VolumeManager::convert(uint8 inputValue, volumeScaling &mode, Math::Angle azimuth, uint8 directionality) {
 	uint8 index = abs(round(azimuth.getDegrees(-180)));
@@ -154,7 +154,7 @@ uint8 VolumeManager::convert(uint8 inputValue, volumeScaling &mode, Math::Angle
 	output = (output + directionalOutput) / 0xFF;
 	debugC(4, kDebugSound, "Directionally converted output %d", output);
 	return output;
-};
+}
 
 uint8 VolumeManager::convert(uint8 inputValue, volumeScaling &mode) {
 	if (inputValue > _scriptScale)
@@ -192,6 +192,6 @@ uint8 VolumeManager::convert(uint8 inputValue, volumeScaling &mode) {
 	}
 	debugC(4, kDebugSound, "Scripted volume %d, scaled volume %d, converted output %d", inputValue, scaledInput, output);
 	return output;
-};
+}
 
 } // End of namespace ZVision


Commit: 193358a03510fa286f8681f6734336be52045094
    https://github.com/scummvm/scummvm/commit/193358a03510fa286f8681f6734336be52045094
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Add FileManager class to automatically handle loading of alternate .raw files.
TODO: Adapt engine code to make use of this new functionality.

Changed paths:
  A engines/zvision/file/file_manager.cpp
  A engines/zvision/file/file_manager.h
    engines/zvision/module.mk
    engines/zvision/zvision.cpp
    engines/zvision/zvision.h


diff --git a/engines/zvision/file/file_manager.cpp b/engines/zvision/file/file_manager.cpp
new file mode 100644
index 00000000000..8648fe67e6e
--- /dev/null
+++ b/engines/zvision/file/file_manager.cpp
@@ -0,0 +1,203 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/debug.h"
+#include "zvision/file/file_manager.h"
+#include "zvision/file/zfs_archive.h"
+
+namespace ZVision {
+
+const char* genExcluded[] {"*.dll", "*.ini", "*.exe", "*.isu", "*.inf", "*path*.txt", "r.svr", "*.zix"};
+//TODO - change this to a list of alternate pairs; only throw an error if both alternatives are unavailable
+const char* zgiExcluded[] {
+	"c000h01q.raw", "cm00h01q.raw", "dm00h01q.raw", "e000h01q.raw", "em00h11p.raw", "em00h50q.raw", "gjnph65p.raw", 
+	"gjnph72p.raw", "h000h01q.raw", "m000h01q.raw", "p000h01q.raw", "q000h01q.raw", "sw00h01q.raw", "t000h01q.raw", 
+	"u000h01q.raw"
+	};
+	
+FileManager::FileManager(ZVision *engine) : 
+	_engine(engine) {}
+
+Common::File *FileManager::open(const Common::Path &filePath, bool allowSrc) {
+	Common::File *file = new Common::File();
+	Common::String fileName = filePath.baseName();
+	bool found = SearchMan.hasFile(filePath);
+	bool foundAlt = false;
+	
+	if (allowSrc) {
+		Common::String altName = fileName;
+		altName.setChar('s', altName.size() - 3);
+		altName.setChar('r', altName.size() - 2);
+		altName.setChar('c', altName.size() - 1);
+		Common::Path altPath = filePath.getParent().appendComponent(altName);
+		foundAlt = SearchMan.hasFile(altPath);
+		if (!foundAlt) {
+			if (!found)
+				warning("Unable to find file %s or alternate file %s", fileName.c_str(), altName.c_str());
+		}
+		else {
+			Common::File *altFile = new Common::File();
+			if (!altFile->open(altPath))
+				warning("File %s not found; alternate file %s found but unable to open", fileName.c_str(), altName.c_str());
+			else {
+				if (!file->open(filePath)) {
+					delete file;
+					debugC(2, kDebugFile,"Opened alternative file %s", altName.c_str());
+					return altFile;
+				}
+				else if (file->size() < altFile->size()) {
+					file->close();
+					delete file;
+					debugC(2, kDebugFile,"Opened alternative file %s", altName.c_str());
+					return altFile;
+				}
+				else
+					altFile->close();
+			}
+			delete altFile;
+		}
+	}
+	
+	if (!found) {
+		if(!allowSrc)
+			warning("File %s not found", fileName.c_str());
+	}
+	else if (!file->open(filePath))
+		warning("File %s found, but unable to open", fileName.c_str());
+	else {
+		debugC(2, kDebugFile,"Opened file %s", fileName.c_str());
+		return file;
+	}
+	
+	delete file;
+	return nullptr;
+}
+
+bool FileManager::loadZix(const Common::Path &name) {
+	Common::File file;
+	if (!file.open(name))
+		return false;
+
+	Common::String line;
+
+	// Skip first block
+	while (!file.eos()) {
+		line = file.readLine();
+		if (line.matchString("----------*", true))
+			break;
+	}
+	
+	if (file.eos())
+		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
+
+	uint8 archives = 0;
+
+	// Parse subdirectories & archives
+	debugC(1, kDebugFile, "Parsing list of subdirectories & archives in %s", name.toString(Common::Path::kNativeSeparator).c_str());
+	while (!file.eos()) {
+		line = file.readLine();
+		line.trim();
+		if (line.matchString("----------*", true))
+			break;
+		else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
+			line = Common::String(line.c_str() + 5);
+			for (uint i = 0; i < line.size(); i++)
+				if (line[i] == '\\')
+					line.setChar('/', i);
+
+			// Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
+			// check the game root folder instead
+			if (line.hasPrefix("znemesis/"))
+				line = Common::String(line.c_str() + 9);
+
+			// Check if INQUIS.ZIX refers to the ZGI folder, and check the game
+			// root folder instead
+			if (line.hasPrefix("zgi/"))
+				line = Common::String(line.c_str() + 4);
+			if (line.hasPrefix("zgi_e/"))
+				line = Common::String(line.c_str() + 6);
+
+			if (line.size() && line[0] == '.')
+				line.deleteChar(0);
+			if (line.size() && line[0] == '/')
+				line.deleteChar(0);
+			if (line.size() && line.hasSuffix("/"))
+				line.deleteLastChar();
+
+			Common::Path path(line, '/');
+			path = path.getLastComponent();	//We are using the search manager in "flat" mode, so only filenames are needed
+
+			if (line.matchString("*.zfs", true)) {
+				debugC(1, kDebugFile, "Adding archive %s to search manager.", path.toString().c_str());
+				Common::Archive *arc;
+				arc = new ZfsArchive(path);
+				SearchMan.add(line, arc);
+			}
+			archives++;
+		}
+	}
+
+	if (file.eos())
+		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
+
+	//Parse files
+	debugC(1, kDebugFile, "Parsing list of individual resource files in %s", name.toString(Common::Path::kNativeSeparator).c_str());
+	while (!file.eos()) {
+		line = file.readLine();
+		line.trim();
+		uint dr = 0;
+		char buf[32];
+		if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
+			if (dr <= archives && dr > 0) {
+				Common::String path(buf);
+				bool exclude = false;
+				for(auto filename : genExcluded)
+					if(path.matchString(filename, true)) {
+						exclude = true;
+						break;
+					}
+				for(auto filename : zgiExcluded)
+					if(path.matchString(filename, true)) {
+						//exclude = true;
+						break;
+					}
+				if(!exclude) {
+					// No need to add file, just verify that it exists
+					Common::File resource;
+					if(!resource.exists(buf))
+						warning("Missing file %s", path.c_str());
+					else
+						debugC(5, kDebugFile, "File found: %s", path.c_str());
+					if(path.matchString("*.zfs", true)) {
+						Common::Path path_(path);
+						debugC(kDebugFile, "Adding archive %s to search manager.", path.c_str());
+						Common::Archive *arc;
+						arc = new ZfsArchive(path_);
+						SearchMan.add(path, arc);
+					}
+				}
+			}
+		}
+	}
+	return true;
+}
+
+}	// End of namespace Zvision
diff --git a/engines/zvision/file/file_manager.h b/engines/zvision/file/file_manager.h
new file mode 100644
index 00000000000..8a7d11dbbac
--- /dev/null
+++ b/engines/zvision/file/file_manager.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/file.h"
+#include "common/path.h"
+#include "zvision/zvision.h"
+
+#ifndef ZVISION_FILE_MANAGER
+#define ZVISION_FILE_MANAGER
+
+namespace ZVision {
+
+class FileManager {
+public:
+	FileManager(ZVision *engine);
+	~FileManager() {};
+	
+	bool loadZix(const Common::Path &name);
+	Common::File *open(const Common::Path &fileName, bool allowSrc=true);	// Wrapper to automatically handle loading of files which may be empty & have an alternate .src file
+
+private:
+	ZVision *_engine;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index eb56f74d4c2..6ab5c04bd1c 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
 	core/console.o \
 	core/events.o \
 	file/lzss_read_stream.o \
+	file/file_manager.o \
 	file/save_manager.o \
 	file/zfs_archive.o \
 	graphics/cursors/cursor.o \
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 583068e3691..54ce44b2a57 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -37,8 +37,8 @@
 #include "gui/message.h"
 #include "zvision/zvision.h"
 #include "zvision/core/console.h"
+#include "zvision/file/file_manager.h"
 #include "zvision/file/save_manager.h"
-#include "zvision/file/zfs_archive.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/graphics/cursors/cursor_manager.h"
 #include "zvision/scripting/menu.h"
@@ -89,6 +89,7 @@ ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
 	  _clock(_system),
 	  _scriptManager(nullptr),
 	  _renderManager(nullptr),
+	  _fileManager(nullptr),
 	  _saveManager(nullptr),
 	  _stringManager(nullptr),
 	  _cursorManager(nullptr),
@@ -119,6 +120,7 @@ ZVision::~ZVision() {
 	// Dispose of resources
 	delete _cursorManager;
 	delete _stringManager;
+	delete _fileManager;
 	delete _saveManager;
 	delete _scriptManager;
 	delete _renderManager;	// should be deleted after the script manager
@@ -210,6 +212,7 @@ void ZVision::initialize() {
 		break;
 	}
 	_scriptManager = new ScriptManager(this);
+	_fileManager = new FileManager(this);
 	_saveManager = new SaveManager(this);
 	_stringManager = new StringManager(this);
 	_cursorManager = new CursorManager(this, _resourcePixelFormat);
@@ -404,13 +407,13 @@ void ZVision::initializePath(const Common::FSNode &gamePath) {
 	
 	switch (getGameId()) {
 	case GID_GRANDINQUISITOR:
-		if (!loadZix("INQUIS.ZIX"))
+		if (!_fileManager->loadZix("INQUIS.ZIX"))
 			error("Unable to load file INQUIS.ZIX");
 		break;
 	case GID_NEMESIS:
-		if (!loadZix("NEMESIS.ZIX"))
+		if (!_fileManager->loadZix("NEMESIS.ZIX"))
 			// The game might not be installed, try MEDIUM.ZIX instead
-			if (!loadZix("ZNEMSCR/MEDIUM.ZIX"))
+			if (!_fileManager->loadZix("ZNEMSCR/MEDIUM.ZIX"))
 				error("Unable to load the file ZNEMSCR/MEDIUM.ZIX");
 		break;
 	case GID_NONE:
@@ -420,121 +423,4 @@ void ZVision::initializePath(const Common::FSNode &gamePath) {
 	}
 }
 
-bool ZVision::loadZix(const Common::Path &name) {
-	Common::File file;
-	if (!file.open(name))
-		return false;
-
-	Common::String line;
-
-	//Skip first block
-	while (!file.eos()) {
-		line = file.readLine();
-		if (line.matchString("----------*", true))
-			break;
-	}
-	
-	if (file.eos())
-		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
-
-	uint8 archives = 0;
-
-	//Parse subdirectories & archives
-	debugC(1, kDebugFile, "Parsing list of subdirectories & archives in %s", name.toString(Common::Path::kNativeSeparator).c_str());
-	while (!file.eos()) {
-		line = file.readLine();
-		line.trim();
-		if (line.matchString("----------*", true))
-			break;
-		else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
-			line = Common::String(line.c_str() + 5);
-			for (uint i = 0; i < line.size(); i++)
-				if (line[i] == '\\')
-					line.setChar('/', i);
-
-			// Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
-			// check the game root folder instead
-			if (line.hasPrefix("znemesis/"))
-				line = Common::String(line.c_str() + 9);
-
-			// Check if INQUIS.ZIX refers to the ZGI folder, and check the game
-			// root folder instead
-			if (line.hasPrefix("zgi/"))
-				line = Common::String(line.c_str() + 4);
-			if (line.hasPrefix("zgi_e/"))
-				line = Common::String(line.c_str() + 6);
-
-			if (line.size() && line[0] == '.')
-				line.deleteChar(0);
-			if (line.size() && line[0] == '/')
-				line.deleteChar(0);
-			if (line.size() && line.hasSuffix("/"))
-				line.deleteLastChar();
-
-			Common::Path path(line, '/');
-			path = path.getLastComponent();	//We are using the search manager in "flat" mode, so only filenames are needed
-
-			if (line.matchString("*.zfs", true)) {
-				debugC(1, kDebugFile, "Adding archive %s to search manager.", path.toString().c_str());
-				Common::Archive *arc;
-				arc = new ZfsArchive(path);
-				SearchMan.add(line, arc);
-			}
-			archives++;
-		}
-	}
-
-	if (file.eos())
-		error("Corrupt ZIX file: %s", name.toString(Common::Path::kNativeSeparator).c_str());
-	
-	const char* genExcluded[] {"*.dll", "*.ini", "*.exe", "*.isu", "*.inf", "*path*.txt", "r.svr", "*.zix"};
-	//TODO - change this to a list of alternate pairs; only throw an error if both alternatives are unavailable
-	const char* zgiExcluded[] {
-		"c000h01q.raw", "cm00h01q.raw", "dm00h01q.raw", "e000h01q.raw", "em00h11p.raw", "em00h50q.raw", "gjnph65p.raw", 
-		"gjnph72p.raw", "h000h01q.raw", "m000h01q.raw", "p000h01q.raw", "q000h01q.raw", "sw00h01q.raw", "t000h01q.raw", 
-		"u000h01q.raw"
-		};
-
-	//Parse files
-	debugC(1, kDebugFile, "Parsing list of individual resource files in %s", name.toString(Common::Path::kNativeSeparator).c_str());
-	while (!file.eos()) {
-		line = file.readLine();
-		line.trim();
-		uint dr = 0;
-		char buf[32];
-		if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
-			if (dr <= archives && dr > 0) {
-				Common::String path(buf);
-				bool exclude = false;
-				for(auto filename : genExcluded)
-					if(path.matchString(filename, true)) {
-						exclude = true;
-						break;
-					}
-				for(auto filename : zgiExcluded)
-					if(path.matchString(filename, true)) {
-						//exclude = true;
-						break;
-					}
-				if(!exclude) {
-					//No need to add file, just verify that it exists
-					Common::File resource;
-					if(!resource.exists(buf))
-						warning("Missing file %s", path.c_str());
-					else
-						debugC(5, kDebugFile, "File found: %s", path.c_str());
-					if(path.matchString("*.zfs", true)) {
-						Common::Path path_(path);
-						debugC(kDebugFile, "Adding archive %s to search manager.", path.c_str());
-						Common::Archive *arc;
-						arc = new ZfsArchive(path_);
-						SearchMan.add(path, arc);
-					}
-				}
-			}
-		}
-	}
-	return true;
-}
-
 } // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 3a7f26a7dfb..4c8eb3e307a 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -58,6 +58,7 @@ class ScriptManager;
 class RenderManager;
 class CursorManager;
 class StringManager;
+class FileManager;
 class SaveManager;
 class RLFDecoder;
 class MenuManager;
@@ -143,6 +144,7 @@ private:
 	StringManager *_stringManager;
 	TextRenderer *_textRenderer;
 	MidiManager *_midiManager;
+	FileManager *_fileManager;
 	SaveManager *_saveManager;
 	MenuManager *_menu;
 	SubtitleManager *_subtitleManager;
@@ -188,6 +190,9 @@ public:
 	CursorManager *getCursorManager() const {
 		return _cursorManager;
 	}
+	FileManager *getFileManager() const {
+		return _fileManager;
+	}
 	SaveManager *getSaveManager() const {
 		return _saveManager;
 	}
@@ -294,7 +299,6 @@ private:
 	uint8 getBufferedKey(uint8 pos);
 
 	double getVobAmplification(Common::String fileName) const;
-	bool loadZix(const Common::Path &name);
 };
 
 } // End of namespace ZVision


Commit: 34d0904e2f8d563b7baf22fb1d36d4c1eebb6780
    https://github.com/scummvm/scummvm/commit/34d0904e2f8d563b7baf22fb1d36d4c1eebb6780
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Move getVobAmplification() to VolumeManager to improve encapsulation.

Changed paths:
    engines/zvision/sound/volume_manager.cpp
    engines/zvision/sound/volume_manager.h
    engines/zvision/video/video.cpp
    engines/zvision/zvision.h


diff --git a/engines/zvision/sound/volume_manager.cpp b/engines/zvision/sound/volume_manager.cpp
index 2f7347286de..341daded96f 100644
--- a/engines/zvision/sound/volume_manager.cpp
+++ b/engines/zvision/sound/volume_manager.cpp
@@ -194,4 +194,99 @@ uint8 VolumeManager::convert(uint8 inputValue, volumeScaling &mode) {
 	return output;
 }
 
+#if defined(USE_MPEG2) && defined(USE_A52)
+double VolumeManager::getVobAmplification(Common::String fileName) const {
+	// For some reason, we get much lower volume in the hi-res videos than
+	// in the low-res ones. So we artificially boost the volume. This is an
+	// approximation, but I've tried to match the old volumes reasonably
+	// well.
+	//
+	// Some of these will cause audio clipping. Hopefully not enough to be
+	// noticeable.
+	double amplification = 0.0;
+	if (fileName == "em00d011.vob") {
+		// The finale.
+		amplification = 10.0;
+	} else if (fileName == "em00d021.vob") {
+		// Jack's escape and arrival at Flathead Mesa.
+		amplification = 9.0;
+	} else if (fileName == "em00d032.vob") {
+		// The Grand Inquisitor's speech.
+		amplification = 11.0;
+	} else if (fileName == "em00d122.vob") {
+		// Jack orders you to the radio tower.
+		amplification = 17.0;
+	} else if (fileName == "em3ed012.vob") {
+		// The Grand Inquisitor gets the Coconut of Quendor.
+		amplification = 12.0;
+	} else if (fileName == "g000d101.vob") {
+		// Griff gets captured.
+		amplification = 11.0;
+	} else if (fileName == "g000d111.vob") {
+		// Brog gets totemized. The music seems to be mixed much softer
+		// in this than in the low-resolution version.
+		amplification = 12.0;
+	} else if (fileName == "g000d122.vob") {
+		// Lucy gets captured.
+		amplification = 14.0;
+	} else if (fileName == "g000d302.vob") {
+		// The Grand Inquisitor visits Jack in his cell.
+		amplification = 13.0;
+	} else if (fileName == "g000d312.vob") {
+		// You get captured.
+		amplification = 14.0;
+	} else if (fileName == "g000d411.vob") {
+		// Propaganda On Parade. No need to make it as loud as the
+		// low-resolution version.
+		amplification = 11.0;
+	} else if (fileName == "pe1ed012.vob") {
+		// Jack lets you in with the lantern.
+		amplification = 14.0;
+	} else if (fileName.hasPrefix("pe1ed")) {
+		// Jack answers the door. Several different ways.
+		amplification = 17.0;
+	} else if (fileName == "pe5ed052.vob") {
+		// You get killed by the guards
+		amplification = 12.0;
+	} else if (fileName == "pe6ed012.vob") {
+		// Jack gets captured by the guards
+		amplification = 17.0;
+	} else if (fileName == "pp1ed022.vob") {
+		// Jack examines the lantern
+		amplification = 10.0;
+	} else if (fileName == "qb1ed012.vob") {
+		// Lucy gets invited to the back room
+		amplification = 17.0;
+	} else if (fileName.hasPrefix("qe1ed")) {
+		// Floyd answers the door. Several different ways.
+		amplification = 17.0;
+	} else if (fileName == "qs1ed011.vob") {
+		// Jack explains the rules of the game.
+		amplification = 16.0;
+	} else if (fileName == "qs1ed021.vob") {
+		// Jack loses the game.
+		amplification = 14.0;
+	} else if (fileName == "uc1gd012.vob") {
+		// Y'Gael appears.
+		amplification = 12.0;
+	} else if (fileName == "ue1ud012.vob") {
+		// Jack gets totemized... or what?
+		amplification = 12.0;
+	} else if (fileName == "ue2qd012.vob") {
+		// Jack agrees to totemization.
+		amplification = 10.0;
+	} else if (fileName == "g000d981.vob") {
+		// The Enterprise logo. Has no low-res version. Its volume is
+		// louder than the other logo animations.
+		amplification = 6.2;
+	} else if (fileName.hasPrefix("g000d")) {
+		// The Dolby Digital and Activision logos. They have no low-res
+		// versions, but I've used the low-resolution Activision logo
+		// (slightly different) as reference.
+		amplification = 8.5;
+	}
+	return amplification;
+}
+#endif
+
 } // End of namespace ZVision
diff --git a/engines/zvision/sound/volume_manager.h b/engines/zvision/sound/volume_manager.h
index 8034a3ae600..4c587a910b2 100644
--- a/engines/zvision/sound/volume_manager.h
+++ b/engines/zvision/sound/volume_manager.h
@@ -52,6 +52,10 @@ public:
 	uint8 convert(uint8 inputValue, volumeScaling &mode);
 	uint8 convert(uint8 inputValue, Math::Angle azimuth, uint8 directionality = 255);
 	uint8 convert(uint8 inputValue, volumeScaling &mode, Math::Angle azimuth, uint8 directionality = 255);
+#if defined(USE_MPEG2) && defined(USE_A52)
+	double getVobAmplification(Common::String fileName) const;
+#endif
+	
 private:
 	ZVision *_engine;
 	uint _scriptScale = 100; // Z-Vision scripts internally use a volume scale of 0-100; ScummVM uses a scale of 0-255.
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index ced144c4d38..5f12bc0c6af 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -32,6 +32,7 @@
 #include "zvision/core/clock.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/scripting/script_manager.h"
+#include "zvision/sound/volume_manager.h"
 #include "zvision/text/subtitle_manager.h"
 #include "zvision/video/rlf_decoder.h"
 #include "zvision/video/zork_avi_decoder.h"
@@ -51,7 +52,7 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::Path &fileName) {
 		animation = new ZorkAVIDecoder();
 #if defined(USE_MPEG2) && defined(USE_A52)
 	else if (tmpFileName.hasSuffix(".vob")) {
- 		double amplification = getVobAmplification(tmpFileName);
+ 		double amplification = getVolumeManager()->getVobAmplification(tmpFileName);
 		animation = new Video::MPEGPSDecoder(amplification);
 	}
 #endif
@@ -188,97 +189,4 @@ void ZVision::playVideo(Video::VideoDecoder &vid, Common::Rect dstRect, bool ski
 	debugC(1, kDebugVideo, "Video playback complete");
 }
 
-double ZVision::getVobAmplification(Common::String fileName) const {
-	// For some reason, we get much lower volume in the hi-res videos than
-	// in the low-res ones. So we artificially boost the volume. This is an
-	// approximation, but I've tried to match the old volumes reasonably
-	// well.
-	//
-	// Some of these will cause audio clipping. Hopefully not enough to be
-	// noticeable.
-	double amplification = 0.0;
-	if (fileName == "em00d011.vob") {
-		// The finale.
-		amplification = 10.0;
-	} else if (fileName == "em00d021.vob") {
-		// Jack's escape and arrival at Flathead Mesa.
-		amplification = 9.0;
-	} else if (fileName == "em00d032.vob") {
-		// The Grand Inquisitor's speech.
-		amplification = 11.0;
-	} else if (fileName == "em00d122.vob") {
-		// Jack orders you to the radio tower.
-		amplification = 17.0;
-	} else if (fileName == "em3ed012.vob") {
-		// The Grand Inquisitor gets the Coconut of Quendor.
-		amplification = 12.0;
-	} else if (fileName == "g000d101.vob") {
-		// Griff gets captured.
-		amplification = 11.0;
-	} else if (fileName == "g000d111.vob") {
-		// Brog gets totemized. The music seems to be mixed much softer
-		// in this than in the low-resolution version.
-		amplification = 12.0;
-	} else if (fileName == "g000d122.vob") {
-		// Lucy gets captured.
-		amplification = 14.0;
-	} else if (fileName == "g000d302.vob") {
-		// The Grand Inquisitor visits Jack in his cell.
-		amplification = 13.0;
-	} else if (fileName == "g000d312.vob") {
-		// You get captured.
-		amplification = 14.0;
-	} else if (fileName == "g000d411.vob") {
-		// Propaganda On Parade. No need to make it as loud as the
-		// low-resolution version.
-		amplification = 11.0;
-	} else if (fileName == "pe1ed012.vob") {
-		// Jack lets you in with the lantern.
-		amplification = 14.0;
-	} else if (fileName.hasPrefix("pe1ed")) {
-		// Jack answers the door. Several different ways.
-		amplification = 17.0;
-	} else if (fileName == "pe5ed052.vob") {
-		// You get killed by the guards
-		amplification = 12.0;
-	} else if (fileName == "pe6ed012.vob") {
-		// Jack gets captured by the guards
-		amplification = 17.0;
-	} else if (fileName == "pp1ed022.vob") {
-		// Jack examines the lantern
-		amplification = 10.0;
-	} else if (fileName == "qb1ed012.vob") {
-		// Lucy gets invited to the back room
-		amplification = 17.0;
-	} else if (fileName.hasPrefix("qe1ed")) {
-		// Floyd answers the door. Several different ways.
-		amplification = 17.0;
-	} else if (fileName == "qs1ed011.vob") {
-		// Jack explains the rules of the game.
-		amplification = 16.0;
-	} else if (fileName == "qs1ed021.vob") {
-		// Jack loses the game.
-		amplification = 14.0;
-	} else if (fileName == "uc1gd012.vob") {
-		// Y'Gael appears.
-		amplification = 12.0;
-	} else if (fileName == "ue1ud012.vob") {
-		// Jack gets totemized... or what?
-		amplification = 12.0;
-	} else if (fileName == "ue2qd012.vob") {
-		// Jack agrees to totemization.
-		amplification = 10.0;
-	} else if (fileName == "g000d981.vob") {
-		// The Enterprise logo. Has no low-res version. Its volume is
-		// louder than the other logo animations.
-		amplification = 6.2;
-	} else if (fileName.hasPrefix("g000d")) {
-		// The Dolby Digital and Activision logos. They have no low-res
-		// versions, but I've used the low-resolution Activision logo
-		// (slightly different) as reference.
-		amplification = 8.5;
-	}
-	return amplification;
-}
-
 } // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
index 4c8eb3e307a..6ddbfd77cd3 100644
--- a/engines/zvision/zvision.h
+++ b/engines/zvision/zvision.h
@@ -297,8 +297,6 @@ private:
 	void pushKeyToCheatBuf(uint8 key);
 	bool checkCode(const char *code);
 	uint8 getBufferedKey(uint8 pos);
-
-	double getVobAmplification(Common::String fileName) const;
 };
 
 } // End of namespace ZVision


Commit: 0f6c5d6ba4ec2b133c512fb06d7a5de8ea25021a
    https://github.com/scummvm/scummvm/commit/0f6c5d6ba4ec2b133c512fb06d7a5de8ea25021a
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Fix incorrect FileManager::open() functionality.
Improve function readability & layout.

Changed paths:
    engines/zvision/file/file_manager.cpp


diff --git a/engines/zvision/file/file_manager.cpp b/engines/zvision/file/file_manager.cpp
index 8648fe67e6e..d0a19b315dc 100644
--- a/engines/zvision/file/file_manager.cpp
+++ b/engines/zvision/file/file_manager.cpp
@@ -37,58 +37,83 @@ FileManager::FileManager(ZVision *engine) :
 	_engine(engine) {}
 
 Common::File *FileManager::open(const Common::Path &filePath, bool allowSrc) {
+	debugC(5, kDebugFile, "FileManager::open()");
 	Common::File *file = new Common::File();
+	Common::File *out = nullptr;
+	
 	Common::String fileName = filePath.baseName();
+	bool open = false;
+	bool altFound = false;
+	bool altOpen = false;
+	
 	bool found = SearchMan.hasFile(filePath);
-	bool foundAlt = false;
+	if(found) {
+		debugC(5, kDebugFile,"File %s found", fileName.c_str());
+		open = file->open(filePath);
+		if(open)
+			debugC(5, kDebugFile,"File %s opened", fileName.c_str());
+	}
 	
 	if (allowSrc) {
+		Common::File *altFile = new Common::File();
 		Common::String altName = fileName;
 		altName.setChar('s', altName.size() - 3);
 		altName.setChar('r', altName.size() - 2);
 		altName.setChar('c', altName.size() - 1);
 		Common::Path altPath = filePath.getParent().appendComponent(altName);
-		foundAlt = SearchMan.hasFile(altPath);
-		if (!foundAlt) {
-			if (!found)
+		altFound = SearchMan.hasFile(altPath);
+		if (altFound) {
+			debugC(5, kDebugFile,"Alternate file %s found", altName.c_str());
+			altOpen = altFile->open(altPath);
+			if (altOpen)
+				debugC(5, kDebugFile,"Alternate file %s opened", altName.c_str());
+		}
+		
+		if(altOpen) {
+			if(open)
+				out = file->size() < altFile->size() ? altFile : file;
+			else
+				out = altFile;
+		}
+		else if(open)
+			out = file;
+		else {
+			if (found && altFound)
+				warning("Found file %s and alternate file %s but unable to open either", fileName.c_str(), altName.c_str());
+			else if (found)
+				warning("Found file %s but unable to open; alternate file %s not found", fileName.c_str(), altName.c_str());
+			else if (altFound)
+				warning("File %s not found; alternate file %s found but but unable to open", fileName.c_str(), altName.c_str());
+			else
 				warning("Unable to find file %s or alternate file %s", fileName.c_str(), altName.c_str());
 		}
+		
+		if (out == altFile) 
+			debugC(5, kDebugFile,"Returning alternate file %s", altName.c_str());
 		else {
-			Common::File *altFile = new Common::File();
-			if (!altFile->open(altPath))
-				warning("File %s not found; alternate file %s found but unable to open", fileName.c_str(), altName.c_str());
-			else {
-				if (!file->open(filePath)) {
-					delete file;
-					debugC(2, kDebugFile,"Opened alternative file %s", altName.c_str());
-					return altFile;
-				}
-				else if (file->size() < altFile->size()) {
-					file->close();
-					delete file;
-					debugC(2, kDebugFile,"Opened alternative file %s", altName.c_str());
-					return altFile;
-				}
-				else
-					altFile->close();
-			}
+			if(altOpen)
+				altFile->close();
 			delete altFile;
 		}
 	}
-	
-	if (!found) {
-		if(!allowSrc)
+	else {
+		if(open)
+			out = file;
+		else if (found)
+			warning("File %s found, but unable to open", fileName.c_str());
+		else
 			warning("File %s not found", fileName.c_str());
 	}
-	else if (!file->open(filePath))
-		warning("File %s found, but unable to open", fileName.c_str());
+	
+	if (out == file) 
+		debugC(5, kDebugFile,"Returning file %s", fileName.c_str());
 	else {
-		debugC(2, kDebugFile,"Opened file %s", fileName.c_str());
-		return file;
+		if(open)
+			file->close();
+		delete file;
 	}
 	
-	delete file;
-	return nullptr;
+	return out;
 }
 
 bool FileManager::loadZix(const Common::Path &name) {


Commit: 879dad1aadef1b21ce26823beb87292cf2e6f00e
    https://github.com/scummvm/scummvm/commit/879dad1aadef1b21ce26823beb87292cf2e6f00e
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Improve debug messaging in RLFDecoder

Changed paths:
    engines/zvision/video/rlf_decoder.cpp


diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index 7e380ad6168..458c8dc3e39 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -35,15 +35,18 @@ RLFDecoder::~RLFDecoder() {
 }
 
 bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
+	debugC(5, kDebugVideo, "loadStream()");
 	close();
-
+	bool isValid = false;
 	// Check if the stream is valid
 	if (stream && !stream->err() && stream->readUint32BE() == MKTAG('F', 'E', 'L', 'R')) {
 		addTrack(new RLFVideoTrack(stream));
-		return true;
+		isValid = true;
 	} else {
-		return false;
+		warning("Invalid rlf stream");
 	}
+	debugC(5, kDebugVideo, "~loadStream()");	
+	return isValid;
 }
 
 RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)


Commit: 3be4d17e11d256c220c94ec8c9163bfa68e2674a
    https://github.com/scummvm/scummvm/commit/3be4d17e11d256c220c94ec8c9163bfa68e2674a
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: convert makeRawZorkStream() & loadAnimation() to make use of FileManager.open()

New bug to fix: Patched Nemesis options menu no longer loads subtitle control.

Changed paths:
    engines/zvision/sound/zork_raw.cpp
    engines/zvision/video/video.cpp
    engines/zvision/zvision.cpp


diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index e2685db69a8..10666f75302 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -30,6 +30,7 @@
 #include "common/tokenizer.h"
 #include "common/util.h"
 #include "zvision/zvision.h"
+#include "zvision/file/file_manager.h"
 #include "zvision/sound/zork_raw.h"
 
 namespace ZVision {
@@ -241,30 +242,9 @@ Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stre
 }
 
 Audio::RewindableAudioStream *makeRawZorkStream(const Common::Path &filePath, ZVision *engine) {
-	Common::File *file = new Common::File();
-	bool found = file->open(filePath);
 	Common::String baseName = filePath.baseName();
-	bool isRaw = baseName.hasSuffix(".raw");
-
-	if ((!found && isRaw) || (found && isRaw && file->size() < 10)) {
-		if (found)
-			file->close();
-
-		// Check for an audio patch (.src)
-		Common::String patchName = baseName;
-		patchName.setChar('s', baseName.size() - 3);
-		patchName.setChar('r', baseName.size() - 2);
-		patchName.setChar('c', baseName.size() - 1);
-
-		if (!file->open(filePath.getParent().appendComponent(patchName))) {
-			warning("Audio file %s AND audio patch %s not found", baseName.c_str(), patchName.c_str());
-			return NULL;
-			}
-	} else if (!found && !isRaw) {
-		warning("Audio file %s not found", baseName.c_str());
-		return NULL;
-	}
-
+	Common::File *file = engine->getFileManager()->open(filePath);
+	
 	const SoundParams *soundParams = NULL;
 
 	if (engine->getGameId() == GID_NEMESIS) {
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 5f12bc0c6af..8b3610cfb03 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -30,6 +30,7 @@
 #endif
 #include "zvision/zvision.h"
 #include "zvision/core/clock.h"
+#include "zvision/file/file_manager.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/scripting/script_manager.h"
 #include "zvision/sound/volume_manager.h"
@@ -40,6 +41,7 @@
 namespace ZVision {
 
 Video::VideoDecoder *ZVision::loadAnimation(const Common::Path &fileName) {
+	debugC(5, kDebugVideo, "loadAnimation()");
 	Common::String tmpFileName = fileName.baseName();
 	tmpFileName.toLowercase();
 	Video::VideoDecoder *animation = NULL;
@@ -59,15 +61,15 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::Path &fileName) {
 	else
 		error("Unknown suffix for animation %s", fileName.toString().c_str());
 
-	Common::File *_file = new Common::File();	//TODO - verify that this is safely deleted when done with
-	_file->open(fileName);
-	if (!_file)
+	Common::File *file = getFileManager()->open(fileName);
+	if (!file)
 		error("Error opening %s", fileName.toString().c_str());
 
-	bool loaded = animation->loadStream(_file);
+	bool loaded = animation->loadStream(file);
 	if (!loaded)
 		error("Error loading animation %s", fileName.toString().c_str());
 
+	debugC(5, kDebugVideo, "~loadAnimation()");
 	return animation;
 }
 
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index 54ce44b2a57..cb024a8b293 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -395,7 +395,7 @@ void ZVision::initializePath(const Common::FSNode &gamePath) {
 	SearchMan.setIgnoreClashes(true);
 	SearchMan.addDirectory(gamePath, 0, 5, true);
 	SearchMan.addSubDirectoryMatching(gameDataDir, "FONTS");
-	SearchMan.addSubDirectoryMatching(gameDataDir, "addon");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "addon");	// TODO - load zfs files found here and make sure they take priority over all others.
 	
 	if (ConfMan.hasKey("extrapath")) {
 		Common::Path gameExtraPath = ConfMan.getPath("extrapath");


Commit: abf8175311112c9ea09cebb75bcd54b2a44210d6
    https://github.com/scummvm/scummvm/commit/abf8175311112c9ea09cebb75bcd54b2a44210d6
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Fix bug from previous commit; .zfs files in addon load correctly now.

Changed paths:
    engines/zvision/zvision.cpp


diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
index cb024a8b293..4ef3deb9a64 100644
--- a/engines/zvision/zvision.cpp
+++ b/engines/zvision/zvision.cpp
@@ -39,6 +39,7 @@
 #include "zvision/core/console.h"
 #include "zvision/file/file_manager.h"
 #include "zvision/file/save_manager.h"
+#include "zvision/file/zfs_archive.h"
 #include "zvision/graphics/render_manager.h"
 #include "zvision/graphics/cursors/cursor_manager.h"
 #include "zvision/scripting/menu.h"
@@ -395,8 +396,8 @@ void ZVision::initializePath(const Common::FSNode &gamePath) {
 	SearchMan.setIgnoreClashes(true);
 	SearchMan.addDirectory(gamePath, 0, 5, true);
 	SearchMan.addSubDirectoryMatching(gameDataDir, "FONTS");
-	SearchMan.addSubDirectoryMatching(gameDataDir, "addon");	// TODO - load zfs files found here and make sure they take priority over all others.
 	
+	//Ensure extras take first search priority 
 	if (ConfMan.hasKey("extrapath")) {
 		Common::Path gameExtraPath = ConfMan.getPath("extrapath");
 		const Common::FSNode gameExtraDir(gameExtraPath);
@@ -405,6 +406,16 @@ void ZVision::initializePath(const Common::FSNode &gamePath) {
 		SearchMan.addSubDirectoryMatching(gameExtraDir, "auxscr");
 	}
 	
+	// Ensure addons (game patches) take search priority over files listed in .zix files
+	SearchMan.addSubDirectoryMatching(gameDataDir, "addon");
+	Common::ArchiveMemberList listAddon;
+	SearchMan.listMatchingMembers(listAddon,"*.zfs");
+	for (auto member : listAddon) {
+		Common::Path path(member->getPathInArchive());
+		ZfsArchive *archive = new ZfsArchive(path);
+		SearchMan.add(path.toString(), archive);
+	}
+	
 	switch (getGameId()) {
 	case GID_GRANDINQUISITOR:
 		if (!_fileManager->loadZix("INQUIS.ZIX"))


Commit: 15574c613bc708a087471b5db79522f606b573c9
    https://github.com/scummvm/scummvm/commit/15574c613bc708a087471b5db79522f606b573c9
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Fix bug in video playback causing audio channels not to be freed upon video completion.

Changed paths:
    engines/zvision/video/video.cpp


diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 8b3610cfb03..55cfddab559 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -181,7 +181,9 @@ void ZVision::playVideo(Video::VideoDecoder &vid, Common::Rect dstRect, bool ski
 
 		_system->delayMillis(vid.getTimeToNextFrame() / 2); // Exponentially decaying delay
 	}
-
+	
+	vid.close();	//Ensure resources are freed.
+	
 	_cutscenesKeymap->setEnabled(false);
 	_gameKeymap->setEnabled(true);
 


Commit: a3066eccf567ebadf67a42e86a26d50693f2661c
    https://github.com/scummvm/scummvm/commit/a3066eccf567ebadf67a42e86a26d50693f2661c
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Add missing header inclusion.

Changed paths:
    engines/zvision/scripting/effects/music_effect.cpp


diff --git a/engines/zvision/scripting/effects/music_effect.cpp b/engines/zvision/scripting/effects/music_effect.cpp
index dd179358954..251a3b9a441 100644
--- a/engines/zvision/scripting/effects/music_effect.cpp
+++ b/engines/zvision/scripting/effects/music_effect.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "audio/decoders/wave.h"
+#include "common/debug.h"
 #include "common/file.h"
 #include "common/scummsys.h"
 #include "common/stream.h"


Commit: 6f9992addced4b095f00446d164981b725373dff
    https://github.com/scummvm/scummvm/commit/6f9992addced4b095f00446d164981b725373dff
Author: Thomas N McEwan (46427621+tnm23 at users.noreply.github.com)
Date: 2025-07-24T19:12:49+01:00

Commit Message:
ZVISION: Code formatting compliance.

Changed paths:
    engines/zvision/video/video.cpp


diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 55cfddab559..08c945960f8 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -182,7 +182,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, Common::Rect dstRect, bool ski
 		_system->delayMillis(vid.getTimeToNextFrame() / 2); // Exponentially decaying delay
 	}
 	
-	vid.close();	//Ensure resources are freed.
+	vid.close();	// Ensure resources are freed.
 	
 	_cutscenesKeymap->setEnabled(false);
 	_gameKeymap->setEnabled(true);




More information about the Scummvm-git-logs mailing list