[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