1 /* ScummVM Tools
2  *
3  * ScummVM Tools is the legal property of its developers, whose
4  * names are too numerous to list here. Please refer to the
5  * COPYRIGHT file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "extract_cryo.h"
26 
27 
ExtractCryo(const std::string & name)28 ExtractCryo::ExtractCryo(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
29 	ToolInput input;
30 	input.format = "*.*";
31 	_inputPaths.push_back(input);
32 
33 	_outputToDirectory = true;
34 
35 	_shorthelp = "Used to extract Lost Eden archive files.";
36 	_helptext = "\nUsage: " + getName() + " [-o /path/to/output/dir/] <inputfile>\n";
37 }
38 
execute()39 void ExtractCryo::execute() {
40 	Common::Filename filename = _inputPaths[0].path;
41 
42 	if (!openDAT(filename))
43 		error("Unable to open %s", filename.getFullName().c_str());
44 
45 	Common::File fOut;
46 	for (DATIterator it = _dir.begin(); it != _dir.end(); ++it) {
47 		byte *buffer = (byte *)malloc((*it)->size);
48 		_datFile.seek((*it)->offset, SEEK_SET);
49 		_datFile.read_noThrow(buffer, (*it)->size);
50 
51 		_outputPath.setFullName((*it)->filename);
52 		print("... %s", (*it)->filename);
53 
54 		fOut.open(_outputPath, "wb");
55 		fOut.write(buffer, (*it)->size);
56 		fOut.close();
57 
58 		free(buffer);
59 	}
60 
61 	_datFile.close();
62 }
63 
inspectInput(const Common::Filename & filename)64 InspectionMatch ExtractCryo::inspectInput(const Common::Filename &filename) {
65 	// TODO: DUNE.DAT
66 	std::string file = filename.getFullName();
67 	if (
68 		scumm_stricmp(file.c_str(), "EDEN.DAT") == 0
69 	)
70 		return IMATCH_PERFECT;
71 	return IMATCH_AWFUL;
72 }
73 
openDAT(Common::Filename & filename)74 bool ExtractCryo::openDAT(Common::Filename &filename) {
75 	_datFile.open(filename, "rb");
76 	if (!_datFile.isOpen()) {
77 		error("FileMan::openDAT(): Error reading the DAT file %s", filename.getFullName().c_str());
78 		return false;
79 	}
80 
81 	uint16 entries = _datFile.readUint16LE();
82 
83 	for (uint16 fileIndex = 0; fileIndex < entries; fileIndex++) {
84 		DATEntry *dirEntry = new DATEntry();
85 
86 		for (int i = 0; i < 16; i++) {
87 			dirEntry->filename[i] = _datFile.readByte();
88 		}
89 
90 		dirEntry->size = _datFile.readUint32LE();
91 		dirEntry->offset = _datFile.readUint32LE();
92 		dirEntry->flag = _datFile.readByte();
93 
94 		if (dirEntry->offset != 0 || dirEntry->size != 0) {
95 			_dir.push_back(dirEntry);
96 		}
97 	}
98 
99 	return true;
100 }
101 
102 #ifdef STANDALONE_MAIN
main(int argc,char * argv[])103 int main(int argc, char *argv[]) {
104 	ExtractCryo cryo(argv[0]);
105 	return cryo.run(argc, argv);
106 }
107 #endif
108