[Scummvm-git-logs] scummvm master -> dd176885214f6ab525b56c9911c51a8c58c1bc12
dreammaster
paulfgilbert at gmail.com
Sun Mar 15 00:28:06 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
dd17688521 ULTIMA: Support running games using uncompressed .dat files
Commit: dd176885214f6ab525b56c9911c51a8c58c1bc12
https://github.com/scummvm/scummvm/commit/dd176885214f6ab525b56c9911c51a8c58c1bc12
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-03-14T17:27:20-07:00
Commit Message:
ULTIMA: Support running games using uncompressed .dat files
To make it easier to continous changes to the contents of the
ultima.dat file in the future, this development allows the
Extra Path to be set to the devtools/create_ultima folder, and
it will use the files in the files/ subfolder in preference to
the ultima.dat archive
Changed paths:
engines/ultima/shared/engine/data_archive.cpp
engines/ultima/shared/engine/data_archive.h
engines/ultima/shared/engine/ultima.cpp
engines/ultima/shared/engine/ultima.h
engines/ultima/ultima8/filesys/file_system.cpp
diff --git a/engines/ultima/shared/engine/data_archive.cpp b/engines/ultima/shared/engine/data_archive.cpp
index 78c1a7807d..5966431a70 100644
--- a/engines/ultima/shared/engine/data_archive.cpp
+++ b/engines/ultima/shared/engine/data_archive.cpp
@@ -21,6 +21,7 @@
*/
#include "ultima/shared/engine/data_archive.h"
+#include "common/config-manager.h"
#include "common/file.h"
#include "common/translation.h"
#include "common/unzip.h"
@@ -54,18 +55,32 @@ public:
}
};
+/*-------------------------------------------------------------------*/
-UltimaDataArchive *UltimaDataArchive::load(const Common::String &subfolder,
+bool UltimaDataArchive::load(const Common::String &subfolder,
int reqMajorVersion, int reqMinorVersion, Common::String &errorMsg) {
Common::Archive *dataArchive = nullptr;
Common::File f;
- if (!Common::File::exists(DATA_FILENAME) ||
- (dataArchive = Common::makeZipArchive(DATA_FILENAME)) == 0 ||
- !f.open(Common::String::format("%s/version.txt", subfolder.c_str()), *dataArchive)) {
- delete dataArchive;
- errorMsg = Common::String::format(_("Could not locate engine data %s"), DATA_FILENAME);
- return nullptr;
+#ifndef RELEASE_BUILD
+ Common::FSNode folder;
+ if (ConfMan.hasKey("extrapath")) {
+ if ((folder = Common::FSNode(ConfMan.get("extrapath"))).exists()
+ && (folder = folder.getChild("files")).exists()
+ && (folder = folder.getChild(subfolder)).exists()) {
+ f.open(folder.getChild("version.txt"));
+ }
+ }
+
+#endif
+ if (!f.isOpen()) {
+ if (!Common::File::exists(DATA_FILENAME) ||
+ (dataArchive = Common::makeZipArchive(DATA_FILENAME)) == 0 ||
+ !f.open(Common::String::format("%s/version.txt", subfolder.c_str()), *dataArchive)) {
+ delete dataArchive;
+ errorMsg = Common::String::format(_("Could not locate engine data %s"), DATA_FILENAME);
+ return false;
+ }
}
// Validate the version
@@ -83,13 +98,24 @@ UltimaDataArchive *UltimaDataArchive::load(const Common::String &subfolder,
delete dataArchive;
errorMsg = Common::String::format(_("Out of date engine data. Expected %d.%d, but got version %d.%d"),
reqMajorVersion, reqMinorVersion, major, minor);
- return nullptr;
+ return false;
}
// It was all validated correctly
- return new UltimaDataArchive(dataArchive, subfolder);
+ Common::Archive *archive;
+#ifndef RELEASE_BUILD
+ if (!dataArchive)
+ archive = new UltimaDataArchiveProxy(folder);
+ else
+#endif
+ archive = new UltimaDataArchive(dataArchive, subfolder);
+
+ SearchMan.add("data", archive);
+ return true;
}
+/*-------------------------------------------------------------------*/
+
bool UltimaDataArchive::hasFile(const Common::String &name) const {
if (!name.hasPrefixIgnoreCase(_publicFolder))
return false;
@@ -149,5 +175,44 @@ Common::SeekableReadStream *UltimaDataArchive::createReadStreamForMember(const C
return nullptr;
}
+/*-------------------------------------------------------------------*/
+
+#ifndef RELEASE_BUILD
+
+const Common::ArchiveMemberPtr UltimaDataArchiveProxy::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *UltimaDataArchiveProxy::createReadStreamForMember(const Common::String &name) const {
+ if (hasFile(name))
+ return getNode(name).createReadStream();
+
+ return nullptr;
+}
+
+Common::FSNode UltimaDataArchiveProxy::getNode(const Common::String &name) const {
+ Common::String remainingName = name.substr(_publicFolder.size());
+ Common::FSNode node = _folder;
+ size_t pos;
+
+ while ((pos = remainingName.findFirstOf('/')) != Common::String::npos) {
+ node = node.getChild(remainingName.substr(0, pos));
+ if (!node.exists())
+ return node;
+
+ remainingName = remainingName.substr(pos + 1);
+ }
+
+ if (!remainingName.empty())
+ node = node.getChild(remainingName);
+
+ return node;
+}
+
+#endif
+
} // End of namespace Shared
} // End of namespace Ultima
diff --git a/engines/ultima/shared/engine/data_archive.h b/engines/ultima/shared/engine/data_archive.h
index b6bfb2da0c..03eeeaf78c 100644
--- a/engines/ultima/shared/engine/data_archive.h
+++ b/engines/ultima/shared/engine/data_archive.h
@@ -24,6 +24,7 @@
#define ULTIMA_SHARED_ENGINE_DATA_ARCHIVE_H
#include "common/archive.h"
+#include "common/fs.h"
#include "common/str.h"
namespace Ultima {
@@ -52,10 +53,14 @@ private:
public:
/**
* Creates a data archive wrapper for the ultima.dat datafile.
- * If the required data is found, it returns the new archive.
+ * Firstly, for debugging purposes, if a "files" folder exists on any path that
+ * has the given subfolder, it will be used first. This will allow for setting
+ * the ScummVM Extra Path to the create_ultima folder, and it will give preference
+ * the files there. Otherwise, it checks for the presence of ultima.dat, and
+ * if the required data is found, it returns the new archive.
* Otherwise, returns an error message in the errorMsg field
*/
- static UltimaDataArchive *load(const Common::String &subfolder,
+ static bool load(const Common::String &subfolder,
int reqMajorVersion, int reqMinorVersion, Common::String &errorMsg);
public:
~UltimaDataArchive() override {
@@ -101,6 +106,78 @@ public:
const Common::String &name) const override;
};
+#ifndef RELEASE_BUILD
+
+/**
+ * The data archive proxy class is used for debugging purposes to access engine data
+ * files when the create_ultima folder is in the search path. It will allow for
+ * local mucking around with the data files and committing changes without having to
+ * recreate the ultima.dat file every time a change is made. ultima.dat then just has
+ * to be recreated prior to a release or when the changes are completed and stable
+ */
+class UltimaDataArchiveProxy : public Common::Archive {
+ friend class UltimaDataArchive;
+private:
+ Common::FSNode _folder;
+ const Common::String _publicFolder;
+
+ UltimaDataArchiveProxy(const Common::FSNode &folder) : _folder(folder), _publicFolder("data/") {}
+
+ /**
+ * Gets a file node from the passed filename
+ */
+ Common::FSNode getNode(const Common::String &name) const;
+public:
+ ~UltimaDataArchiveProxy() override {
+ }
+
+ /**
+ * Check if a member with the given name is present in the Archive.
+ * Patterns are not allowed, as this is meant to be a quick File::exists()
+ * replacement.
+ */
+ bool hasFile(const Common::String &name) const override {
+ return name.hasPrefixIgnoreCase(_publicFolder) && getNode(name).exists();
+ }
+
+ /**
+ * Add all members of the Archive matching the specified pattern to list.
+ * Must only append to list, and not remove elements from it.
+ *
+ * @return the number of members added to list
+ */
+ int listMatchingMembers(Common::ArchiveMemberList &list,
+ const Common::String &pattern) const override {
+ return 0;
+ }
+
+ /**
+ * Add all members of the Archive to list.
+ * Must only append to list, and not remove elements from it.
+ *
+ * @return the number of names added to list
+ */
+ int listMembers(Common::ArchiveMemberList &list) const override {
+ return 0;
+ }
+
+ /**
+ * Returns a ArchiveMember representation of the given file.
+ */
+ const Common::ArchiveMemberPtr getMember(const Common::String &name)
+ const override;
+
+ /**
+ * Create a stream bound to a member with the specified name in the
+ * archive. If no member with this name exists, 0 is returned.
+ * @return the newly created input stream
+ */
+ Common::SeekableReadStream *createReadStreamForMember(
+ const Common::String &name) const override;
+};
+
+#endif
+
} // End of namespace Shared
} // End of namespace Ultima
diff --git a/engines/ultima/shared/engine/ultima.cpp b/engines/ultima/shared/engine/ultima.cpp
index 1f7281d4b8..e81365b434 100644
--- a/engines/ultima/shared/engine/ultima.cpp
+++ b/engines/ultima/shared/engine/ultima.cpp
@@ -58,16 +58,14 @@ bool UltimaEngine::initialize() {
if (!isDataRequired(folder, reqMajorVersion, reqMinorVersion))
return true;
- // Try and open the data archive
+ // Try and set up the data archive
Common::String errorMsg;
- _dataArchive = UltimaDataArchive::load(folder, reqMajorVersion, reqMinorVersion, errorMsg);
- if (_dataArchive) {
- SearchMan.add("data", _dataArchive);
- return true;
- } else {
+ if (!UltimaDataArchive::load(folder, reqMajorVersion, reqMinorVersion, errorMsg)) {
GUIError(errorMsg);
return false;
}
+
+ return true;
}
void UltimaEngine::GUIError(const Common::String &msg) {
diff --git a/engines/ultima/shared/engine/ultima.h b/engines/ultima/shared/engine/ultima.h
index 1b21b631c7..59298c4b9a 100644
--- a/engines/ultima/shared/engine/ultima.h
+++ b/engines/ultima/shared/engine/ultima.h
@@ -113,13 +113,6 @@ public:
return min + _randomSource.getRandomNumber(max - min);
}
- /**
- * Get a reference to the data archive
- */
- Common::Archive *getDataArchive() const {
- return _dataArchive;
- }
-
/**
* Returns a file system node for the game directory
*/
diff --git a/engines/ultima/ultima8/filesys/file_system.cpp b/engines/ultima/ultima8/filesys/file_system.cpp
index abc7d102ef..dacda8188c 100644
--- a/engines/ultima/ultima8/filesys/file_system.cpp
+++ b/engines/ultima/ultima8/filesys/file_system.cpp
@@ -86,8 +86,7 @@ bool FileSystem::rawOpen(Common::SeekableReadStream *&in, const string &fname) {
if (name.hasPrefix("@data/")) {
// It's a file specifically from the ultima.dat file
f = new Common::File();
- if (f->open(Common::String::format("data/%s", name.substr(6).c_str()),
- *Ultima8Engine::get_instance()->getDataArchive())) {
+ if (f->open(Common::String::format("data/%s", name.substr(6).c_str()))) {
in = f;
return true;
}
More information about the Scummvm-git-logs
mailing list