[Scummvm-cvs-logs] SF.net SVN: scummvm: [25254] tools/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Mon Jan 29 18:18:25 CET 2007


Revision: 25254
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25254&view=rev
Author:   lordhoto
Date:     2007-01-29 09:18:25 -0800 (Mon, 29 Jan 2007)

Log Message:
-----------
Switches to a common Kyra PAK extractor/packer for extract_kyra and compress_kyra.

Modified Paths:
--------------
    tools/trunk/Makefile
    tools/trunk/compress_kyra.cpp
    tools/trunk/extract_kyra.cpp

Added Paths:
-----------
    tools/trunk/kyra_pak.cpp
    tools/trunk/kyra_pak.h

Removed Paths:
-------------
    tools/trunk/extract_kyra.h

Modified: tools/trunk/Makefile
===================================================================
--- tools/trunk/Makefile	2007-01-29 17:04:37 UTC (rev 25253)
+++ tools/trunk/Makefile	2007-01-29 17:18:25 UTC (rev 25254)
@@ -48,7 +48,7 @@
 
 all: $(TARGETS)
 
-compress_kyra$(EXEEXT): compress_kyra.o compress.o util.o
+compress_kyra$(EXEEXT): compress_kyra.o kyra_pak.o compress.o util.o
 	$(CXX) $(LDFLAGS) -o $@ $+
 
 compress_queen$(EXEEXT): compress_queen.o util.o
@@ -93,7 +93,7 @@
 extract_agos$(EXEEXT): extract_agos.o
 	$(CC) $(LDFLAGS) -o $@ $+
 
-extract_kyra$(EXEEXT): extract_kyra.o util.o
+extract_kyra$(EXEEXT): extract_kyra.o kyra_pak.o util.o
 	$(CXX) $(LDFLAGS) -o $@ $+
 
 extract_loom_tg16$(EXEEXT): extract_loom_tg16.o util.o
@@ -136,6 +136,7 @@
 extract_mm_nes.o \
 extract_scumm_mac.o \
 extract_zak_c64.o \
+kyra_pak.o \
 util.o: util.h
 
 clean:

Modified: tools/trunk/compress_kyra.cpp
===================================================================
--- tools/trunk/compress_kyra.cpp	2007-01-29 17:04:37 UTC (rev 25253)
+++ tools/trunk/compress_kyra.cpp	2007-01-29 17:18:25 UTC (rev 25254)
@@ -21,17 +21,10 @@
  */
 
 #include "compress.h"
+#include "kyra_pak.h"
 
-struct PakFileEntry {
-	char filename[25];
-	uint8 *fileData;
-	uint32 size;
-};
-
 static void showhelp(const char *exename);
-static void process(FILE *file, const char *output);
-static void decompress(uint8 *data, uint32 size, PakFileEntry &output);
-static void processFile(const char *file, PakFileEntry &output);
+static void process(const char *infile, const char *output);
 
 #define OUTPUT_MP3 ".VO3"
 #define OUTPUT_OGG ".VOG"
@@ -39,7 +32,7 @@
 
 #define TEMPFILE "TEMP.VOC"
 
-const char *outputName = 0;
+const char *outputExt = 0;
 static CompressMode gCompMode = kMP3Mode;
 
 int main(int argc, char *argv[]) {
@@ -65,35 +58,29 @@
 
 	switch (gCompMode) {
 	case kMP3Mode:
-		outputName = OUTPUT_MP3;
+		outputExt = OUTPUT_MP3;
 		tempEncoded = TEMP_MP3;
 		if (!process_mp3_parms(argc - 1, argv, i))
 			showhelp(argv[0]);
 		break;
 	case kVorbisMode:
-		outputName = OUTPUT_OGG;
+		outputExt = OUTPUT_OGG;
 		tempEncoded = TEMP_OGG;
 		if (!process_ogg_parms(argc - 1, argv, i))
 			showhelp(argv[0]);
 		break;
 	case kFlacMode:
-		outputName = OUTPUT_FLAC;
+		outputExt = OUTPUT_FLAC;
 		tempEncoded = TEMP_FLAC;
 		if (!process_flac_parms(argc - 1, argv, i))
 			showhelp(argv[0]);
 		break;
 	}
 	
-	i = argc - 2;
-	
-	FILE *input = fopen(argv[i], "rb");
-	if (!input) {
-		printf("Cannot open file: %s\n", argv[i]);
-		exit(-1);
-	}
-	
-	process(input, argv[argc - 1]);
-	fclose(input);
+	if (scumm_stricmp(argv[argc - 2], argv[argc - 1]) == 0)
+		error("infile and outfile are the same file");
+	process(argv[argc - 2], argv[argc - 1]);
+	return 0;
 }
 
 static void showhelp(const char *exename) {
@@ -133,178 +120,54 @@
 	exit(2);
 }
 
