[Scummvm-git-logs] scummvm-tools master -> 2317d8fdc062ad55b0e7f7f4d758162e342b8c00
sev-
sev at scummvm.org
Tue Sep 10 11:17:50 CEST 2019
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:
2317d8fdc0 TOOLS: Added HDB extraction tool
Commit: 2317d8fdc062ad55b0e7f7f4d758162e342b8c00
https://github.com/scummvm/scummvm-tools/commit/2317d8fdc062ad55b0e7f7f4d758162e342b8c00
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2019-08-13T00:07:21+02:00
Commit Message:
TOOLS: Added HDB extraction tool
Changed paths:
A engines/hdb/extract_hdb.cpp
A engines/hdb/extract_hdb.h
Makefile.common
README
tools.cpp
diff --git a/Makefile.common b/Makefile.common
index 08a95c4..e782d4c 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -172,6 +172,7 @@ tools_OBJS := \
engines/bladerunner/pack_bladerunner.o \
engines/gob/compress_gob.o \
engines/gob/extract_fascination_cd.o \
+ engines/hdb/extract_hdb.o \
engines/kyra/compress_kyra.o \
engines/queen/compress_queen.o \
engines/saga/compress_saga.o \
diff --git a/README b/README
index ab47190..84b0cc5 100644
--- a/README
+++ b/README
@@ -92,6 +92,12 @@ Extraction Tools:
Example of usage:
./scummvm-tools-cli --tool extract_gob_stk [-o outputdir] <infile>
+ extract_hdb
+ Extracts Hyperspace Delivery Boy! archives.
+
+ Example of usage:
+ ./scummvm-tools-cli --tool extract_hdb [-o outputdir] <hyperspace.msd>
+
extract_kyra
Unpacks .PAK files from Kyrandia games.
diff --git a/engines/hdb/extract_hdb.cpp b/engines/hdb/extract_hdb.cpp
new file mode 100644
index 0000000..ec2ce0b
--- /dev/null
+++ b/engines/hdb/extract_hdb.cpp
@@ -0,0 +1,168 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "extract_hdb.h"
+#include <zlib.h>
+
+
+ExtractHDB::ExtractHDB(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
+ ToolInput input;
+ input.format = "*.*";
+ _inputPaths.push_back(input);
+
+ _outputToDirectory = true;
+
+ _shorthelp = "Used to extract Hyperspace Delivery Boy! archive files.";
+ _helptext = "\nUsage: " + getName() + " [-o /path/to/output/dir/] <inputfile>\n";
+
+ _compressed = false;
+}
+
+void ExtractHDB::execute() {
+ Common::Filename filename = _inputPaths[0].path;
+
+ if (!openMPC(filename))
+ error("Unable to open %s", filename.getFullName().c_str());
+
+ Common::File fOut;
+ for (Common::Array<MPCEntry *>::iterator it = _dir.begin(); it != _dir.end(); it++) {
+ byte *buffer = (byte *)malloc((*it)->length);
+
+ _mpcFile.seek((*it)->offset, SEEK_SET);
+
+ _mpcFile.read_noThrow(buffer, (*it)->length);
+
+ _outputPath.setFullName((*it)->filename);
+
+ fOut.open(_outputPath, "wb");
+
+ if (_compressed) {
+ byte *buffer2 = (byte *)calloc((*it)->ulength, 1);
+ unsigned long len = (*it)->ulength;
+
+ print("... decompressing %s", (*it)->filename);
+
+ if (uncompress(buffer2, &len, buffer, (*it)->length) != Z_OK) {
+ print("Error uncompressing file %s", (*it)->filename);
+
+ fOut.write(buffer, (*it)->length);
+ } else if (len != (*it)->ulength) {
+ print("Size mismatch for %s: %d <> %d", (*it)->filename, len, (*it)->ulength);
+
+ fOut.write(buffer, (*it)->length);
+ } else {
+ fOut.write(buffer2, (*it)->ulength);
+ }
+
+ free(buffer2);
+ } else {
+ print("... %s", (*it)->filename);
+ fOut.write(buffer, (*it)->length);
+ }
+
+ fOut.close();
+
+ free(buffer);
+ }
+
+ _mpcFile.close();
+}
+
+InspectionMatch ExtractHDB::inspectInput(const Common::Filename &filename) {
+ // Accept either 'vol.cat' or 'vol.dat'
+ std::string file = filename.getFullName();
+ if (
+ scumm_stricmp(file.c_str(), "hyperspace.mpc") == 0 ||
+ scumm_stricmp(file.c_str(), "hyperspace.msd") == 0 ||
+ scumm_stricmp(file.c_str(), "hyperdemo.mpc") == 0 ||
+ scumm_stricmp(file.c_str(), "hyperdemo.msd") == 0
+ )
+ return IMATCH_PERFECT;
+ return IMATCH_AWFUL;
+}
+
+bool ExtractHDB::openMPC(Common::Filename &filename) {
+ uint32 offset;
+
+ _mpcFile.open(filename, "rb");
+ if (!_mpcFile.isOpen()) {
+ error("FileMan::openMPC(): Error reading the MSD/MPC file %s", filename.getFullName().c_str());
+ return false;
+ }
+
+ _dataHeader.id = _mpcFile.readUint32BE();
+
+ if (_dataHeader.id == 'MPCC') {
+ print("COMPRESSED MPC FILE");
+ return false;
+ } else if (_dataHeader.id == 'MPCU') {
+ print("Unpacking uncompressed MPC file...");
+ // we're fine
+ } else if (_dataHeader.id == 'MSDC') {
+ print("Unpacking compressed MSD file...");
+ _compressed = true;
+ // we're fine
+ } else if (_dataHeader.id == 'MSDU') {
+ print("UNCOMPRESSED MSD FILE");
+ return false;
+ } else {
+ error("Invalid MPC/MSD File.");
+ return false;
+ }
+
+ // read the directory
+ offset = _mpcFile.readUint32LE();
+ _mpcFile.seek((int32)offset, SEEK_SET);
+
+ // Note: The MPC archive format assumes the offset to be uint32,
+ // but Common::File::seek() takes the offset as int32.
+
+ _dataHeader.dirSize = _mpcFile.readUint32LE();
+
+ print("MPCU: Read %d entries", _dataHeader.dirSize);
+
+ for (uint32 fileIndex = 0; fileIndex < _dataHeader.dirSize; fileIndex++) {
+ MPCEntry *dirEntry = new MPCEntry();
+
+ for (int i = 0; i < 64; i++) {
+ dirEntry->filename[i] = _mpcFile.readByte();
+ }
+
+ dirEntry->offset = _mpcFile.readUint32LE();
+ dirEntry->length = _mpcFile.readUint32LE();
+ dirEntry->ulength = _mpcFile.readUint32LE();
+ dirEntry->type = (DataType)_mpcFile.readUint32LE();
+
+ _dir.push_back(dirEntry);
+ }
+
+ return true;
+}
+
+#ifdef STANDALONE_MAIN
+int main(int argc, char *argv[]) {
+ ExtractHDB hdb(argv[0]);
+ return hdb.run(argc, argv);
+}
+#endif
diff --git a/engines/hdb/extract_hdb.h b/engines/hdb/extract_hdb.h
new file mode 100644
index 0000000..8917c07
--- /dev/null
+++ b/engines/hdb/extract_hdb.h
@@ -0,0 +1,71 @@
+/* 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_HDB_H
+#define EXTRACT_HDB_H
+
+#include "tool.h"
+#include "common/array.h"
+
+enum DataType {
+ TYPE_ERROR,
+ TYPE_BINARY,
+ TYPE_TILE32,
+ TYPE_FONT,
+ TYPE_ICON32,
+ TYPE_PIC,
+
+ ENDOFTYPES
+};
+
+struct MPCEntry {
+ char filename[64]; // filename
+ int32 offset; // offset in MSD file of data
+ int32 length; // compressed length of data
+ int32 ulength; // uncompressed length
+ DataType type; // type of data
+};
+
+#define MPCIterator Common::Array<MPCEntry *>::iterator
+
+class ExtractHDB : public Tool {
+public:
+ ExtractHDB(const std::string &name = "extract_hdb");
+
+ virtual void execute();
+
+ virtual InspectionMatch inspectInput(const Common::Filename &filename);
+
+protected:
+ bool openMPC(Common::Filename &filename);
+
+ Common::File _mpcFile;
+
+ struct {
+ uint32 id;
+ uint32 dirSize;
+ } _dataHeader;
+
+ Common::Array<MPCEntry *> _dir;
+ bool _compressed;
+};
+
+#endif
diff --git a/tools.cpp b/tools.cpp
index b45cc6d..2ae1c08 100644
--- a/tools.cpp
+++ b/tools.cpp
@@ -54,6 +54,7 @@
#include "engines/cruise/extract_cruise_pc.h"
#include "engines/gob/extract_gob_stk.h"
#include "engines/gob/extract_fascination_cd.h"
+#include "engines/hdb/extract_hdb.h"
#include "engines/kyra/extract_kyra.h"
#include "engines/prince/extract_prince.h"
#include "engines/prince/pack_prince.h"
@@ -96,6 +97,7 @@ Tools::Tools() {
_tools.push_back(new ExtractCruisePC());
_tools.push_back(new ExtractGobStk());
_tools.push_back(new ExtractFascinationCD());
+ _tools.push_back(new ExtractHDB());
_tools.push_back(new ExtractKyra());
_tools.push_back(new ExtractPrince());
_tools.push_back(new PackPrince());
More information about the Scummvm-git-logs
mailing list