[Scummvm-git-logs] scummvm-tools master -> ade48f5069899721b0ce3428988522a55ac35dbf
alxpnv
a04198622 at gmail.com
Thu Oct 14 12:44:23 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm-tools' repo located at https://github.com/scummvm/scummvm-tools .
Summary:
ade48f5069 TOOLS: add a tool to extract Sanitarium resource packs
Commit: ade48f5069899721b0ce3428988522a55ac35dbf
https://github.com/scummvm/scummvm-tools/commit/ade48f5069899721b0ce3428988522a55ac35dbf
Author: alxpnv (alxpnv22 at yahoo.com)
Date: 2021-10-14T15:45:30+03:00
Commit Message:
TOOLS: add a tool to extract Sanitarium resource packs
Changed paths:
A engines/asylum/extract_asylum.cpp
A engines/asylum/extract_asylum.h
Makefile.common
NEWS
README
tools.cpp
diff --git a/Makefile.common b/Makefile.common
index baf26b81d..b50f1afc4 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -212,6 +212,7 @@ tools_OBJS := \
engines/touche/compress_touche.o \
engines/tucker/compress_tucker.o \
engines/agos/extract_agos.o \
+ engines/asylum/extract_asylum.o \
engines/cge/extract_cge.o \
engines/cge/pack_cge.o \
engines/cine/extract_cine.o \
diff --git a/NEWS b/NEWS
index 354da174b..aba83d774 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
For a more comprehensive changelog of the latest experimental code, see:
https://github.com/scummvm/scummvm-tools/commits/
+2.6.0 (XXXX-XX-XX)
+ - Added a tool to extract Sanitarium resource packs.
+
2.5.0 (2021-10-09)
- Added tool for exctracting NGI's .nl archives
- Improve handling of input for tools that expect a directory as input.
diff --git a/README b/README
index bc5a28a5e..0d232bc08 100644
--- a/README
+++ b/README
@@ -52,6 +52,14 @@ Extraction Tools:
Example of usage:
./scummvm-tools-cli --tool extract_agos <infile 1> ... <infile n>
+ extract_asylum
+ Extracts Sanitarium resource packs.
+
+ If resourceindex is provided, only that resource is extracted.
+
+ Example of usage:
+ ./scummvm-tools-cli --tool extract_asylum [-o outputdir] [-R resourceindex] <inputfile>
+
extract_cge
Unpacks Soltys and Sfinx game data files.
diff --git a/engines/asylum/extract_asylum.cpp b/engines/asylum/extract_asylum.cpp
new file mode 100644
index 000000000..02ab86425
--- /dev/null
+++ b/engines/asylum/extract_asylum.cpp
@@ -0,0 +1,150 @@
+/* ScummVM Tools
+ *
+ * ScummVM Tools 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/file.h"
+#include "common/str.h"
+
+#include "extract_asylum.h"
+
+// based on scummvm/engines/asylum/respack.cpp
+
+#define MAKE_RESOURCE(pack, index) (ResourceId)((((pack) << 16) + 0x80000000) + (unsigned int)(index))
+
+ExtractAsylum::ExtractAsylum(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
+ ToolInput input;
+ input.format = "*.*";
+ _inputPaths.push_back(input);
+
+ _outputToDirectory = true;
+
+ _shorthelp = "Used to extract Sanitarium resource packs.";
+ _helptext = "\nUsage: " + getName() + " [-o /path/to/output/dir/] [-R <resourceindex>] <resourcepack>\n";
+
+ _supportsProgressBar = true;
+
+ _packId = 0;
+ _resInd = -1;
+}
+
+InspectionMatch ExtractAsylum::inspectInput(const Common::Filename &filename) {
+ std::string file = filename.getFullName();
+ if (!strncmp(file.c_str(), "RES.", 4) || !strncmp(file.c_str(), "MUS.", 4))
+ return IMATCH_PERFECT;
+
+ return IMATCH_AWFUL;
+}
+
+void ExtractAsylum::parseExtraArguments() {
+ if (!_arguments.empty()) {
+ if (_arguments.front() == "-R") {
+ _arguments.pop_front();
+ _resInd = atoi(_arguments.front().c_str());
+ _arguments.pop_front();
+ }
+ }
+}
+
+void ExtractAsylum::execute() {
+ initPack(_inputPaths[0].path);
+
+ if (_resInd >= 0) {
+ dumpResource(_resInd);
+ } else {
+ for (int i = 0; i < _resources.size(); i++) {
+ dumpResource(i);
+ updateProgress(i, _resources.size());
+ }
+ }
+}
+
+void ExtractAsylum::initPack(const Common::Filename &filename) {
+ _packFile.open(filename, "rb");
+ if (!_packFile.isOpen())
+ error("[ExtractAsylum::initPack] Could not open resource file: %s", filename.getFullName().c_str());
+
+ _packId = atoi(strchr(filename.getFullName().c_str(), '.') + 1);
+
+ uint32 entryCount = _packFile.readUint32LE();
+ _resources.resize(entryCount);
+
+ uint32 prevOffset = _packFile.readUint32LE();
+ uint32 nextOffset = 0;
+
+ for (uint32 i = 0; i < entryCount; i++) {
+ ResourceEntry entry;
+ entry.offset = prevOffset;
+
+ // Read the offset of the next entry to determine the size of this one
+ nextOffset = (i < entryCount - 1) ? _packFile.readUint32LE() : (uint32)_packFile.size();
+ entry.size = (nextOffset > 0) ? nextOffset - prevOffset : (uint32)_packFile.size() - prevOffset;
+ entry.data = NULL;
+
+ _resources[i] = entry;
+
+ prevOffset = nextOffset;
+ }
+}
+
+void ExtractAsylum::dumpResource(int resInd) {
+ struct ResourceEntry *entry = &_resources[resInd];
+ ResourceId resourceId = MAKE_RESOURCE(_packId, resInd);
+
+ if (!entry->offset)
+ return;
+
+ entry->data = new byte[entry->size];
+ if (entry->data == NULL) {
+ warning("[ExtractAsylum::dumpResource] Could not allocate memory for resource 0x%X", resourceId);
+ return;
+ }
+
+ _packFile.seek(entry->offset, SEEK_SET);
+ _packFile.read_noThrow(entry->data, entry->size);
+
+ const char *extension;
+ if (!strncmp((char *)entry->data, "RIFF", 4)) {
+ extension = "WAV";
+ } else if (!strncmp((char *)entry->data, "D3GR", 4)) {
+ if (entry->size == 800)
+ extension = "PAL";
+ else
+ extension = "D3GR";
+ } else if (*(entry->data + entry->size - 1) == '\0') {
+ extension = "TXT";
+ } else {
+ extension = "BIN";
+ }
+
+ Common::File fout;
+ _outputPath.setFullName(Common::String::format("%X.%s", resourceId, extension).c_str());
+ fout.open(_outputPath, "wb");
+ fout.write(entry->data, entry->size);
+ fout.close();
+
+ delete[] entry->data;
+}
+
+#ifdef STANDALONE_MAIN
+int main(int argc, char *argv[]) {
+ ExtractAsylum asylum(argv[0]);
+ return asylum.run(argc, argv);
+}
+#endif
diff --git a/engines/asylum/extract_asylum.h b/engines/asylum/extract_asylum.h
new file mode 100644
index 000000000..7feb333b2
--- /dev/null
+++ b/engines/asylum/extract_asylum.h
@@ -0,0 +1,55 @@
+/* ScummVM Tools
+ *
+ * ScummVM Tools 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef EXTRACT_ASYLUM_H
+#define EXTRACT_ASYLUM_H
+
+#include "tool.h"
+
+#include "common/array.h"
+#include "common/file.h"
+
+typedef int ResourceId;
+
+struct ResourceEntry {
+ uint8 *data;
+ uint32 size;
+ uint32 offset;
+};
+
+class ExtractAsylum : public Tool {
+public:
+ ExtractAsylum(const std::string &name = "extract_asylum");
+ virtual InspectionMatch inspectInput(const Common::Filename &filename);
+ virtual void parseExtraArguments();
+ virtual void execute();
+
+protected:
+ uint _packId;
+ int _resInd;
+ Common::File _packFile;
+ Common::Array<ResourceEntry> _resources;
+
+ void initPack(const Common::Filename &filename);
+ void dumpResource(int resInd);
+};
+
+#endif // EXTRACT_ASYLUM_H
diff --git a/tools.cpp b/tools.cpp
index bd3793888..54debe9d5 100644
--- a/tools.cpp
+++ b/tools.cpp
@@ -25,6 +25,7 @@
#include "tool.h"
#include "engines/agos/compress_agos.h"
+#include "engines/asylum/extract_asylum.h"
#include "engines/gob/compress_gob.h"
#include "engines/kyra/compress_kyra.h"
#include "engines/queen/compress_queen.h"
@@ -91,6 +92,7 @@ Tools::Tools() {
#endif
_tools.push_back(new ExtractAgos());
+ _tools.push_back(new ExtractAsylum());
_tools.push_back(new PackBladeRunner());
_tools.push_back(new ExtractCge());
_tools.push_back(new PackCge());
More information about the Scummvm-git-logs
mailing list