-static void process(FILE *file, const char *output) {
-	FILE *outputFile = fopen(output, "wb");
-	if (!outputFile) {
-		printf("Cannot open file: %s\n", output);
-		exit(-1);
-	}
+static bool hasSuffix(const char *str, const char *suf) {
+	const int sufSize = strlen(suf);
+	int off = strlen(str);
+	if (off < sufSize)
+		return false;
+	off -= sufSize;
+	printf("'%s'\n", &str[off]);
+	return (scumm_stricmp(&str[off], suf) == 0);
+}
 
-	uint32 file_size = fileSize(file);
-	fseek(file, 0, SEEK_SET);
-	int filesInPak = 0;
-	readUint32LE(file);
-	while (1) {
-		++filesInPak;
-		PakFileEntry tempPak;
-		int namePos = 0;
-		while (1) {
-			tempPak.filename[namePos++] = readByte(file);
-			if (!tempPak.filename[namePos-1])
-				break;
-		}
-		uint32 temp = readUint32LE(file);
-		if (temp == file_size)
-			break;
-	}
-	if (filesInPak == 0) {
-		printf("ERROR: Empty or unknown PAK file format\n");
-		exit(-1);
-	}
-	printf("Found %d files in package\n", filesInPak);
-	
-	PakFileEntry *pakEntries = new PakFileEntry[filesInPak];
-	assert(pakEntries);
-	memset(pakEntries, 0, sizeof(PakFileEntry)*filesInPak);
-	
-	fseek(file, 0, SEEK_SET);
-	
-	uint32 startOffset = readUint32LE(file);
-	uint32 endOffset = 0;
-	int pakPos = 0;
-	while (!feof(file)) {
-		PakFileEntry tempPak;
+static void process(const char *infile, const char *outfile) {
+	PAKFile input, output;
+	if (!input.loadFile(infile, false))
+		return;
+	if (!output.loadFile(0, false))
+		return;
 		
-		int namePos = 0;
-		while (1) {
-			tempPak.filename[namePos++] = readByte(file);
-			if (!tempPak.filename[namePos-1])
-				break;
-		}		
-		endOffset = readUint32LE(file);
-		
-		if (strstr(tempPak.filename, ".VOC") == NULL) {
-			if (endOffset == file_size)
-				break;
-			startOffset = endOffset;
+	PAKFile::cFileList *list = input.getFileList();
+	char outputName[32];
+	for (; list; list = list->next) {
+		if (!hasSuffix(list->filename, ".VOC"))
 			continue;
-		}
-		
-		if (!endOffset)
-			endOffset = file_size;
-		
-		long position = ftell(file);
-		
-		fseek(file, startOffset, SEEK_SET);
-		fseek(file, 26, SEEK_CUR);
 
-		if (fgetc(file) != 1) {
-			warning("broken VOC file '%s' skipping it...", tempPak.filename);
-			startOffset = endOffset;
-			fseek(file, position, SEEK_SET);
+		if (list->data[26] != 1) {
+			warning("broken VOC file '%s' skipping it...", list->filename);
 			continue;
 		}
 
-		fseek(file, -1, SEEK_CUR);
+		input.outputFileAs(list->filename, TEMPFILE);
+		strncpy(outputName, list->filename, 32);
 		
-		uint8 *temp = new uint8[endOffset - startOffset];
-		assert(temp);
-		fread(temp, sizeof(uint8), endOffset - startOffset, file);
-
-		char *vocStart = strstr(tempPak.filename, ".VOC");
-		for (unsigned int i = 0; i < strlen(outputName); ++i) {
-			vocStart[i] = outputName[i];
-		}
-		strcpy(pakEntries[pakPos].filename, tempPak.filename);
+		FILE *tempFile = fopen(TEMPFILE, "rb");
+		extractAndEncodeVOC(TEMP_RAW, tempFile, gCompMode);
+		fclose(tempFile);
 		
-		decompress(temp, endOffset - startOffset, pakEntries[pakPos++]);
+		char *vocStart = strstr(outputName, ".VOC");
+		for (unsigned int i = 0; i < strlen(outputExt); ++i)
+			vocStart[i] = outputExt[i];
+		output.addFile(outputName, tempEncoded);
 		
-		delete [] temp;
-		temp = 0;
-		
-		fseek(file, position, SEEK_SET);
-		
-		if (endOffset == file_size)
-			break;
-		startOffset = endOffset;
+		unlink(TEMPFILE);
+		unlink(TEMP_RAW);
+		unlink(tempEncoded);
 	}
 	
-	// writes the new pack file
-	uint32 startAddr = 0x0;
-	static const char *zeroName = "\0\0\0\0\0";
-	
-	for (int i = 0; i < filesInPak; ++i) {
-		if (strcmp(pakEntries[i].filename, "") == 0)
-			continue;
-		startAddr += strlen(pakEntries[i].filename) + 1 + 4;
+	if (output.getFileList()) {
+		output.saveFile(outfile);
+	} else {
+		printf("file '%s' doesn't contain any .voc files\n", infile);
 	}
-	startAddr += 5 + 4;
-	
-	// writes the filenames
-	uint32 curAddr = startAddr;
-	for (int i = 0; i < filesInPak; ++i) {
-		if (strcmp(pakEntries[i].filename, "") == 0)
-			continue;
-		writeUint32LE(outputFile, curAddr);
-		fwrite(pakEntries[i].filename, sizeof(uint8), strlen(pakEntries[i].filename) + 1, outputFile);
-		curAddr += pakEntries[i].size;
-	}
-	
-	writeUint32LE(outputFile, curAddr);
-	fwrite(zeroName, sizeof(uint8), 5, outputFile);
-	
-	for (int i = 0; i < filesInPak; ++i) {
-		if (strcmp(pakEntries[i].filename, "") == 0)
-			continue;
-		fwrite(pakEntries[i].fileData, sizeof(uint8), pakEntries[i].size, outputFile);
-		delete [] pakEntries[i].fileData;
-		pakEntries[i].fileData = 0;
-	}
-	
-	fclose(outputFile);
-	unlink(TEMPFILE);
 }
-
-static void decompress(uint8 *data, uint32 size, PakFileEntry &output) {
-	FILE *tempFile = fopen(TEMPFILE, "wb");
-	if (!tempFile) {
-		printf("Cannot open file: %s\n", TEMPFILE);
-		exit(-1);
-	}
-	fwrite(data, sizeof(uint8), size, tempFile);
-	fclose(tempFile);
-	
-	tempFile = fopen(TEMPFILE, "rb");
-	if (!tempFile) {
-		printf("Cannot open file: %s\n", TEMPFILE);
-		exit(-1);
-	}
-	
-	extractAndEncodeVOC(TEMP_RAW, tempFile, gCompMode);
-	processFile(tempEncoded, output);
-	fclose(tempFile);
-
-	unlink(TEMPFILE);
-	unlink(TEMP_RAW);
-	unlink(tempEncoded);
-}
-
-static void processFile(const char *file, PakFileEntry &output) {
-	FILE *tempFile = fopen(file, "rb");
-	if (!tempFile) {
-		printf("Cannot open file: %s\n", file);
-		exit(-1);
-	}
-	
-	fseek(tempFile, 0, SEEK_END);
-	output.size = ftell(tempFile);
-	
-	fseek(tempFile, 0, SEEK_SET);
-	
-	output.fileData = new uint8[output.size];
-	assert(output.fileData);
-	
-	fread(output.fileData, sizeof(uint8), output.size, tempFile); 
-	
-	fclose(tempFile);
-}

Modified: tools/trunk/extract_kyra.cpp
===================================================================
--- tools/trunk/extract_kyra.cpp	2007-01-29 17:04:37 UTC (rev 25253)
+++ tools/trunk/extract_kyra.cpp	2007-01-29 17:18:25 UTC (rev 25254)
@@ -21,7 +21,7 @@
  *
  */
 
-#include "extract_kyra.h"
+#include "kyra_pak.h"
 
 int main(int argc, char **argv) {
 	if (argc < 2) {
@@ -32,7 +32,7 @@
 				"-x       Extract all files\n"
 				"-a       Use this if you want to extract files from the Amiga .PAK files\n",
 				argv[0]);
-		return false;
+		return -1;
 	}
 	
 	bool extractAll = false, extractOne = false;
@@ -49,7 +49,7 @@
 				if (param >= argc) {
 					printf("you have to add a filename to option -o\n"
 							"like: unpackkyra A_E.PAK -o ALGAE.CPS\n");
-					return false;
+					return -1;
 				}
 				
 				++pos;
@@ -61,149 +61,19 @@
 		}
 	}
 
-	PAKFile myfile(argv[1], isAmiga);
-	
+	PAKFile myfile;
+	if (!myfile.loadFile(argv[1], isAmiga)) {
+		error("couldn't load file '%s'", argv[1]);
+		return -1;
+	}
+
 	if(extractAll) {
 		myfile.outputAllFiles();
 	} else if(extractOne) {
 		myfile.outputFile(argv[param]);
 	} else {
-		myfile.drawFilelist();
+		myfile.drawFileList();
 	}
 
-	return true;
+	return 0;
 }
-
-PAKFile::PAKFile(const char* file, bool isAmiga) {
-	FILE *pakfile = fopen(file, "rb");
-	if (!pakfile) {
-		error("couldn't open file '%s'", file);
-	}
-	
-	_open = true;
-	_isAmiga = isAmiga;
-	_filesize = fileSize(pakfile);
-
-	_buffer = new uint8[_filesize];
-	assert(_buffer);
-	
-	fread(_buffer, _filesize, 1, pakfile);
-	
-	fclose(pakfile);
-}
-
-void PAKFile::drawFilelist(void) {
-	const char* currentName = 0;
-	
-	uint32 startoffset = _isAmiga ? READ_BE_UINT32(_buffer) : READ_LE_UINT32(_buffer);
-	uint32 endoffset = 0;
-	uint8* position = _buffer + 4;
-	
-	for (;;) {
-		uint32 strlgt = strlen((const char*)position);
-		currentName = (const char*)position;
-		
-		if (!(*currentName))
-			break;
-
-		position += strlgt + 1;
-		// skip offset
-		endoffset = _isAmiga ? READ_BE_UINT32(position) : READ_LE_UINT32(position);
-		if (endoffset > _filesize) {
-			endoffset = _filesize;
-		} else if (endoffset == 0) {
-			endoffset = _filesize;
-		}
-		position += 4;
-		
-		printf("Filename: %s size: %d\n", currentName, endoffset - startoffset);
-		
-		if (endoffset == _filesize) {
-			break;
-		}
-		
-		startoffset = endoffset;
-	}
-}
-
-void PAKFile::outputFile(const char* file) {
-	const char* currentName = 0;
-	
-	uint32 startoffset = _isAmiga ? READ_BE_UINT32(_buffer) : READ_LE_UINT32(_buffer);
-	uint32 endoffset = 0;
-	uint8* position = _buffer + 4;
-	
-	for (;;) {
-		uint32 strlgt = strlen((const char*)position);
-		currentName = (const char*)position;
-		
-		if (!(*currentName))
-			break;
-
-
-		position += strlgt + 1;
-		// skip offset
-		endoffset = _isAmiga ? READ_BE_UINT32(position) : READ_LE_UINT32(position);
-		if (endoffset > _filesize) {
-			endoffset = _filesize;
-		} else if (endoffset == 0) {
-			endoffset = _filesize;
-		}
-		position += 4;
-		
-		if (!strcmp(currentName, file)) {
-			FILE *output = fopen(file, "wb");
-			if (output) {
-				fwrite(_buffer + startoffset, endoffset - startoffset, 1, output);
-				fclose(output);
-			}
-			return;
-		}
-		
-		if (endoffset == _filesize) {
-			break;
-		}
-		
-		startoffset = endoffset;
-	}
-	
-	printf("File '%s' not found in this pakfile\n", file);
-}
-
-void PAKFile::outputAllFiles(void) {
-	const char* currentName = 0;
-	
-	uint32 startoffset = _isAmiga ? READ_BE_UINT32(_buffer) : READ_LE_UINT32(_buffer);
-	uint32 endoffset = 0;
-	uint8* position = _buffer + 4;
-	
-	for (;;) {
-		uint32 strlgt = strlen((const char*)position);
-		currentName = (const char*)position;
-		
-		if (!(*currentName))
-			break;
-
-		position += strlgt + 1;
-		// skip offset
-		endoffset = _isAmiga ? READ_BE_UINT32(position) : READ_LE_UINT32(position);
-		if (endoffset > _filesize) {
-			endoffset = _filesize;
-		} else if (endoffset == 0) {
-			endoffset = _filesize;
-		}
-		position += 4;
-		
-		FILE *output = fopen(currentName, "wb");
-		if (output) {
-			fwrite(_buffer + startoffset, endoffset - startoffset, 1, output);
-			fclose(output);
-		}
-		
-		if (endoffset == _filesize) {
-			break;
-		}
-		
-		startoffset = endoffset;
-	}
-}

Deleted: tools/trunk/extract_kyra.h
===================================================================
--- tools/trunk/extract_kyra.h	2007-01-29 17:04:37 UTC (rev 25253)
+++ tools/trunk/extract_kyra.h	2007-01-29 17:18:25 UTC (rev 25254)
@@ -1,49 +0,0 @@
-/* UnPak - Extractor for Kyrandia .pak archives
- * Copyright (C) 2004  Johannes Schickel
- * Copyright (C) 2004-2006  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
- * 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 UNPAK_H
-#define UNPAK_H
-
-#include "util.h"
-
-// standard Package format for Kyrandia games
-class PAKFile {
-	public:
-		PAKFile(const char* file, bool isAmiga);
-		~PAKFile() { delete [] _buffer; }
-		
-		void drawFilelist(void);
-		void outputAllFiles(void);
-		void outputFile(const char* file);
-
-		bool isValid(void) {return (_buffer != 0);}
-		bool isOpen(void) {return _open;}
-
-	private:
-		bool _open;
-		bool _isAmiga;
-		uint8* _buffer; // the whole file	
-		uint32 _filesize;	
-};
-
-#endif

Added: tools/trunk/kyra_pak.cpp
===================================================================
--- tools/trunk/kyra_pak.cpp	                        (rev 0)
+++ tools/trunk/kyra_pak.cpp	2007-01-29 17:18:25 UTC (rev 25254)
@@ -0,0 +1,244 @@
+/* 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$
+ *
+ */
+
+#include "kyra_pak.h"
+
+bool PAKFile::loadFile(const char *file, const bool isAmiga) {
+	_isAmiga = isAmiga;
+	if (!file)
+		return true;
+
+	delete _fileList;
+	_fileList = 0;
+
+	FILE *pakfile = fopen(file, "rb");
+	if (!pakfile) {
+		error("couldn't open file '%s'", file);
+		return false;
+	}
+
+	uint32 filesize = fileSize(pakfile);
+
+	// TODO: get rid of temp. buffer
+	uint8 *buffer = new uint8[filesize];
+	assert(buffer);
+	
+	fread(buffer, filesize, 1, pakfile);
+	
+	fclose(pakfile);
+	
+	const char *currentName = 0;
+	
+	uint32 startoffset = _isAmiga ? READ_BE_UINT32(buffer) : READ_LE_UINT32(buffer);
+	uint32 endoffset = 0;
+	uint8* position = buffer + 4;
+	
+	while (true) {
+		uint32 strlgt = strlen((const char*)position);
+		currentName = (const char*)position;
+		
+		if (!(*currentName))
+			break;
+
+		position += strlgt + 1;
+		endoffset = _isAmiga ? READ_BE_UINT32(position) : READ_LE_UINT32(position);
+		if (endoffset > filesize) {
+			endoffset = filesize;
+		} else if (endoffset == 0) {
+			endoffset = filesize;
+		}
+		position += 4;
+		
+		FileList *newEntry = new FileList;
+		assert(newEntry);
+		
+		newEntry->filename = new char[strlgt+1];
+		assert(newEntry->filename);
+		memcpy(newEntry->filename, currentName, strlgt+1);
+		newEntry->size = endoffset - startoffset;
+		newEntry->data = new uint8[newEntry->size];
+		assert(newEntry->data);
+		memcpy(newEntry->data, buffer + startoffset, newEntry->size);
+		
+		if (_fileList) {
+			_fileList->addEntry(newEntry);
+		} else {
+			_fileList = newEntry;
+		}
+		
+		if (endoffset == filesize)
+			break;
+		
+		startoffset = endoffset;
+	}
+	
+	delete [] buffer;
+	return true;
+}
+
+bool PAKFile::saveFile(const char *file) {
+	if (!_fileList)
+		return true;
+
+	FILE *f = fopen(file, "wb");
+	if (!f) {
+		error("couldn't open file '%s' for writing", file);
+		return false;
+	}
+	
+	// TODO: implement error handling
+	uint32 startAddr = _fileList->getTableSize()+5+4;
+	static const char *zeroName = "\0\0\0\0\0";
+	
+	uint32 curAddr = startAddr;
+	for (FileList *cur = _fileList; cur; cur = cur->next) {
+		if (_isAmiga)
+			writeUint32BE(f, curAddr);
+		else
+			writeUint32LE(f, curAddr);
+		fwrite(cur->filename, 1, strlen(cur->filename) + 1, f);
+		curAddr += cur->size;
+	}
+	if (_isAmiga)
+		writeUint32BE(f, curAddr);
+	else
+		writeUint32LE(f, curAddr);
+	fwrite(zeroName, 1, 5, f);
+	
+	for (FileList *cur = _fileList; cur; cur = cur->next)
+		fwrite(cur->data, 1, cur->size, f);
+	
+	fclose(f);	
+	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::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'...", cur->filename);
+	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;
+
+	if (!cur) {
+		error("file '%s' not found");
+		return 0;
+	}
+	
+	if (size)
+		*size = cur->size;
+	return cur->data;
+}
+
+bool PAKFile::addFile(const char *name, const char *file) {
+	if (_fileList && _fileList->findEntry(name)) {
+		error("entry '%s' already exists");
+		return false;
+	}
+	
+	FILE *f = fopen(file, "rb");
+	if (!f) {
+		error("couldn't open file '%s'", file);
+		return false;
+	}
+	
+	uint32 filesize = fileSize(f);
+	uint8 *data = new uint8[filesize];
+	assert(data);
+	if (fread(data, 1, filesize, f) != filesize) {
+		error("couldn't read from file '%s'", file);
+		return false;
+	}
+	fclose(f);	
+	return addFile(name, data, filesize);
+}
+
+bool PAKFile::addFile(const char *name, uint8 *data, uint32 size) {
+	if (_fileList && _fileList->findEntry(name)) {
+		error("entry '%s' already exists");
+		return false;
+	}
+
+	FileList *newEntry = new FileList;
+	assert(newEntry);
+	newEntry->filename = new char[strlen(name)+1];
+	assert(newEntry->filename);
+	strcpy(newEntry->filename, name);
+	newEntry->size = size;
+	newEntry->data = data;
+
+	if (_fileList) {
+		_fileList->addEntry(newEntry);
+	} else {
+		_fileList = newEntry;
+	}
+
+	return true;
+}


Property changes on: tools/trunk/kyra_pak.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Added: tools/trunk/kyra_pak.h
===================================================================
--- tools/trunk/kyra_pak.h	                        (rev 0)
+++ tools/trunk/kyra_pak.h	2007-01-29 17:18:25 UTC (rev 25254)
@@ -0,0 +1,89 @@
+/* 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 KYRA_PAK_H
+#define KYRA_PAK_H
+
+#include "util.h"
+#include <string.h>
+
+class PAKFile {
+public:
+	PAKFile() : _fileList(0), _isAmiga(false) {}
+	~PAKFile() { delete _fileList; }
+
+	bool loadFile(const char *file, const bool isAmiga);
+	bool saveFile(const char *file);
+
+	void drawFileList();
+
+	bool outputAllFiles();
+
+	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);
+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;
+		}
+		void addEntry(FileList *e) {
+			if (next)
+				next->addEntry(e);
+			else
+				next = e;
+		}
+		uint32 getTableSize() {
+			return strlen(filename)+1+4+((next != 0) ? next->getTableSize() : 0);
+		}
+
+		char *filename;
+		uint32 size;
+		uint8 *data;
+		
+		FileList *next;
+	};
+
+	typedef const FileList cFileList;
+	
+	cFileList *getFileList() { return _fileList; }
+private:
+	FileList *_fileList;
+	bool _isAmiga;
+};
+
+#endif


Property changes on: tools/trunk/kyra_pak.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native


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