[Scummvm-cvs-logs] SF.net SVN: scummvm: [32446] tools/trunk
lordhoto at users.sourceforge.net
lordhoto at users.sourceforge.net
Sun Jun 1 01:06:53 CEST 2008
Revision: 32446
http://scummvm.svn.sourceforge.net/scummvm/?rev=32446&view=rev
Author: lordhoto
Date: 2008-05-31 16:06:53 -0700 (Sat, 31 May 2008)
Log Message:
-----------
Added support for HoF floppy installer files in extract_kyra.
Modified Paths:
--------------
tools/trunk/Makefile
tools/trunk/README
tools/trunk/extract_kyra.cpp
tools/trunk/kyra_pak.cpp
tools/trunk/kyra_pak.h
Added Paths:
-----------
tools/trunk/extract_kyra.h
tools/trunk/kyra_ins.cpp
tools/trunk/kyra_ins.h
Modified: tools/trunk/Makefile
===================================================================
--- tools/trunk/Makefile 2008-05-31 22:54:09 UTC (rev 32445)
+++ tools/trunk/Makefile 2008-05-31 23:06:53 UTC (rev 32446)
@@ -149,7 +149,7 @@
extract_agos$(EXEEXT): extract_agos.o
$(CXX) $(LDFLAGS) -o $@ $+
-extract_kyra$(EXEEXT): extract_kyra.o kyra_pak.o util.o
+extract_kyra$(EXEEXT): extract_kyra.o kyra_pak.o kyra_ins.o util.o
$(CXX) $(LDFLAGS) -o $@ $+
extract_loom_tg16$(EXEEXT): extract_loom_tg16.o util.o
Modified: tools/trunk/README
===================================================================
--- tools/trunk/README 2008-05-31 22:54:09 UTC (rev 32445)
+++ tools/trunk/README 2008-05-31 23:06:53 UTC (rev 32446)
@@ -16,6 +16,11 @@
extract_kyra
Unpacks .PAK files from Kyrandia games.
+ It is also able to extract the installer package files from
+ Hand of Fate DOS floppy version. You should be sure you got
+ all WESTWOOD.### files for that, since they are one big package
+ file splitted into several, so with -x you will extract *all*
+ files from the installer files.
Example of usage:
extract_kyra [params] <file>
Modified: tools/trunk/extract_kyra.cpp
===================================================================
--- tools/trunk/extract_kyra.cpp 2008-05-31 22:54:09 UTC (rev 32445)
+++ tools/trunk/extract_kyra.cpp 2008-05-31 23:06:53 UTC (rev 32446)
@@ -1,6 +1,6 @@
/* extract_kyra - Extractor for Kyrandia .pak archives
* Copyright (C) 2004 Johannes Schickel
- * Copyright (C) 2004-2006 The ScummVM Team
+ * Copyright (C) 2004-2008 The ScummVM Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,27 +22,27 @@
*/
#include "kyra_pak.h"
+#include "kyra_ins.h"
-void showhelp(char* exename)
-{
- printf("\nUsage: %s [params] <file>\n", exename);
+void showhelp(char *exename) {
+ printf("\nUsage: %s [params] <file>\n", exename);
- printf("\nParams:\n");
- printf("-o <filename> Extract only <filename>\n");
- printf("-x Extract all files\n");
- printf("-a Extract files from the Amiga .PAK files\n");
+ printf("\nParams:\n");
+ printf( "-o <filename> Extract only <filename>\n"
+ "-x Extract all files\n"
+ "-a Extract files from the Amiga .PAK files\n"
+ "-2 Extract files from HoF installer files\n");
- exit(2);
+ exit(2);
}
int main(int argc, char **argv) {
char inputPath[768];
- if (argc < 2) {
+ if (argc < 2)
showhelp(argv[0]);
- }
- bool extractAll = false, extractOne = false, isAmiga = false;
+ bool extractAll = false, extractOne = false, isAmiga = false, isHoFInstaller = false;
char singleFilename[256] = "";
int param;
@@ -63,29 +63,39 @@
extractAll = true;
} else if (strcmp(argv[param], "-a") == 0) {
isAmiga = true;
+ } else if (strcmp(argv[param], "-2") == 0) {
+ isHoFInstaller = true;
}
}
- if (param > argc) {
+ if (param > argc)
showhelp(argv[0]);
- }
- PAKFile myfile;
- if (!myfile.loadFile(argv[argc - 1], isAmiga)) {
- error("Couldn't load file '%s'", argv[argc - 1]);
+ Extractor *extract = 0;
+ if (isHoFInstaller) {
+ extract = new HoFInstaller(argv[argc - 1]);
+ } else {
+ PAKFile *myfile = new PAKFile;
+ if (!myfile->loadFile(argv[argc - 1], isAmiga)) {
+ delete myfile;
+ error("Couldn't load file '%s'", argv[argc - 1]);
+ }
+
+ extract = myfile;
}
getPath(argc[argv - 1], inputPath);
- if(extractAll) {
- myfile.outputAllFiles(inputPath);
- } else if(extractOne) {
+ if (extractAll) {
+ extract->outputAllFiles(inputPath);
+ } else if (extractOne) {
char outputFilename[1024];
- sprintf(outputFilename, "%s/%s", inputPath, singleFilename);
- myfile.outputFileAs(singleFilename, outputFilename);
+ snprintf(outputFilename, 1024, "%s/%s", inputPath, singleFilename);
+ extract->outputFileAs(singleFilename, outputFilename);
} else {
- myfile.drawFileList();
+ extract->drawFileList();
}
return 0;
}
+
Added: tools/trunk/extract_kyra.h
===================================================================
--- tools/trunk/extract_kyra.h (rev 0)
+++ tools/trunk/extract_kyra.h 2008-05-31 23:06:53 UTC (rev 32446)
@@ -0,0 +1,92 @@
+/* Scumm Tools
+ * Copyright (C) 2007 The ScummVM project
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef EXTRACT_KYRA_H
+#define EXTRACT_KYRA_H
+
+#include "util.h"
+
+class Extractor {
+public:
+ virtual ~Extractor() {}
+
+ virtual void drawFileList();
+
+ virtual bool outputAllFiles() { return outputAllFiles("./"); }
+ virtual bool outputAllFiles(const char *outputPath);
+
+ virtual bool outputFile(const char *file) { return outputFileAs(file, file); }
+ virtual bool outputFileAs(const char *file, const char *outputName);
+
+ struct FileList {
+ FileList() : filename(0), size(0), data(0), next(0) {}
+ ~FileList() {
+ delete[] filename;
+ delete[] data;
+ delete next;
+ }
+
+ FileList *findEntry(const char *f) {
+ for (FileList *cur = this; cur; cur = cur->next) {
+ if (scumm_stricmp(cur->filename, f) != 0)
+ continue;
+ return cur;
+ }
+ return 0;
+ }
+
+ const FileList *findEntry(const char *f) const {
+ for (const FileList *cur = this; cur; cur = cur->next) {
+ if (scumm_stricmp(cur->filename, f) != 0)
+ continue;
+ return cur;
+ }
+ return 0;
+ }
+
+ void addEntry(FileList *e) {
+ if (next)
+ next->addEntry(e);
+ else
+ next = e;
+ }
+ uint32 getTableSize() const {
+ return strlen(filename)+1+4+((next != 0) ? next->getTableSize() : 0);
+ }
+ uint32 getFileSize() const {
+ return size + (next != 0 ? next->getFileSize() : 0);
+ }
+
+ char *filename;
+ uint32 size;
+ uint8 *data;
+
+ FileList *next;
+ };
+
+ typedef const FileList cFileList;
+
+ virtual cFileList *getFileList() const = 0;
+};
+
+#endif
+
Property changes on: tools/trunk/extract_kyra.h
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Added: tools/trunk/kyra_ins.cpp
===================================================================
--- tools/trunk/kyra_ins.cpp (rev 0)
+++ tools/trunk/kyra_ins.cpp 2008-05-31 23:06:53 UTC (rev 32446)
@@ -0,0 +1,677 @@
+/* Scumm Tools
+ * Copyright (C) 2008 The ScummVM project
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra_ins.h"
+
+class FileExpanderSource {
+public:
+ FileExpanderSource(const uint8 *data) : _dataPtr(data), _bitsLeft(8), _key(0), _index(0) {}
+ ~FileExpanderSource() {}
+
+ void advSrcRefresh();
+ void advSrcBitsBy1();
+ void advSrcBitsByIndex(uint8 newIndex);
+
+ uint8 getKeyLower() { return _key & 0xff; }
+ void setIndex(uint8 index) { _index = index; }
+ uint16 getKeyMasked(uint8 newIndex);
+ uint16 keyMaskedAlign(uint16 val);
+
+ void copyBytes(uint8 *& dst);
+
+private:
+ const uint8 *_dataPtr;
+ uint16 _key;
+ int8 _bitsLeft;
+ uint8 _index;
+};
+
+void FileExpanderSource::advSrcBitsBy1() {
+ _key >>= 1;
+ if (!--_bitsLeft) {
+ _key = ((*_dataPtr++) << 8 ) | (_key & 0xff);
+ _bitsLeft = 8;
+ }
+}
+
+void FileExpanderSource::advSrcBitsByIndex(uint8 newIndex) {
+ _index = newIndex;
+ _bitsLeft -= _index;
+ if (_bitsLeft <= 0) {
+ _key >>= (_index + _bitsLeft);
+ _index = -_bitsLeft;
+ _bitsLeft = 8 - _index;
+ _key = (*_dataPtr++ << 8) | (_key & 0xff);
+ }
+ _key >>= _index;
+}
+
+uint16 FileExpanderSource::getKeyMasked(uint8 newIndex) {
+ static const uint8 mskTable[] = { 0x0F, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
+ _index = newIndex;
+ uint16 res = 0;
+
+ if (_index > 8) {
+ newIndex = _index - 8;
+ res = (_key & 0xff) & mskTable[8];
+ advSrcBitsByIndex(8);
+ _index = newIndex;
+ res |= (((_key & 0xff) & mskTable[_index]) << 8);
+ advSrcBitsByIndex(_index);
+ } else {
+ res = (_key & 0xff) & mskTable[_index];
+ advSrcBitsByIndex(_index);
+ }
+
+ return res;
+}
+
+void FileExpanderSource::copyBytes(uint8 *& dst) {
+ advSrcBitsByIndex(_bitsLeft);
+ uint16 r = (READ_LE_UINT16(_dataPtr) ^ _key) + 1;
+ _dataPtr += 2;
+
+ if (r)
+ error("decompression failure");
+
+ memcpy(dst, _dataPtr, _key);
+ _dataPtr += _key;
+ dst += _key;
+}
+
+uint16 FileExpanderSource::keyMaskedAlign(uint16 val) {
+ val -= 0x101;
+ _index = (val & 0xff) >> 2;
+ int16 b = ((_bitsLeft << 8) | _index) - 1;
+ _bitsLeft = b >> 8;
+ _index = b & 0xff;
+ return (((val & 3) + 4) << _index) + 0x101 + getKeyMasked(_index);
+}
+
+void FileExpanderSource::advSrcRefresh() {
+ _key = READ_LE_UINT16(_dataPtr);
+ _dataPtr += 2;
+ _bitsLeft = 8;
+}
+
+class FileExpander {
+public:
+ FileExpander();
+ ~FileExpander();
+
+ bool process(uint8 *dst, const uint8 *src, uint32 outsize, uint32 insize);
+
+private:
+ void generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex2, int cnt);
+ uint8 calcCmdAndIndex(const uint8 *tbl, int16 ¶);
+
+ FileExpanderSource *_src;
+ uint8 *_tables[9];
+ uint16 *_tables16[3];
+};
+
+FileExpander::FileExpander() : _src(0) {
+ _tables[0] = new uint8[3914];
+ assert(_tables[0]);
+
+ _tables[1] = _tables[0] + 320;
+ _tables[2] = _tables[0] + 352;
+ _tables[3] = _tables[0] + 864;
+ _tables[4] = _tables[0] + 2016;
+ _tables[5] = _tables[0] + 2528;
+ _tables[6] = _tables[0] + 2656;
+ _tables[7] = _tables[0] + 2736;
+ _tables[8] = _tables[0] + 2756;
+
+ _tables16[0] = (uint16 *)(_tables[0] + 3268);
+ _tables16[1] = (uint16 *)(_tables[0] + 3302);
+ _tables16[2] = (uint16 *)(_tables[0] + 3338);
+}
+
+FileExpander::~FileExpander() {
+ delete _src;
+ delete[] _tables[0];
+}
+
+bool FileExpander::process(uint8 *dst, const uint8 *src, uint32 outsize, uint32 compressedSize) {
+ static const uint8 indexTable[] = {
+ 0x10, 0x11, 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, 0x0A,
+ 0x05, 0x0B, 0x04, 0x0C, 0x03, 0x0D, 0x02, 0x0E, 0x01, 0x0F
+ };
+
+ memset(_tables[0], 0, 3914);
+
+ uint8 *d = dst;
+ uint16 tableSize0 = 0;
+ uint16 tableSize1 = 0;
+ bool needrefresh = true;
+ bool postprocess = false;
+
+ _src = new FileExpanderSource(src);
+
+ while (d < dst + outsize) {
+
+ if (needrefresh) {
+ needrefresh = false;
+ _src->advSrcRefresh();
+ }
+
+ _src->advSrcBitsBy1();
+
+ int mode = _src->getKeyMasked(2) - 1;
+ if (mode == 1) {
+ tableSize0 = _src->getKeyMasked(5) + 257;
+ tableSize1 = _src->getKeyMasked(5) + 1;
+ memset(_tables[7], 0, 19);
+
+ const uint8 *itbl = indexTable;
+ int numbytes = _src->getKeyMasked(4) + 4;
+
+ while (numbytes--)
+ _tables[7][*itbl++] = _src->getKeyMasked(3);
+
+ generateTables(7, 8, 255, 19);
+
+ int cnt = tableSize0 + tableSize1;
+ uint8 *tmp = _tables[0];
+
+ while (cnt) {
+ uint16 cmd = _src->getKeyLower();
+ cmd = READ_LE_UINT16(&_tables[8][cmd << 1]);
+ _src->advSrcBitsByIndex(_tables[7][cmd]);
+
+ if (cmd < 16) {
+ *tmp++ = cmd;
+ cnt--;
+ } else {
+ uint8 tmpI = 0;
+ if (cmd == 16) {
+ cmd = _src->getKeyMasked(2) + 3;
+ tmpI = *(tmp - 1);
+ } else if (cmd == 17) {
+ cmd = _src->getKeyMasked(3) + 3;
+ } else {
+ cmd = _src->getKeyMasked(7) + 11;
+ }
+ _src->setIndex(tmpI);
+ memset(tmp, tmpI, cmd);
+ tmp += cmd;
+
+ cnt -= cmd;
+ if (cnt < 0)
+ error("decompression failure");
+ }
+ }
+
+ memcpy(_tables[1], _tables[0] + tableSize0, tableSize1);
+ generateTables(0, 2, 3, tableSize0);
+ generateTables(1, 4, 5, tableSize1);
+ postprocess = true;
+ } else if (mode < 0) {
+ _src->copyBytes(d);
+ postprocess = false;
+ needrefresh = true;
+ } else if (mode == 0){
+ uint8 *d2 = _tables[0];
+ memset(d2, 8, 144);
+ memset(d2 + 144, 9, 112);
+ memset(d2 + 256, 7, 24);
+ memset(d2 + 280, 8, 8);
+ d2 = _tables[1];
+ memset(d2, 5, 32);
+ tableSize0 = 288;
+ tableSize1 = 32;
+
+ generateTables(0, 2, 3, tableSize0);
+ generateTables(1, 4, 5, tableSize1);
+ postprocess = true;
+ } else {
+ error("decompression failure");
+ }
+
+ if (!postprocess)
+ continue;
+
+ int16 cmd = 0;
+
+ do {
+ cmd = ((int16*) _tables[2])[_src->getKeyLower()];
+ _src->advSrcBitsByIndex(cmd < 0 ? calcCmdAndIndex(_tables[3], cmd) : _tables[0][cmd]);
+
+ if (cmd == 0x11d) {
+ cmd = 0x200;
+ } else if (cmd > 0x108) {
+ cmd = _src->keyMaskedAlign(cmd);
+ }
+
+ if (!(cmd >> 8)) {
+ *d++ = cmd & 0xff;
+ } else if (cmd != 0x100) {
+ cmd -= 0xfe;
+ int16 offset = ((int16*) _tables[4])[_src->getKeyLower()];
+ _src->advSrcBitsByIndex(offset < 0 ? calcCmdAndIndex(_tables[5], offset) : _tables[1][offset]);
+ if ((offset & 0xff) >= 4) {
+ uint8 newIndex = ((offset & 0xff) >> 1) - 1;
+ offset = (((offset & 1) + 2) << newIndex) + _src->getKeyMasked(newIndex);
+ }
+
+ uint8 *s2 = d - 1 - offset;
+ if (s2 >= dst) {
+ while (cmd--)
+ *d++ = *s2++;
+ } else {
+ uint32 pos = dst - s2;
+ s2 += (d - dst);
+
+ if (pos < (uint32) cmd) {
+ cmd -= pos;
+ while (pos--)
+ *d++ = *s2++;
+ s2 = dst;
+ }
+ while (cmd--)
+ *d++ = *s2++;
+ }
+ }
+ } while (cmd != 0x100);
+ }
+
+ delete _src;
+ _src = 0;
+
+ return true;
+}
+
+void FileExpander::generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex2, int cnt) {
+ const uint8 *tbl1 = _tables[srcIndex];
+ const uint8 *tbl2 = _tables[dstIndex];
+ const uint8 *tbl3 = dstIndex2 == 0xff ? 0 : _tables[dstIndex2];
+
+ if (!cnt)
+ return;
+
+ const uint8 *s = tbl1;
+ memset(_tables16[0], 0, 32);
+
+ for (int i = 0; i < cnt; i++)
+ _tables16[0][(*s++)]++;
+
+ _tables16[1][1] = 0;
+
+ for (uint16 i = 1, r = 0; i < 16; i++) {
+ r = (r + _tables16[0][i]) << 1;
+ _tables16[1][i + 1] = r;
+ }
+
+ if (_tables16[1][16]) {
+ uint16 r = 0;
+ for (uint16 i = 1; i < 16; i++)
+ r += _tables16[0][i];
+ if (r > 1)
+ error("decompression failure");
+ }
+
+ s = tbl1;
+ uint16 *d = _tables16[2];
+ for (int i = 0; i < cnt; i++) {
+ uint16 t = *s++;
+ if (t) {
+ _tables16[1][t]++;
+ t = _tables16[1][t] - 1;
+ }
+ *d++ = t;
+ }
+
+ s = tbl1;
+ d = _tables16[2];
+ for (int i = 0; i < cnt; i++) {
+ int8 t = ((int8)(*s++)) - 1;
+ if (t > 0) {
+ uint16 v1 = *d;
+ uint16 v2 = 0;
+
+ do {
+ v2 = (v2 << 1) | (v1 & 1);
+ v1 >>= 1;
+ } while (--t && v1);
+
+ t++;
+ uint8 c1 = (v1 & 1);
+ while (t--) {
+ uint8 c2 = v2 >> 15;
+ v2 = (v2 << 1) | c1;
+ c1 = c2;
+ };
+
+ *d++ = v2;
+ } else {
+ d++;
+ }
+ }
+
+ memset((void*) tbl2, 0, 512);
+
+ cnt--;
+ s = tbl1 + cnt;
+ d = &_tables16[2][cnt];
+ uint16 * bt = (uint16*) tbl3;
+ uint16 inc = 0;
+ uint16 cnt2 = 0;
+
+ do {
+ uint8 t = *s--;
+ uint16 *s2 = (uint16*) tbl2;
+
+ if (t && t < 9) {
+ inc = 1 << t;
+ uint16 o = *d;
+
+ do {
+ s2[o] = cnt;
+ o += inc;
+ } while (!(o & 0xf00));
+
+ } else if (t > 8) {
+ if (!bt)
+ error("decompression failure");
+
+ t -= 8;
+ uint8 shiftCnt = 1;
+ uint8 v = (*d) >> 8;
+ s2 = &((uint16*) tbl2)[*d & 0xff];
+
+ do {
+ if (!*s2) {
+ *s2 = (uint16)(~cnt2);
+ *(uint32*)&bt[cnt2] = 0;
+ cnt2 += 2;
+ }
+
+ s2 = &bt[(uint16)(~*s2)];
+ if (v & shiftCnt)
+ s2++;
+
+ shiftCnt <<= 1;
+ } while (--t);
+ *s2 = cnt;
+ }
+ d--;
+ } while (--cnt >= 0);
+}
+
+uint8 FileExpander::calcCmdAndIndex(const uint8 *tbl, int16 ¶) {
+ const uint16 *t = (const uint16*)tbl;
+ _src->advSrcBitsByIndex(8);
+ uint8 newIndex = 0;
+ uint16 v = _src->getKeyLower();
+
+ do {
+ newIndex++;
+ para = t[((~para) & 0xfffe) | (v & 1)];
+ v >>= 1;
+ } while (para < 0);
+
+ return newIndex;
+}
+
+template<class T>
+T MIN(T l, T r) {
+ return (l < r) ? l : r;
+}
+
+HoFInstaller::HoFInstaller(const char *baseFilename) : _list(0) {
+ strncpy(_baseFilename, baseFilename, sizeof(_baseFilename));
+ char *str = strstr(_baseFilename, ".");
+ if (str) {
+ if ((uint)((str - _baseFilename) + 1) < strlen(_baseFilename))
+ str[1] = 0;
+ } else {
+ error("filename too long '%s'", baseFilename);
+ }
+
+ uint32 pos = 0;
+ uint32 bytesleft = 0;
+ bool startFile = true;
+
+ _list = new Archive;
+ memset(_list, 0, sizeof(Archive));
+ Archive *newArchive = _list;
+
+ for (int8 currentFile = 1; currentFile; currentFile++) {
+ char filename[64];
+ snprintf(filename, 64, "%s%03d", _baseFilename, currentFile);
+
+ FILE *file = NULL;
+ if ((file = fopen(filename, "rb")) == NULL)
+ break;
+
+ fseek(file, pos, SEEK_SET);
+ uint8 fileId = readByte(file);
+ pos++;
+
+ uint32 size = fileSize(file) - 1;
+ if (startFile) {
+ size -= 4;
+ if (fileId == currentFile) {
+ size -= 6;
+ pos += 6;
+ fseek(file, 6, SEEK_CUR);
+ } else {
+ size = size + 1 - pos;
+ }
+
+ strcpy(newArchive->filename, _baseFilename);
+ bytesleft = newArchive->totalSize = readUint32LE(file);
+ pos += 4;
+ newArchive->firstFile = currentFile;
+ newArchive->startOffset = pos;
+ startFile = false;
+ }
+
+ uint32 cs = MIN(size, bytesleft);
+ bytesleft -= cs;
+
+ fclose(file);
+
+ pos += cs;
+ if (cs == size) {
+ if (!bytesleft) {
+ newArchive->lastFile = currentFile;
+ newArchive->endOffset = --pos;
+
+ newArchive->next = new Archive;
+ newArchive = newArchive->next;
+ memset(newArchive, 0, sizeof(Archive));
+ currentFile = -1;
+ } else {
+ pos = 0;
+ }
+ } else {
+ startFile = true;
+ bytesleft = size - cs;
+ newArchive->lastFile = currentFile--;
+ newArchive->endOffset = --pos;
+
+ newArchive->next = new Archive;
+ newArchive = newArchive->next;
+ memset(newArchive, 0, sizeof(Archive));
+ }
+ }
+
+ FileExpander exp;
+ uint32 insize = 0;
+ uint32 outsize = 0;
+ uint8 *inbuffer = 0;
+ uint8 *outbuffer = 0;
+ uint32 inPart1 = 0;
+ uint32 inPart2 = 0;
+ char entryStr[64];
+
+ pos = 0;
+
+ const uint32 kExecSize = 0x0bba;
+ const uint32 kHeaderSize = 30;
+ const uint32 kHeaderSize2 = 46;
+
+ for (Archive *a = _list; a != 0 && a->filename[0]; a = a->next) {
+ startFile = true;
+ for (uint32 i = a->firstFile; i != (a->lastFile + 1); i++) {
+ char filename[64];
+ snprintf(filename, 64, "%s%03d", _baseFilename, i);
+
+ FILE *file = NULL;
+ if ((file = fopen(filename, "rb")) == NULL) {
+ error("[2] Couldn't open file '%s'", filename);
+ break;
+ }
+
+ uint32 size = (i == a->lastFile) ? a->endOffset : fileSize(file);
+
+ if (startFile) {
+ startFile = false;
+ pos = a->startOffset + kExecSize;
+ if (pos > size) {
+ pos -= size;
+ fclose(file);
+ continue;
+ }
+ } else {
+ if (inPart2) {
+ fseek(file, 1, SEEK_SET);
+ fread(inbuffer + inPart1, 1, inPart2, file);
+ inPart2 = 0;
+ exp.process(outbuffer, inbuffer, outsize, insize);
+ delete[] inbuffer;
+ inbuffer = 0;
+
+ FileList *newEntry = new FileList;
+ assert(newEntry);
+ newEntry->filename = new char[strlen(entryStr)+1];
+ assert(newEntry->filename);
+ strncpy(newEntry->filename, entryStr, strlen(entryStr)+1);
+ newEntry->size = outsize;
+ newEntry->data = outbuffer;
+
+ if (_files)
+ _files->addEntry(newEntry);
+ else
+ _files = newEntry;
+ }
+ pos++;
+ }
+
+ while (pos < size) {
+ uint8 hdr[43];
+ uint32 m = 0;
+ fseek(file, pos, SEEK_SET);
+
+ if (pos + 42 > size) {
+ m = size - pos;
+ uint32 b = 42 - m;
+
+ if (m >= 4) {
+ uint32 id = readUint32LE(file);
+ if (id == 0x06054B50) {
+ startFile = true;
+ break;
+ } else {
+ fseek(file, pos, SEEK_SET);
+ }
+ }
+
+ snprintf(filename, 64, "%s.%03d", _baseFilename, i+1);
+
+ FILE *file2 = fopen(filename, "rb");
+ if (file2 == NULL)
+ error("Couldn't open file '%s'", filename);
+
+ fread(hdr, 1, m, file);
+ fread(hdr + m , 1, b, file2);
+ fclose(file2);
+ } else {
+ fread(hdr, 1, 42, file);
+ }
+
+ uint32 id = READ_LE_UINT32(hdr);
+
+ if (id == 0x04034B50) {
+ if (hdr[8] != 8)
+ error("compression type not implemented");
+ insize = READ_LE_UINT32(hdr + 18);
+ outsize = READ_LE_UINT32(hdr + 22);
+
+ uint16 filestrlen = READ_LE_UINT16(hdr + 26);
+ *(hdr + 30 + filestrlen) = 0;
+ strcpy(entryStr, (const char *)(hdr + 30));
+ pos += (kHeaderSize + filestrlen - m);
+ fseek(file, pos, SEEK_SET);
+
+ outbuffer = new uint8[outsize];
+ assert(outbuffer);
+
+ if (!inbuffer) {
+ inbuffer = new uint8[insize];
+ assert(inbuffer);
+ }
+
+ if ((pos + insize) > size) {
+ // this is for files that are split between two archive files
+ inPart1 = size - pos;
+ inPart2 = insize - inPart1;
+ fread(inbuffer, 1, inPart1, file);
+ } else {
+ fread(inbuffer, 1, insize, file);
+ inPart2 = 0;
+ exp.process(outbuffer, inbuffer, outsize, insize);
+ delete[] inbuffer;
+ inbuffer = 0;
+
+ FileList *newEntry = new FileList;
+ assert(newEntry);
+ newEntry->filename = new char[strlen(entryStr)+1];
+ assert(newEntry->filename);
+ strncpy(newEntry->filename, entryStr, strlen(entryStr)+1);
+ newEntry->size = outsize;
+ newEntry->data = outbuffer;
+
+ if (_files)
+ _files->addEntry(newEntry);
+ else
+ _files = newEntry;
+ }
+
+ pos += insize;
+ if (pos > size) {
+ pos -= size;
+ break;
+ }
+ } else {
+ uint32 filestrlen = READ_LE_UINT32(hdr + 28);
+ pos += (kHeaderSize2 + filestrlen - m);
+ }
+ }
+
+ fclose(file);
+ }
+ }
+}
+
Property changes on: tools/trunk/kyra_ins.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Added: tools/trunk/kyra_ins.h
===================================================================
--- tools/trunk/kyra_ins.h (rev 0)
+++ tools/trunk/kyra_ins.h 2008-05-31 23:06:53 UTC (rev 32446)
@@ -0,0 +1,57 @@
+/* Scumm Tools
+ * Copyright (C) 2008 The ScummVM project
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef KYRA_INS_H
+#define KYRA_INS_H
+
+#include "extract_kyra.h"
+#include "util.h"
+
+class HoFInstaller : public Extractor {
+public:
+ HoFInstaller(const char *baseFilename);
+ ~HoFInstaller() { delete _list; delete _files; }
+
+ cFileList *getFileList() const { return _files; }
+private:
+ char _baseFilename[1024];
+
+ struct Archive {
+ Archive() : next(0) {}
+ ~Archive() { delete next; next = 0; }
+
+ char filename[1024];
+ uint32 firstFile;
+ uint32 startOffset;
+ uint32 lastFile;
+ uint32 endOffset;
+ uint32 totalSize;
+
+ Archive *next;
+ };
+
+ Archive *_list;
+ FileList *_files;
+};
+
+#endif
+
Property changes on: tools/trunk/kyra_ins.h
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Date Rev Author URL Id
Name: svn:eol-style
+ native
Modified: tools/trunk/kyra_pak.cpp
===================================================================
--- tools/trunk/kyra_pak.cpp 2008-05-31 22:54:09 UTC (rev 32445)
+++ tools/trunk/kyra_pak.cpp 2008-05-31 23:06:53 UTC (rev 32446)
@@ -78,7 +78,7 @@
startoffset = endoffset;
}
- delete [] buffer;
+ delete[] buffer;
return true;
}
@@ -118,83 +118,6 @@
return true;
}
-void PAKFile::drawFileList() {
- FileList *cur = _fileList;
- while (cur) {
- printf("Filename: '%s' size: %d\n", cur->filename, cur->size);
- cur = cur->next;
- }
-}
-
-bool PAKFile::outputAllFiles() {
- FileList *cur = _fileList;
- while (cur) {
- FILE *file = fopen(cur->filename, "wb");
- if (!file) {
- error("couldn't open file '%s' for writing", cur->filename);
- return false;
- }
- printf("Exracting file '%s'...", cur->filename);
- if (fwrite(cur->data, 1, cur->size, file) == cur->size) {
- printf("OK\n");
- } else {
- printf("FAILED\n");
- return false;
- }
- fclose(file);
- cur = cur->next;
- }
- return true;
-}
-
-bool PAKFile::outputAllFiles(char* outputPath) {
- FileList *cur = _fileList;
- char outputFilename[1024];
-
- while (cur) {
- sprintf(outputFilename, "%s/%s", outputPath, cur->filename);
- FILE *file = fopen(outputFilename, "wb");
- if (!file) {
- error("couldn't open file '%s' for writing", outputFilename);
- return false;
- }
- printf("Exracting file '%s'...", cur->filename);
- if (fwrite(cur->data, 1, cur->size, file) == cur->size) {
- printf("OK\n");
- } else {
- printf("FAILED\n");
- return false;
- }
- fclose(file);
- cur = cur->next;
- }
- return true;
-}
-
-bool PAKFile::outputFileAs(const char *f, const char *fn) {
- FileList *cur = (_fileList != 0) ? _fileList->findEntry(f) : 0;
-
- if (!cur) {
- error("file '%s' not found");
- return false;
- }
-
- FILE *file = fopen(fn, "wb");
- if (!file) {
- error("couldn't open file '%s' in write mode", fn);
- return false;
- }
- printf("Exracting file '%s' to file '%s'...", cur->filename, fn);
- if (fwrite(cur->data, 1, cur->size, file) == cur->size) {
- printf("OK\n");
- } else {
- printf("FAILED\n");
- return false;
- }
- fclose(file);
- return true;
-}
-
const uint8 *PAKFile::getFileData(const char *file, uint32 *size) {
FileList *cur = (_fileList != 0) ? _fileList->findEntry(file) : 0;
@@ -243,11 +166,10 @@
newEntry->size = size;
newEntry->data = data;
- if (_fileList) {
+ if (_fileList)
_fileList->addEntry(newEntry);
- } else {
+ else
_fileList = newEntry;
- }
return true;
}
@@ -266,3 +188,63 @@
}
return false;
}
+
+//HACK: move this to another file
+
+void Extractor::drawFileList() {
+ cFileList *cur = getFileList();
+ while (cur) {
+ printf("Filename: '%s' size: %d\n", cur->filename, cur->size);
+ cur = cur->next;
+ }
+}
+
+bool Extractor::outputAllFiles(const char *outputPath) {
+ cFileList *cur = getFileList();
+ char outputFilename[1024];
+
+ while (cur) {
+ sprintf(outputFilename, "%s/%s", outputPath, cur->filename);
+ FILE *file = fopen(outputFilename, "wb");
+ if (!file) {
+ error("couldn't open file '%s' for writing", outputFilename);
+ return false;
+ }
+ printf("Exracting file '%s'...", cur->filename);
+ if (fwrite(cur->data, 1, cur->size, file) == cur->size) {
+ printf("OK\n");
+ } else {
+ printf("FAILED\n");
+ return false;
+ }
+ fclose(file);
+ cur = cur->next;
+ }
+ return true;
+}
+
+bool Extractor::outputFileAs(const char *f, const char *fn) {
+ cFileList *cur = getFileList();
+ cur = (cur != 0) ? cur->findEntry(f) : 0;
+
+ if (!cur) {
+ error("file '%s' not found");
+ return false;
+ }
+
+ FILE *file = fopen(fn, "wb");
+ if (!file) {
+ error("couldn't open file '%s' in write mode", fn);
+ return false;
+ }
+ printf("Exracting file '%s' to file '%s'...", cur->filename, fn);
+ if (fwrite(cur->data, 1, cur->size, file) == cur->size) {
+ printf("OK\n");
+ } else {
+ printf("FAILED\n");
+ return false;
+ }
+ fclose(file);
+ return true;
+}
+
Modified: tools/trunk/kyra_pak.h
===================================================================
--- tools/trunk/kyra_pak.h 2008-05-31 22:54:09 UTC (rev 32445)
+++ tools/trunk/kyra_pak.h 2008-05-31 23:06:53 UTC (rev 32446)
@@ -23,9 +23,10 @@
#ifndef KYRA_PAK_H
#define KYRA_PAK_H
+#include "extract_kyra.h"
#include "util.h"
-class PAKFile {
+class PAKFile : public Extractor {
public:
PAKFile() : _fileList(0), _isAmiga(false) {}
~PAKFile() { delete _fileList; }
@@ -36,68 +37,13 @@
const uint32 getFileSize() const { return _fileList->getTableSize()+5+4+_fileList->getFileSize(); }
- void drawFileList();
-
- bool outputAllFiles();
- bool outputAllFiles(char* outputPath);
-
- bool outputFile(const char *file) { return outputFileAs(file, file); }
- bool outputFileAs(const char *file, const char *outputName);
const uint8 *getFileData(const char *file, uint32 *size);
bool addFile(const char *name, const char *file);
bool addFile(const char *name, uint8 *data, uint32 size);
bool removeFile(const char *name);
-public:
- struct FileList {
- FileList() : filename(0), size(0), data(0), next(0) {}
- ~FileList() {
- delete [] filename;
- delete [] data;
- delete next;
- }
- FileList *findEntry(const char *f) {
- for (FileList *cur = this; cur; cur = cur->next) {
- if (scumm_stricmp(cur->filename, f) != 0)
- continue;
- return cur;
- }
- return 0;
- }
-
- const FileList *findEntry(const char *f) const {
- for (const FileList *cur = this; cur; cur = cur->next) {
- if (scumm_stricmp(cur->filename, f) != 0)
- continue;
- return cur;
- }
- return 0;
- }
-
- void addEntry(FileList *e) {
- if (next)
- next->addEntry(e);
- else
- next = e;
- }
- uint32 getTableSize() const {
- return strlen(filename)+1+4+((next != 0) ? next->getTableSize() : 0);
- }
- uint32 getFileSize() const {
- return size + (next != 0 ? next->getFileSize() : 0);
- }
-
- char *filename;
- uint32 size;
- uint8 *data;
-
- FileList *next;
- };
-
- typedef const FileList cFileList;
-
cFileList *getFileList() const { return _fileList; }
private:
FileList *_fileList;
@@ -105,3 +51,4 @@
};
#endif
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list