[Scummvm-cvs-logs] scummvm-tools master -> d471dc8ca2ed9bb5b405974755064ed918426678

sev- sev at scummvm.org
Mon Nov 3 17:07:32 CET 2014


This automated email contains information about 10 new commits which have been
pushed to the 'scummvm-tools' repo located at https://github.com/scummvm/scummvm-tools .

Summary:
f6bec2d4a7 PRINCE: Texts extraction tool for translation purposes
a97aaf9ecd PRINCE: Update in translation extraction tool
4e1ad68ab9 PRINCE: Text packing tool for translation purposes
00f618f298 PRINCE: Update of extracting and packing tool for credits file
d24638c099 PRINCE: Packing tool - pack all previous files to one main translation file - prince_translation.dat
061fa53d4c PRINCE: Extraction and packing tool - rename some variables, add more printfs during packing, update comments
9b0be70fc1 PRINCE: Extraction tool - allow to extract texts from DE data
43fce1314d PRINCE: Fix compilation on gcc, silence warnings
8b268067af PRINCE: Add extract/pack tools in MSVC10 build files
d471dc8ca2 Merge pull request #7 from lukaslw/prince-tools


Commit: f6bec2d4a73cce20ee3fa59fc76aa6d5d83c15e7
    https://github.com/scummvm/scummvm-tools/commit/f6bec2d4a73cce20ee3fa59fc76aa6d5d83c15e7
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-06T04:38:18+02:00

Commit Message:
PRINCE: Texts extraction tool for translation purposes

Changed paths:
  A engines/prince/extract_prince.cpp
  A engines/prince/extract_prince.h
    tools.cpp



diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
new file mode 100644
index 0000000..6d28506
--- /dev/null
+++ b/engines/prince/extract_prince.cpp
@@ -0,0 +1,701 @@
+/* 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 <string.h>
+#include "extract_prince.h"
+#include "common\endian.h"
+
+struct FileData;
+
+ExtractPrince::ExtractPrince(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
+	ToolInput input;
+	input.format = "/";
+	_inputPaths.push_back(input);
+
+	_outputToDirectory = true;
+
+	_shorthelp = "Used to extract The Prince and the Coward text data for translation.";
+	_helptext = "\nUsage: " + getName() + " [-o /path/to/output/dir/] <inputfile>\n";
+}
+
+void ExtractPrince::execute() {
+	const int kNumberOfLocations = 61;
+
+	Common::Filename mainDir = _inputPaths[0].path;
+	// We always need to setup default output path, since there is no obligation to specify it
+	if (_outputPath.empty()) {
+		_outputPath.setFullPath("./");
+	}
+
+	char *pathBuffer = (char *)malloc(17 * sizeof(char));
+	printf("Unpacking The Prince and the Coward text data... \n");
+
+	std::string fullName = mainDir.getFullPath();
+	sprintf(pathBuffer, "all/databank.ptc");
+	fullName += pathBuffer;
+	Common::Filename filename(fullName);
+	_databank.open(filename, "rb");
+	if (!_databank.isOpen()) {
+		_fFiles.close();
+		error("Unable to open all/databank.ptc");
+	}
+	byte *fileTable = openDatabank();
+	for (size_t i = 0; i < _items.size(); i++) {
+		if (!scumm_stricmp(_items[i]._name.c_str(), "variatxt.dat")) {
+			exportVariaTxt(loadFile(i));
+		}
+		if (!scumm_stricmp(_items[i]._name.c_str(), "invtxt.dat")) {
+			exportInvTxt(loadFile(i));
+		}
+		if (!scumm_stricmp(_items[i]._name.c_str(), "talktxt.dat")) {
+			exportTalkTxt(loadFile(i));
+		}
+	}
+	free(fileTable);
+	_databank.close();
+	_items.clear();
+
+	_outputPath.setFullName("mob.txt");
+	_fFiles.open(_outputPath, "w");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create mob.txt");
+	}
+	_fFiles.print("mob.lst\nmob_name - exam text\n");
+	for (int loc = 1; loc <= kNumberOfLocations; loc++) {
+		if (loc != 44 && loc != 45) {
+			_fFiles.print("\nLocation %d\n", loc);
+			std::string fullName = mainDir.getFullPath();
+			sprintf(pathBuffer, "%02d/databank.ptc", loc);
+			fullName += pathBuffer;
+			Common::Filename filename(fullName);
+			_databank.open(filename, "rb");
+			if (!_databank.isOpen()) {
+				_fFiles.close();
+				error("Unable to open %02d/databank.ptc", loc);
+			}
+			byte *fileTable = openDatabank();
+			for (size_t i = 0; i < _items.size(); i++) {
+				if (!scumm_stricmp(_items[i]._name.c_str(), "mob.lst")) {
+					exportMobs(loadFile(i));
+				}
+			}
+			free(fileTable);
+			_databank.close();
+			_items.clear();
+		}
+	}
+	printf("mob.txt - done\n");
+	printf("All done!\n");
+	free(pathBuffer);
+	_fFiles.close();
+}
+
+InspectionMatch ExtractPrince::inspectInput(const Common::Filename &filename) {
+	std::string file = filename.getFullName();
+	if (scumm_stricmp(file.c_str(), "databank.ptc") == 0) {
+		return IMATCH_PERFECT;
+	}
+	return IMATCH_AWFUL;
+}
+
+byte *ExtractPrince::openDatabank() {
+	_databank.readUint32LE(); // magic
+	uint32 fileTableOffset = _databank.readUint32LE() ^ 0x4D4F4B2D; // MOK-
+	uint32 fileTableSize = _databank.readUint32LE() ^ 0x534F4654; // SOFT
+
+	//printf("fileTableOffset : %08X\n", fileTableOffset);
+	//printf("fileTableSize: %08X\n", fileTableSize);
+
+	_databank.seek(fileTableOffset, SEEK_SET);
+
+	byte *fileTable = (byte *)malloc(fileTableSize);
+	byte *fileTableEnd = fileTable + fileTableSize;
+	_databank.read_throwsOnError(fileTable, fileTableSize);
+
+	decrypt(fileTable, fileTableSize);
+
+	for (byte *fileItem = fileTable; fileItem < fileTableEnd; fileItem += 32) {
+		FileEntry item;
+		item._name = (const char *)fileItem;
+		item._offset = READ_LE_UINT32(fileItem + 24);
+		item._size = READ_LE_UINT32(fileItem + 28);
+		//printf("%12s %8X %d\n", (const char *)fileItem, item._offset, item._size);
+		_items.push_back(item);
+	}
+	return fileTable;
+}
+
+void ExtractPrince::decrypt(byte *buffer, uint32 size) {
+	uint32 key = 0xDEADF00D;
+	while (size--) {
+		*buffer++ += key & 0xFF;
+		key ^= 0x2E84299A;
+		key += 0x424C4148;
+		key = ((key & 1) << 31) | (key >> 1);
+	}
+}
+
+ExtractPrince::FileData ExtractPrince::loadFile(int itemIndex) {
+	FileData fileData;
+	fileData._fileTable = nullptr;
+	fileData._size = 0;
+
+	const FileEntry &entryHeader = _items[itemIndex];
+
+	if (entryHeader._size < 4) {
+		return fileData;
+	}
+
+	fileData._size = entryHeader._size;
+
+	_databank.seek(entryHeader._offset, SEEK_SET);
+
+	fileData._fileTable = (byte *)malloc(fileData._size);
+	_databank.read_throwsOnError(fileData._fileTable, fileData._size);
+
+	if (READ_BE_UINT32(fileData._fileTable) == 0x4D41534D) {
+		Decompressor dec;
+		uint32 decompLen = READ_BE_UINT32(fileData._fileTable + 14);
+		byte *decompData = (byte *)malloc(decompLen);
+		dec.decompress(fileData._fileTable + 18, decompData, decompLen);
+		free(fileData._fileTable);
+		fileData._size = decompLen;
+		fileData._fileTable = decompData;
+	}
+
+	return fileData;
+}
+
+// TODO - export offset/id of mob?
+void ExtractPrince::exportMobs(FileData fileData) {
+	if (fileData._fileTable != nullptr) {
+		const int kMobsStructSize = 32;
+		const int kMobsTextOffsetsPos = 24;
+		int streamPos = 0;
+
+		while (READ_LE_UINT16(fileData._fileTable + streamPos) != 0xFFFF) {
+			byte *mobTextOffset = fileData._fileTable + streamPos + kMobsTextOffsetsPos;
+
+			uint32 nameOffset = READ_LE_UINT32(mobTextOffset);
+			mobTextOffset += 4;
+			uint32 examTextOffset = READ_LE_UINT32(mobTextOffset);
+
+			std::string mobName, mobExamText;
+			byte c;
+
+			byte *namePointer = fileData._fileTable + nameOffset;
+			mobName.clear();
+			while ((c = *namePointer)) {
+				c = correctPolishLetter(c);
+				mobName += c;
+				namePointer++;
+			}
+
+			byte *examPointer = fileData._fileTable + examTextOffset;
+			mobExamText.clear();
+			c = *examPointer;
+			examPointer++;
+			if (c) {
+				// TODO - add this in packing tool
+				//mobExamText += c;
+				do {
+					c = *examPointer;
+					c = correctPolishLetter(c);
+					if (c == 10) {
+						c = '|';
+					}
+					mobExamText += c;
+					examPointer++;
+				} while (c != 255);
+			}
+			_fFiles.print("%s - %s\n", mobName.c_str(), mobExamText.c_str());
+			streamPos += kMobsStructSize;
+		}
+		free(fileData._fileTable);
+	}
+}
+
+void ExtractPrince::exportVariaTxt(FileData fileData) {
+	if (fileData._fileTable != nullptr) {
+		_outputPath.setFullName("variatxt.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create variatxt.txt");
+		}
+		_fFiles.print("variatxt.dat\nstringId. string\n");
+		const int variaTxtSize = 6000;
+		for (int stringId = 0; stringId < variaTxtSize; stringId++) {
+			uint32 stringOffset = READ_LE_UINT32(fileData._fileTable + stringId * 4);
+			if (stringOffset > fileData._size) {
+				assert(false);
+			}
+			std::string variaTxtString;
+			byte c;
+			byte *txtPointer = fileData._fileTable + stringOffset;
+			variaTxtString.clear();
+			txtPointer++; // TODO -  remove this in packing tool
+			while ((c = *txtPointer)) {
+				c = correctPolishLetter(c);
+				variaTxtString += c;
+				txtPointer++;
+			}
+			if (variaTxtString.size()) {
+				_fFiles.print("%d. %s\n", stringId, variaTxtString.c_str());
+			}
+		}
+		free(fileData._fileTable);
+		_fFiles.close();
+		printf("variatxt.txt - done\n");
+	}
+}
+
+void ExtractPrince::exportInvTxt(FileData fileData) {
+	if (fileData._fileTable != nullptr) {
+		std::string itemName, itemExamText;
+		const int kItems = 100;
+		_outputPath.setFullName("invtxt.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create invtxt.txt");
+		}
+		_fFiles.print("invtxt.dat\nitemNr. name - exam text\n");
+		for (int itemNr = 0; itemNr < kItems; itemNr++) {
+			int txtOffset = READ_LE_UINT32(fileData._fileTable + itemNr * 8);
+			int examTxtOffset = READ_LE_UINT32(fileData._fileTable + itemNr * 8 + 4);
+
+			byte c;
+			byte *nameTxt = fileData._fileTable + txtOffset;
+			itemName.clear();
+			while ((c = *nameTxt)) {
+				c = correctPolishLetter(c);
+				itemName += c;
+				nameTxt++;
+			}
+
+			byte *examTxt = fileData._fileTable + examTxtOffset;
+			itemExamText.clear();
+			while ((c = *examTxt)) {
+				c = correctPolishLetter(c);
+				if (c == 10) {
+					c = '|';
+				}
+				itemExamText += c;
+				examTxt++;
+			}
+
+			if (itemName.size() != 2) {
+				_fFiles.print("%d. %s - %s\n", itemNr, itemName.c_str(), itemExamText.c_str());
+			}
+		}
+		free(fileData._fileTable);
+		_fFiles.close();
+		printf("invtxt.txt - done\n");
+	}
+}
+
+void ExtractPrince::exportTalkTxt(FileData fileData) {
+	if (fileData._fileTable != nullptr) {
+		_outputPath.setFullName("talktxt.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create talktxt.txt");
+		}
+		_fFiles.print("talktxt.dat\n");
+		const int textOffset = 8000;
+		byte *talkTxt = fileData._fileTable + textOffset;
+		uint32 pos = 0;
+		int size;
+		while (pos + textOffset < fileData._size) {
+			if (*talkTxt == 0xFF) {
+				size = talkTxtWithDialog(talkTxt);
+				talkTxt += size;
+				pos += size;
+			} else {
+				size = talkTxtNoDialog(talkTxt);
+				talkTxt += size;
+				pos += size;
+			}
+		}
+		free(fileData._fileTable);
+		_fFiles.close();
+		printf("talktxt.txt - done\n");
+	}
+}
+
+int ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
+	byte *mainString;
+	byte *dialogBoxAddr[32];
+	byte *dialogOptAddr[32];
+	byte c;
+	std::string lineString;
+	int size = 0;
+
+	byte *stringCurrOff = talkTxt;
+	stringCurrOff++;
+	size++;
+	int32 adressOfFirstSequence = (int)READ_LE_UINT16(stringCurrOff);
+	mainString = talkTxt + adressOfFirstSequence;
+	stringCurrOff += 2;
+	size += 2;
+
+	for (int i = 0; i < 32; i++) {
+		dialogBoxAddr[i] = 0;
+		dialogOptAddr[i] = 0;
+	}
+
+	int16 off;
+	byte *line = nullptr;
+
+	int dialogBox = 0;
+	while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
+		stringCurrOff += 2;
+		size += 2;
+		if (off) {
+			line = talkTxt + off;
+		}
+		dialogBoxAddr[dialogBox] = line;
+		dialogBox++;
+	}
+	stringCurrOff += 2;
+	size += 2;
+
+	int dialogOpt = 0;
+	while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
+		stringCurrOff += 2;
+		size += 2;
+		if (off) {
+			line = talkTxt + off;
+		}
+		dialogOptAddr[dialogOpt] = line;
+		dialogOpt++;
+	}
+	size += 2;
+
+	_fFiles.print("@DIALOGBOX_LINES:\n");
+	while ((c = *mainString) != 255) {
+		if (printSpecialDialogData(c)) {
+			mainString++;
+			size++;
+			_fFiles.print("%c\n", (*mainString) + 48);
+		}
+		mainString++;
+		size++;
+	}
+	size++;
+	_fFiles.print("#END\n");
+			
+	for (int i = 0; i < dialogBox; i++) {
+		_fFiles.print("@DIALOG_BOX %d\n", i);
+		while ((c = *dialogBoxAddr[i]) != 255) {
+			_fFiles.print("$%d\n", *dialogBoxAddr[i]);
+			dialogBoxAddr[i]++;
+			size++;
+			lineString.clear();
+			while ((c = *dialogBoxAddr[i])) {
+				c = correctPolishLetter(c);
+				if (c == 10) {
+					c = '|';
+				}
+				dialogBoxAddr[i]++;
+				size++;
+				lineString += c;
+			}
+			dialogBoxAddr[i]++;
+			size++;
+			_fFiles.print("%s\n", lineString.c_str());
+		}
+		size++;
+		_fFiles.print("#END\n");
+	}
+
+	for (int i = 0; i < dialogOpt; i++) {
+		_fFiles.print("@DIALOG_OPT %d\n", i);
+		while ((c = *dialogOptAddr[i]) != 255) {
+			if (printSpecialDialogData(c)) {
+				dialogOptAddr[i]++;
+				size++;
+				_fFiles.print("%c\n", (*dialogOptAddr[i]) + 48);
+			}
+			dialogOptAddr[i]++;
+			size++;
+		}
+		size++;
+		_fFiles.print("#END\n");
+	}
+	_fFiles.print("#ENDEND\n");
+	return size;
+}
+
+int ExtractPrince::talkTxtNoDialog(byte *talkTxt) {
+	byte c;
+	int size = 0;
+	_fFiles.print("@NORMAL_LINES:\n");
+	while ((c = *talkTxt) != 255) {
+		if (printSpecialDialogData(c)) {
+			talkTxt++;
+			size++;
+			_fFiles.print("%c\n", (*talkTxt) + 48);
+		}
+		talkTxt++;
+		size++;
+	}
+	size++;
+	_fFiles.print("#END\n");
+	return size;
+}
+
+// Returns 'true' if next char is a value for 'enable option', 
+// 'disable option', 'show dialog box", 'flag code' or 'exit code'
+bool ExtractPrince::printSpecialDialogData(byte c) {
+	switch (c) {
+	case 0:
+		_fFiles.print("\n");
+		return false;
+	case 1:
+		_fFiles.print("#HERO\n");
+		return false;
+	case 4:
+		_fFiles.print("#OTHER\n");
+		return false;
+	case 5:
+		_fFiles.print("#OTHER2\n");
+		return false;
+	case 10:
+		_fFiles.print("|");
+		return false;
+	case 254:
+		_fFiles.print("#PAUSE\n");
+		return false;
+	case 240:
+		_fFiles.print("#ENABLE ");
+		return true;
+	case 241:
+		_fFiles.print("#DISABLE ");
+		return true;
+	case 242:
+		_fFiles.print("#BOX ");
+		return true;
+	case 243:
+		_fFiles.print("#EXIT ");
+		return true;
+	case 244:
+		_fFiles.print("#FLAG ");
+		return true;
+	default:
+		c = correctPolishLetter(c);
+		_fFiles.print("%c", c);
+		return false;
+	}
+}
+
+// Conversion from Mazovia to Windows-1250
+char ExtractPrince::correctPolishLetter(char c) {
+	switch (c) {
+	case '\x86':
+		return '\xB9';
+	case '\x92':
+		return '\xB3';
+	case '\x9E':
+		return '\x9C';
+	case '\x8D':
+		return '\xE6';
+	case '\xA4':
+		return '\xF1';
+	case '\xA6':
+		return '\x9F';
+	case '\x91':
+		return '\xEA';
+	case '\xA2':
+		return '\xF3';
+	case '\xA7':
+		return '\xBF';
+	case '\x8F':
+		return '\xA5';
+	case '\x9C':
+		return '\xA3';
+	case '\x98':
+		return '\x8C';
+	case '\x95':
+		return '\xC6';
+	case '\xA5':
+		return '\xD1';
+	case '\xA0':
+		return '\x8F';
+	case '\x90':
+		return '\xCA';
+	case '\xA3':
+		return '\xD3';
+	case '\xA1':
+		return '\xAF';
+	default:
+		return c;
+	}
+}
+
+// John_Doe's implementation
+static const uint16 table1[] = {
+    0x8000, 0x0002,
+    0x4000, 0x0004,
+    0x2000, 0x0008,
+    0x1000, 0x0010,
+    0x0800, 0x0020,
+    0x0400, 0x0040,
+    0x0200, 0x0080,
+    0x0100, 0x0100,
+    0x0080, 0x0200,
+    0x0040, 0x0400
+};
+
+static const uint32 table2[] = {
+    0x0000F000,
+    0x0020FC00,
+    0x00A0FF00,
+    0x02A0FF80,
+    0x06A0FFC0,
+    0x0EA0FFE0,
+    0x1EA0FFF0,
+    0x3EA0FFF8
+};
+
+static const uint16 table3[] = {
+    0x8000, 0x0000,
+    0x4000, 0x0002,
+    0x2000, 0x0006,
+    0x1000, 0x000E,
+    0x0800, 0x001E,
+    0x0400, 0x003E,
+    0x0200, 0x007E,
+    0x0100, 0x00FE,
+    0x0080, 0x01FE,
+    0x0040, 0x03FE,
+    0x0020, 0x07FE,
+    0x0010, 0x0FFE,
+    0x0008, 0x1FFE,
+    0x0004, 0x3FFE,
+    0x0002, 0x7FFE,
+    0x0001, 0xFFFE
+};
+
+void Decompressor::decompress(byte *source, byte *dest, uint32 destSize) {
+    byte *destEnd = dest + destSize;
+    int more;
+    _src = source;
+    _dst = dest;
+    _bitBuffer = 0x80;
+    while (_dst < destEnd) {
+        uint32 ebp;
+        uint16 offset, length;
+        if (getBit()) {
+            if (getBit()) {
+                if (getBit()) {
+                    if (getBit()) {
+                        if (getBit()) {
+                            if (getBit()) {
+                                uint32 tableIndex = 0;
+                                while (getBit())
+                                    tableIndex++;
+                                length = table3[tableIndex * 2 + 0];
+                                do {
+                                    more = !(length & 0x8000);
+                                    length = (length << 1) | getBit();
+                                } while (more);
+                                length += table3[tableIndex * 2 + 1];
+                                length++;
+                                memcpy(_dst, _src, length);
+                                _src += length;
+                                _dst += length;
+                            }
+                            *_dst++ = *_src++;
+                        }
+                        *_dst++ = *_src++;
+                    }
+                    *_dst++ = *_src++;
+                }
+                *_dst++ = *_src++;
+            }
+            *_dst++ = *_src++;
+        }
+        if (!getBit()) {
+            if (getBit()) {
+                uint32 tableIndex = getBit();
+                tableIndex = (tableIndex << 1) | getBit();
+                tableIndex = (tableIndex << 1) | getBit();
+                ebp = table2[tableIndex];
+                length = 1;
+            } else {
+                ebp = 0x0000FF00;
+                length = 0;
+            }
+        } else {
+            uint32 tableIndex = 0;
+            while (getBit())
+                tableIndex++;
+            length = table1[tableIndex * 2 + 0];
+            do {
+                more = !(length & 0x8000);
+                length = (length << 1) | getBit();
+            } while (more);
+            length += table1[tableIndex * 2 + 1];
+            tableIndex = getBit();
+            tableIndex = (tableIndex << 1) | getBit();
+            tableIndex = (tableIndex << 1) | getBit();
+            ebp = table2[tableIndex];
+        }
+        offset = ebp & 0xFFFF;
+        do {
+            if (_bitBuffer == 0x80) {
+                if (offset >= 0xFF00) {
+                    offset = (offset << 8) | *_src++;
+                }
+            }
+            more = offset & 0x8000;
+            offset = (offset << 1) | getBit();
+        } while (more);
+        offset += (ebp >> 16);
+        length += 2;
+        while (length--) {
+            if (_dst >= destEnd) {
+                return;
+            }
+            *_dst = *(_dst - offset);
+            _dst++;
+        }
+    }
+}
+
+int Decompressor::getBit() {
+    int bit = (_bitBuffer & 0x80) >> 7;
+    _bitBuffer <<= 1;
+    if (_bitBuffer == 0) {
+        _bitBuffer = *_src++;
+        bit = (_bitBuffer & 0x80) >> 7;
+        _bitBuffer <<= 1;
+        _bitBuffer |= 1;
+    }
+    return bit;
+}
+
+#ifdef STANDALONE_MAIN
+int main(int argc, char *argv[]) {
+	ExtractCge cge(argv[0]);
+	return cge.run(argc, argv);
+}
+#endif
diff --git a/engines/prince/extract_prince.h b/engines/prince/extract_prince.h
new file mode 100644
index 0000000..47292bb
--- /dev/null
+++ b/engines/prince/extract_prince.h
@@ -0,0 +1,76 @@
+/* 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_PRINCE_H
+#define EXTRACT_PRINCE_H
+
+#include "tool.h"
+#include "common\array.h"
+
+class ExtractPrince : public Tool {
+public:
+	ExtractPrince(const std::string &name = "extract_prince");
+	
+	virtual void execute();
+	
+	virtual InspectionMatch inspectInput(const Common::Filename &filename);
+	
+protected:
+	struct FileEntry {
+		std::string _name;
+		uint32 _offset;
+		uint32 _size;
+	};
+
+	struct FileData {
+		byte *_fileTable;
+		uint32 _size;
+	};
+
+	byte *openDatabank();
+	static void decrypt(byte *buffer, uint32 size);
+
+	FileData loadFile(int itemIndex);
+	char correctPolishLetter(char c);
+
+	void exportMobs(FileData fileData);
+	void exportVariaTxt(FileData fileData);
+	void exportInvTxt(FileData fileData);
+	void exportTalkTxt(FileData fileData);
+	int talkTxtWithDialog(byte *talkTxt);
+	int talkTxtNoDialog(byte *talkTxt);
+	bool printSpecialDialogData(byte c);
+
+	Common::Array<FileEntry> _items;
+	Common::File _databank, _fFiles;
+};
+
+class Decompressor {
+public:
+	void decompress(byte *source, byte *dest, uint32 destSize);
+protected:
+	byte *_src, *_dst;
+	byte _bitBuffer;
+	int _bitsLeft;
+	int getBit();
+};
+
+#endif
diff --git a/tools.cpp b/tools.cpp
index af80aca..6ea6644 100644
--- a/tools.cpp
+++ b/tools.cpp
@@ -52,6 +52,7 @@
 #include "engines/gob/extract_gob_stk.h"
 #include "engines/gob/extract_fascination_cd.h"
 #include "engines/kyra/extract_kyra.h"
+#include "engines/prince/extract_prince.h"
 #include "engines/scumm/extract_loom_tg16.h"
 #include "engines/scumm/extract_mm_apple.h"
 #include "engines/scumm/extract_mm_c64.h"
@@ -89,6 +90,7 @@ Tools::Tools() {
 	_tools.push_back(new ExtractGobStk());
 	_tools.push_back(new ExtractFascinationCD());
 	_tools.push_back(new ExtractKyra());
+	_tools.push_back(new ExtractPrince());
 	_tools.push_back(new ExtractLoomTG16());
 	_tools.push_back(new ExtractMMApple());
 	_tools.push_back(new ExtractMMC64());


Commit: a97aaf9ecd8ac6d549fe8e3065dab996cce2088b
    https://github.com/scummvm/scummvm-tools/commit/a97aaf9ecd8ac6d549fe8e3065dab996cce2088b
Author: Łukasz Wątka (lukaslw at gmail.com)
Date: 2014-10-25T05:30:58+02:00

Commit Message:
PRINCE: Update in translation extraction tool

variatxt.txt - change new lines to |

mob.txt - fix for texts longer then 1 sentence and change in location numeration.

talktxt.txt - fix several bugs that appears in original talktxt.dat

Add talktxt_ids.txt file for offset calculations

Changed paths:
    engines/prince/extract_prince.cpp
    engines/prince/extract_prince.h



diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
index 6d28506..2339e2d 100644
--- a/engines/prince/extract_prince.cpp
+++ b/engines/prince/extract_prince.cpp
@@ -80,8 +80,9 @@ void ExtractPrince::execute() {
 	}
 	_fFiles.print("mob.lst\nmob_name - exam text\n");
 	for (int loc = 1; loc <= kNumberOfLocations; loc++) {
+		_fFiles.print("%d.\n", loc);
+		// no databanks for loc 44 and 45
 		if (loc != 44 && loc != 45) {
-			_fFiles.print("\nLocation %d\n", loc);
 			std::string fullName = mainDir.getFullPath();
 			sprintf(pathBuffer, "%02d/databank.ptc", loc);
 			fullName += pathBuffer;
@@ -184,7 +185,6 @@ ExtractPrince::FileData ExtractPrince::loadFile(int itemIndex) {
 	return fileData;
 }
 
-// TODO - export offset/id of mob?
 void ExtractPrince::exportMobs(FileData fileData) {
 	if (fileData._fileTable != nullptr) {
 		const int kMobsStructSize = 32;
@@ -208,25 +208,40 @@ void ExtractPrince::exportMobs(FileData fileData) {
 				mobName += c;
 				namePointer++;
 			}
+			if (mobName.size()) {
+				_fFiles.print("%s - ", mobName.c_str());
+			}
 
 			byte *examPointer = fileData._fileTable + examTextOffset;
 			mobExamText.clear();
 			c = *examPointer;
-			examPointer++;
 			if (c) {
-				// TODO - add this in packing tool
-				//mobExamText += c;
-				do {
-					c = *examPointer;
-					c = correctPolishLetter(c);
-					if (c == 10) {
-						c = '|';
-					}
-					mobExamText += c;
+				examPointer++;
+				while ((c = *examPointer) != 255) {
+					mobExamText.clear();
+					do {
+						c = correctPolishLetter(c);
+						if (c == 10) {
+							c = '|';
+						}
+						mobExamText += c;
+						examPointer++;
+					} while ((c = *examPointer));
+					_fFiles.print("%s", mobExamText.c_str());
 					examPointer++;
-				} while (c != 255);
+					if (*examPointer == 254) {
+						_fFiles.print("*"); // show that there is pause before talking
+						examPointer++;
+					}
+					if (*examPointer == 1) {
+						_fFiles.print("+"); // show that there is next line of exam text
+						examPointer++;
+					}
+				};
+			}
+			if (mobName.size()) {
+				_fFiles.print("\n");
 			}
-			_fFiles.print("%s - %s\n", mobName.c_str(), mobExamText.c_str());
 			streamPos += kMobsStructSize;
 		}
 		free(fileData._fileTable);
@@ -254,6 +269,9 @@ void ExtractPrince::exportVariaTxt(FileData fileData) {
 			txtPointer++; // TODO -  remove this in packing tool
 			while ((c = *txtPointer)) {
 				c = correctPolishLetter(c);
+				if (c == 10) {
+					c = '|';
+				}
 				variaTxtString += c;
 				txtPointer++;
 			}
@@ -319,42 +337,67 @@ void ExtractPrince::exportTalkTxt(FileData fileData) {
 			error("Unable to create talktxt.txt");
 		}
 		_fFiles.print("talktxt.dat\n");
-		const int textOffset = 8000;
-		byte *talkTxt = fileData._fileTable + textOffset;
-		uint32 pos = 0;
-		int size;
-		while (pos + textOffset < fileData._size) {
+
+		byte *setStringOffsets = fileData._fileTable;
+		const int kSetStringValues = 2000;
+		int setStringOffsetsArray[kSetStringValues];
+		int setStringIdArray[kSetStringValues];
+		for (int i = 0; i < kSetStringValues; i++) {
+			setStringOffsetsArray[i] = READ_LE_UINT32(setStringOffsets);
+			setStringIdArray[i] = 0;
+			setStringOffsets += 4;
+		}
+
+		int id = 1;
+		int diff = 0;
+		const int kTextOffset = 8000;
+		byte *talkTxt = fileData._fileTable + kTextOffset;
+		byte *endOfTalkTxt = fileData._fileTable + fileData._size;
+		while (talkTxt < endOfTalkTxt) {
+			diff = talkTxt - fileData._fileTable;
+			for (int i = 0; i < kSetStringValues; i++) {
+				if (setStringOffsetsArray[i] == diff) {
+					setStringIdArray[i] = id;
+				}
+			}
 			if (*talkTxt == 0xFF) {
-				size = talkTxtWithDialog(talkTxt);
-				talkTxt += size;
-				pos += size;
+				talkTxt = talkTxtWithDialog(talkTxt);
 			} else {
-				size = talkTxtNoDialog(talkTxt);
-				talkTxt += size;
-				pos += size;
+				talkTxt = talkTxtNoDialog(talkTxt);
 			}
+			id++;
 		}
 		free(fileData._fileTable);
 		_fFiles.close();
 		printf("talktxt.txt - done\n");
+
+		// Additional id data for texts
+		_outputPath.setFullName("talktxt_ids.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create talktxt_ids.txt");
+		}
+		_fFiles.print("talktxt_ids\n");
+		for (int i = 0; i < kSetStringValues; i++) {
+			_fFiles.print("%d\n", setStringIdArray[i]);
+		}
+		_fFiles.close();
+		printf("talktxt_ids.txt - done\n");
 	}
 }
 
-int ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
+byte *ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
 	byte *mainString;
 	byte *dialogBoxAddr[32];
 	byte *dialogOptAddr[32];
 	byte c;
 	std::string lineString;
-	int size = 0;
 
 	byte *stringCurrOff = talkTxt;
 	stringCurrOff++;
-	size++;
 	int32 adressOfFirstSequence = (int)READ_LE_UINT16(stringCurrOff);
 	mainString = talkTxt + adressOfFirstSequence;
 	stringCurrOff += 2;
-	size += 2;
 
 	for (int i = 0; i < 32; i++) {
 		dialogBoxAddr[i] = 0;
@@ -367,39 +410,32 @@ int ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
 	int dialogBox = 0;
 	while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
 		stringCurrOff += 2;
-		size += 2;
 		if (off) {
 			line = talkTxt + off;
+			dialogBoxAddr[dialogBox] = line;
+			dialogBox++;
 		}
-		dialogBoxAddr[dialogBox] = line;
-		dialogBox++;
 	}
 	stringCurrOff += 2;
-	size += 2;
 
 	int dialogOpt = 0;
 	while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
 		stringCurrOff += 2;
-		size += 2;
 		if (off) {
 			line = talkTxt + off;
+			dialogOptAddr[dialogOpt] = line;
+			dialogOpt++;
 		}
-		dialogOptAddr[dialogOpt] = line;
-		dialogOpt++;
 	}
-	size += 2;
 
 	_fFiles.print("@DIALOGBOX_LINES:\n");
 	while ((c = *mainString) != 255) {
 		if (printSpecialDialogData(c)) {
 			mainString++;
-			size++;
-			_fFiles.print("%c\n", (*mainString) + 48);
+			_fFiles.print("%d\n", *mainString);
 		}
 		mainString++;
-		size++;
 	}
-	size++;
 	_fFiles.print("#END\n");
 			
 	for (int i = 0; i < dialogBox; i++) {
@@ -407,7 +443,6 @@ int ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
 		while ((c = *dialogBoxAddr[i]) != 255) {
 			_fFiles.print("$%d\n", *dialogBoxAddr[i]);
 			dialogBoxAddr[i]++;
-			size++;
 			lineString.clear();
 			while ((c = *dialogBoxAddr[i])) {
 				c = correctPolishLetter(c);
@@ -415,51 +450,50 @@ int ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
 					c = '|';
 				}
 				dialogBoxAddr[i]++;
-				size++;
 				lineString += c;
 			}
 			dialogBoxAddr[i]++;
-			size++;
 			_fFiles.print("%s\n", lineString.c_str());
 		}
-		size++;
 		_fFiles.print("#END\n");
 	}
 
 	for (int i = 0; i < dialogOpt; i++) {
 		_fFiles.print("@DIALOG_OPT %d\n", i);
+		byte lastC = 0;
 		while ((c = *dialogOptAddr[i]) != 255) {
-			if (printSpecialDialogData(c)) {
-				dialogOptAddr[i]++;
-				size++;
-				_fFiles.print("%c\n", (*dialogOptAddr[i]) + 48);
+			// WALKAROUND: fix for unnecessery '0' after PAUSE
+			// and double #HERO
+			if ((lastC != 254 || c != 0) && (lastC != 1 || c != 1)) {
+				if (printSpecialDialogData(c)) {
+					dialogOptAddr[i]++;
+					_fFiles.print("%d\n", *dialogOptAddr[i]);
+				}
 			}
+			lastC = c;
 			dialogOptAddr[i]++;
-			size++;
 		}
-		size++;
 		_fFiles.print("#END\n");
 	}
 	_fFiles.print("#ENDEND\n");
-	return size;
+	talkTxt = dialogOptAddr[dialogOpt - 1];
+	talkTxt++;
+	return talkTxt;
 }
 
-int ExtractPrince::talkTxtNoDialog(byte *talkTxt) {
+byte *ExtractPrince::talkTxtNoDialog(byte *talkTxt) {
 	byte c;
-	int size = 0;
 	_fFiles.print("@NORMAL_LINES:\n");
 	while ((c = *talkTxt) != 255) {
 		if (printSpecialDialogData(c)) {
 			talkTxt++;
-			size++;
-			_fFiles.print("%c\n", (*talkTxt) + 48);
+			_fFiles.print("%d\n", *talkTxt);
 		}
 		talkTxt++;
-		size++;
 	}
-	size++;
 	_fFiles.print("#END\n");
-	return size;
+	talkTxt++;
+	return talkTxt;
 }
 
 // Returns 'true' if next char is a value for 'enable option', 
diff --git a/engines/prince/extract_prince.h b/engines/prince/extract_prince.h
index 47292bb..4d39306 100644
--- a/engines/prince/extract_prince.h
+++ b/engines/prince/extract_prince.h
@@ -55,8 +55,8 @@ protected:
 	void exportVariaTxt(FileData fileData);
 	void exportInvTxt(FileData fileData);
 	void exportTalkTxt(FileData fileData);
-	int talkTxtWithDialog(byte *talkTxt);
-	int talkTxtNoDialog(byte *talkTxt);
+	byte *talkTxtWithDialog(byte *talkTxt);
+	byte *talkTxtNoDialog(byte *talkTxt);
 	bool printSpecialDialogData(byte c);
 
 	Common::Array<FileEntry> _items;


Commit: 4e1ad68ab967e923dc43fd17103cd8814efa09b7
    https://github.com/scummvm/scummvm-tools/commit/4e1ad68ab967e923dc43fd17103cd8814efa09b7
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-25T06:02:11+02:00

Commit Message:
PRINCE: Text packing tool for translation purposes

Changed paths:
  A engines/prince/pack_prince.cpp
  A engines/prince/pack_prince.h
    tools.cpp



diff --git a/engines/prince/pack_prince.cpp b/engines/prince/pack_prince.cpp
new file mode 100644
index 0000000..13ecd6d
--- /dev/null
+++ b/engines/prince/pack_prince.cpp
@@ -0,0 +1,870 @@
+/* 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 <string.h>
+#include "pack_prince.h"
+#include "common\endian.h"
+
+PackPrince::PackPrince(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
+	ToolInput input;
+	input.format = "/";
+	_inputPaths.push_back(input);
+
+	_outputToDirectory = true;
+
+	_shorthelp = "Used to repackage The Prince and the Coward text data for translation.";
+	_helptext = "\nUsage: " + getName() + " [-o /path/to/output/dir/] /path/to/inputfiles\n";
+}
+
+void PackPrince::execute() {
+	Common::Filename mainDir = _inputPaths[0].path;
+	// We always need to setup default output path, since there is no obligation to specify it
+	if (_outputPath.empty()) {
+		_outputPath.setFullPath("./");
+	}
+
+	printf("Packing The Prince and the Coward text data... \n");
+
+	mainDir.setFullName("variatxt.txt");
+	_databank.open(mainDir, "rb");
+	if (!_databank.isOpen()) {
+		error("Unable to open variatxt.txt");
+	}
+	packVariaTxt();
+	_databank.close();
+
+	mainDir.setFullName("invtxt.txt");
+	_databank.open(mainDir, "rb");
+	if (!_databank.isOpen()) {
+		error("Unable to open invtxt.txt");
+	}
+	packInvTxt();
+	_databank.close();
+
+	mainDir.setFullName("talktxt.txt");
+	_databank.open(mainDir, "rb");
+	if (!_databank.isOpen()) {
+		error("Unable to open talktxt.txt");
+	}
+	packTalkTxt();
+	_databank.close();
+
+	mainDir.setFullName("mob.txt");
+	_databank.open(mainDir, "rb");
+	if (!_databank.isOpen()) {
+		error("Unable to open mob.txt");
+	}
+	packMobs();
+	_databank.close();
+}
+
+// TODO
+InspectionMatch PackPrince::inspectInput(const Common::Filename &filename) {
+	/*
+	std::string file = filename.getFullName();
+	if (scumm_stricmp(file.c_str(), "databank.ptc") == 0) {
+		return IMATCH_PERFECT;
+	}
+	return IMATCH_AWFUL;
+	*/
+	return IMATCH_PERFECT;
+}
+
+void PackPrince::packVariaTxt() {
+	_outputPath.setFullName("variatxt_translate.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create variatxt_translate.dat");
+	}
+	// File size
+	uint32 fileSize = _databank.size();
+
+	// Header test
+	byte c;
+	std::string name, examTxt;
+	while ((c = _databank.readByte()) != '\r') {
+		name += c;
+	}
+	if (name.compare("variatxt.dat")) {
+		error("Wrong header in variatxt.txt");
+	}
+	
+	// Skip comment until first number
+	while ((c = _databank.readByte()) != '\r');
+	_databank.readByte(); // skip '\n'
+	
+	// Loading to array:
+	const int variaTxtSize = 6000;
+	Common::Array<VariaTxt> variaTxtList; // list of all txt
+	VariaTxt newVariaTxt; // temp varia txt
+	newVariaTxt._txt = "";
+	for (int i = 0; i < variaTxtSize; i++) {
+		variaTxtList.push_back(newVariaTxt);
+	}
+
+	while (1) {
+		// Id:
+		int id = 0;
+		while ((c = _databank.readByte()) != '.') {
+			id *= 10;
+			id += c - 48;
+		}
+		_databank.readByte(); // skip space
+
+		// Text:
+		newVariaTxt._txt.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			c = correctPolishLetter(c); // temporary
+			if (c == '|') {
+				c = 10;
+			}
+			newVariaTxt._txt += c;
+		}
+
+		// Set VariaTxt in array
+		variaTxtList[id]._txt = newVariaTxt._txt;
+
+		// Skip '\n' and test eof
+		_databank.readByte(); 
+		if (_databank.pos() == fileSize) {
+			break;
+		}
+	}
+	
+	int textOffset = variaTxtSize * 4;
+	// Offset counting and packing:
+	for (int i = 0; i < variaTxtSize; i++) {
+		if (variaTxtList[i]._txt.size()) {
+			_fFiles.writeUint32LE(textOffset);
+			textOffset += variaTxtList[i]._txt.size() + 3;
+		} else {
+			_fFiles.writeUint32LE(0);
+		}
+	}
+	for (uint i = 0; i < variaTxtList.size(); i++) {
+		if (variaTxtList[i]._txt.size()) {
+			_fFiles.writeByte(1);
+			for (uint j = 0; j < variaTxtList[i]._txt.size(); j++) {
+				_fFiles.writeByte(variaTxtList[i]._txt[j]);
+			}
+			_fFiles.writeByte(0);
+			_fFiles.writeByte(255);
+		}
+	}
+	_fFiles.close();
+}
+
+void PackPrince::packInvTxt() {
+	_outputPath.setFullName("invtxt_translate.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create invtxt_translate.dat");
+	}
+
+	// File size
+	uint32 fileSize = _databank.size();
+
+	// Header test
+	byte c;
+	std::string name, examTxt;
+	while ((c = _databank.readByte()) != '\r') {
+		name += c;
+	}
+	if (name.compare("invtxt.dat")) {
+		error("Wrong header in invtxt.txt");
+	}
+	
+	// Skip comments until first inventory item nr
+	while ((c = _databank.readByte()) != '0');
+	
+	// Skip first dot and space
+	_databank.readByte();
+	_databank.readByte();
+
+	// Loading to an array:
+	const int kItems = 100;
+	Common::Array<InvTxt> invTxtList; // list of all invTxt
+	InvTxt newInvTxt; // temp invTxt
+	for (int i = 0; i < kItems; i++) {
+		invTxtList.push_back(newInvTxt);
+	}
+
+	int id = 0;
+	while (1) {
+		newInvTxt._name.clear();
+		newInvTxt._examTxt.clear();
+		// Name:
+		while ((c = _databank.readByte()) != '-') {
+			c = correctPolishLetter(c); // temporary
+			newInvTxt._name += c;
+		}
+		newInvTxt._name.pop_back(); // remove first space
+		_databank.readByte(); // skip second space
+
+		// Exam text:
+		while ((c = _databank.readByte()) != '\r') {
+			c = correctPolishLetter(c); // temporary
+			if (c == '|') {
+				c = 10;
+			}
+			newInvTxt._examTxt += c;
+		}
+
+		// Add new item to list
+		invTxtList[id] = newInvTxt;
+
+		// Skip '\n' and test eof
+		_databank.readByte(); 
+		if (_databank.pos() == fileSize) {
+			break;
+		} else {
+			while ((c = _databank.readByte()) != ' '); // skip item nr, space and dot
+		}
+		id++;
+	}
+	
+	// Offset counting and packing:
+	int nameOffset = kItems * 4 * 2;
+	for (uint i = 0; i < kItems; i++) {
+		if (invTxtList[i]._name.size()) {
+			int examTextOffset = nameOffset + invTxtList[i]._name.size() + 1;
+			_fFiles.writeUint32LE(nameOffset);
+			_fFiles.writeUint32LE(examTextOffset);
+			nameOffset += invTxtList[i]._name.size() + invTxtList[i]._examTxt.size() + 2;
+		} else {
+			_fFiles.writeUint32LE(0);
+			_fFiles.writeUint32LE(0);
+		}
+	}
+	for (uint32 i = 0; i < invTxtList.size(); i++) {
+		if (invTxtList[i]._name.size()) {
+			// Names
+			for (uint j = 0; j < invTxtList[i]._name.size(); j++) {
+				_fFiles.writeByte(invTxtList[i]._name[j]);
+			}
+			_fFiles.writeByte(0);
+			// Exam texts
+			for (uint j = 0; j < invTxtList[i]._examTxt.size(); j++) {
+				_fFiles.writeByte(invTxtList[i]._examTxt[j]);
+			}
+			_fFiles.writeByte(0);
+		}
+	}
+	_fFiles.close();
+}
+
+void PackPrince::packTalkTxt() {
+	_outputPath.setFullName("talktxt_translate.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create talktxt_translate.dat");
+	}
+
+	// IDs array for first 2000 offsets calculation
+	const int kSetStringValues = 2000;
+	int setStringIdArray[kSetStringValues];
+	Common::Filename mainDir = _inputPaths[0].path;
+	Common::File idsFile;
+	mainDir.setFullName("talktxt_ids.txt");
+	idsFile.open(mainDir, "rb");
+	if (!idsFile.isOpen()) {
+		error("Unable to open talktxt_ids.txt");
+	}
+
+	// Header test
+	byte c;
+	std::string line;
+	while ((c = idsFile.readByte()) != '\r') {
+		line += c;
+	}
+	if (line.compare("talktxt_ids")) {
+		error("Wrong header in talktxt_ids.txt");
+	}
+	idsFile.readByte(); // skip '\n'
+
+	// IDs loading
+	for (int i = 0; i < kSetStringValues; i++) {
+		int value = 0;
+		while ((c = idsFile.readByte()) != '\r') {
+			value *= 10;
+			value += c - 48;
+		}
+		idsFile.readByte(); // skip '\n'
+		setStringIdArray[i] = value;
+	}
+	idsFile.close();
+
+	// Main file
+	// File size
+	uint32 fileSize = _databank.size();
+
+	// Header test
+	line.clear();
+	while ((c = _databank.readByte()) != '\r') {
+		line += c;
+	}
+	if (line.compare("talktxt.dat")) {
+		error("Wrong header in talktxt.txt");
+	}
+	_databank.readByte(); // skip '\n'
+	
+	// TODO - temp, to put main offsets here
+	for (int i = 0; i < kSetStringValues; i++) {
+		_fFiles.writeUint32LE(0);
+	}
+
+	int id = 1;
+	int setStringOffsetsArray[kSetStringValues];
+	for (int i = 0; i < kSetStringValues; i++) {
+		setStringOffsetsArray[i] = 0;
+	}
+
+	while (1) {
+		line.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			line += c;
+		}
+		_databank.readByte(); // skip '\n'
+
+		for (int i = 0; i < kSetStringValues; i++) {
+			if (id == setStringIdArray[i]) {
+				setStringOffsetsArray[i] = _fFiles.pos();
+			}
+		}
+
+		if (!line.compare("@DIALOGBOX_LINES:")) {
+			talkTxtWithDialog();
+		} else if (!line.compare("@NORMAL_LINES:")) {
+			talkTxtNoDialog();
+		}
+
+		id++;
+
+		if (_databank.pos() == fileSize) {
+			break;
+		}
+	}
+
+	// Back to start of file for offsets setting
+	_fFiles.seek(0, SEEK_SET);
+	for (int i = 0; i < kSetStringValues; i++) {
+		_fFiles.writeUint32LE(setStringOffsetsArray[i]);
+	}
+
+	_fFiles.close();
+}
+
+void PackPrince::talkTxtWithDialog() {
+	byte c;
+	std::string line;
+	Common::Array<TalkBeforeBox> beforeDialogBoxArray;
+	Common::Array<Common::Array<TalkBeforeBox>> allDialogBoxesArray;
+	Common::Array<Common::Array<TalkBeforeBox>> allDialogOptionsArray;
+
+	// Intro talk before dialog box:
+	TalkBeforeBox tempTalkBeforeBox;
+	while (1) {
+		// Special dialog data
+		line.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			line += c;
+		}
+		_databank.readByte(); // skip '\n'
+
+		if (!line.compare("#HERO")) {
+			tempTalkBeforeBox._dialogData = 1;
+		} else if (!line.compare("#OTHER")) {
+			tempTalkBeforeBox._dialogData = 4;
+		} else if (!line.compare("#OTHER2")) {
+			tempTalkBeforeBox._dialogData = 5;
+		} else if (!line.compare("#PAUSE")) {
+			tempTalkBeforeBox._dialogData = 254;
+			tempTalkBeforeBox._txt.clear();
+			beforeDialogBoxArray.push_back(tempTalkBeforeBox);
+			continue;
+		} else if (!line.compare("#BOX 0")) {
+			while (_databank.readByte() != '\n'); // skip #END
+			break;
+		}
+
+		// Line of text
+		tempTalkBeforeBox._txt.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			c = correctPolishLetter(c); // temporary
+			if (c == '|') {
+				c = 10;
+			}
+			tempTalkBeforeBox._txt += c;
+		}
+		c = 0;
+		tempTalkBeforeBox._txt += c;
+		_databank.readByte(); // skip '\n'
+
+		beforeDialogBoxArray.push_back(tempTalkBeforeBox);
+	}
+
+	// All dialog boxes:
+	int dbNr = 0;
+	Common::Array<TalkBeforeBox> tempDialogBoxArray;
+	TalkBeforeBox tempDialogBoxLine;
+
+	while (1) {
+		// Check if @DIALOG_BOX
+		line.clear();
+		while ((c = _databank.readByte()) != ' ') {
+			line += c;
+		}
+		while (_databank.readByte() != '\n'); // skip " %d\r\n"
+		if (line.compare("@DIALOG_BOX")) {
+			break;
+		}
+
+		tempDialogBoxArray.clear();
+		allDialogBoxesArray.push_back(tempDialogBoxArray);
+	
+		// Lines of dialog box
+		while (1) {
+			// Skip $, check if #END
+			c = _databank.readByte();
+			if (c == '#') {
+				while (_databank.readByte() != '\n'); // skip "END\r\n"
+				break;
+			}
+
+			// Text number
+			int textNr = 0;
+			while ((c = _databank.readByte()) != '\r') {
+				textNr *= 10;
+				textNr += c - 48;
+			}
+			tempDialogBoxLine._dialogData = textNr;
+			_databank.readByte(); // skip '\n'
+
+			// Line of text
+			tempDialogBoxLine._txt.clear();
+			while ((c = _databank.readByte()) != '\r') {
+				c = correctPolishLetter(c); // temporary
+				if (c == '|') {
+					c = 10;
+				}
+				tempDialogBoxLine._txt += c;
+			}
+			c = 0;
+			tempDialogBoxLine._txt += c;
+			_databank.readByte(); // skip '\n'
+
+			allDialogBoxesArray[dbNr].push_back(tempDialogBoxLine);
+		}
+
+		dbNr++;
+	}
+
+	// All dialog options:
+	int dbOptNr = 0;
+	Common::Array<TalkBeforeBox> tempDialogOptionsArray;
+	TalkBeforeBox tempDialogOptionsLine;
+
+	while (1) {
+		tempDialogOptionsArray.clear();
+		allDialogOptionsArray.push_back(tempDialogOptionsArray);
+	
+		// Lines of dialog opt
+		while (1) {
+			// Special dialog data
+			line.clear();
+			while ((c = _databank.readByte()) != '\r' && c != ' ') {
+				line += c;
+			}
+			// Check if #END
+			if (!line.compare("#END")) {
+				_databank.readByte(); // skip '\n'
+				break;
+			}
+			if (!line.compare("#HERO")) {
+				tempDialogOptionsLine._dialogData = 1;
+			} else if (!line.compare("#OTHER")) {
+				tempDialogOptionsLine._dialogData = 4;
+			} else if (!line.compare("#OTHER2")) {
+				tempDialogOptionsLine._dialogData = 5;
+			} else if (!line.compare("#PAUSE")) {
+				tempDialogOptionsLine._dialogData = 254;
+				tempDialogOptionsLine._txt.clear();
+				_databank.readByte(); // skip '\n'
+				allDialogOptionsArray[dbOptNr].push_back(tempDialogOptionsLine);
+				continue;
+			} else {
+				if (!line.compare("#ENABLE")) { // 0 - 15
+					tempDialogOptionsLine._dialogData = 240;
+					uint8 value = 0;
+					while ((c = _databank.readByte()) != '\r') {
+						value *= 10;
+						value += c - 48;
+					}
+					tempDialogOptionsLine._txt.clear();
+					tempDialogOptionsLine._txt += value;
+				} else {
+					if (!line.compare("#DISABLE")) { // 1
+						tempDialogOptionsLine._dialogData = 241;
+					} else if (!line.compare("#BOX")) { // 0, 1, 2, 3, 4
+						tempDialogOptionsLine._dialogData = 242;
+					} else if (!line.compare("#EXIT")) { // 0, 1, 2, 3, 4
+						tempDialogOptionsLine._dialogData = 243;
+					} else if (!line.compare("#FLAG")) { // 1
+						tempDialogOptionsLine._dialogData = 244;
+					}
+					tempDialogOptionsLine._txt.clear();
+					tempDialogOptionsLine._txt += _databank.readByte() - 48;
+					_databank.readByte(); // skip '\r'
+				}
+				_databank.readByte(); // skip '\n'
+				allDialogOptionsArray[dbOptNr].push_back(tempDialogOptionsLine);
+				continue;
+			}
+
+			_databank.readByte(); // skip '\n'
+
+			// Line of text
+			tempDialogOptionsLine._txt.clear();
+			while ((c = _databank.readByte()) != '\r') {
+				c = correctPolishLetter(c); // temporary
+				if (c == '|') {
+					c = 10;
+				}
+				tempDialogOptionsLine._txt += c;
+			}
+			c = 0;
+			tempDialogOptionsLine._txt += c;
+			_databank.readByte(); // skip '\n'
+			allDialogOptionsArray[dbOptNr].push_back(tempDialogOptionsLine);
+		}
+		dbOptNr++;
+		// Check if #ENDEND, skip @DIALOG_OPT %d
+		line.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			line += c;
+		}
+		_databank.readByte(); // skip '\n'
+		if (!line.compare("#ENDEND")) {
+			break;
+		}
+	}
+
+	// Offset counting and packing:
+	_fFiles.writeByte(255); // show that this is dialog box
+	
+	// Offset of init dialog texts
+	int offset = 3 + allDialogBoxesArray.size() * 2 + 2 + allDialogOptionsArray.size() * 2 + 2;
+	_fFiles.writeUint16LE(offset); 
+	for (uint i = 0; i < beforeDialogBoxArray.size(); i++) {
+		offset += beforeDialogBoxArray[i]._txt.size() + 1; // data and text
+	}
+	offset += 3; // always BOX 0 and 255 at the end
+	
+	// Dialog boxes texts offsets:
+	for (uint i = 0; i < allDialogBoxesArray.size(); i++) {
+		_fFiles.writeUint16LE(offset);
+		for (uint j = 0; j < allDialogBoxesArray[i].size(); j++) {
+			offset += allDialogBoxesArray[i][j]._txt.size() + 1; // data and text
+		}
+		offset++; // 255 at the end
+	}
+	_fFiles.writeByte(255);
+	_fFiles.writeByte(255);
+	// Dialog opts texts offsets:
+	for (uint i = 0; i < allDialogOptionsArray.size(); i++) {
+		_fFiles.writeUint16LE(offset);
+		for (uint j = 0; j < allDialogOptionsArray[i].size(); j++) {
+			offset += allDialogOptionsArray[i][j]._txt.size() + 1;
+		}
+		offset++; // 255 at the end
+	}
+	_fFiles.writeByte(255);
+	_fFiles.writeByte(255);
+
+	// Init texts:
+	for (uint i = 0; i < beforeDialogBoxArray.size(); i++) {
+		_fFiles.writeByte(beforeDialogBoxArray[i]._dialogData);
+		for (uint j = 0; j < beforeDialogBoxArray[i]._txt.size(); j++) {
+			_fFiles.writeByte(beforeDialogBoxArray[i]._txt[j]);
+		}
+	}
+	_fFiles.writeByte(242);
+	_fFiles.writeByte(0);
+	_fFiles.writeByte(255);
+
+	// Dialog boxes:
+	for (uint i = 0; i < allDialogBoxesArray.size(); i++) {
+		for (uint j = 0; j < allDialogBoxesArray[i].size(); j++) {
+			_fFiles.writeByte(allDialogBoxesArray[i][j]._dialogData);
+			for (uint k = 0; k < allDialogBoxesArray[i][j]._txt.size(); k++) {
+				_fFiles.writeByte(allDialogBoxesArray[i][j]._txt[k]);
+			}
+		}
+		_fFiles.writeByte(255);
+	}
+
+	// Dialog opts:
+	for (uint i = 0; i < allDialogOptionsArray.size(); i++) {
+		for (uint j = 0; j < allDialogOptionsArray[i].size(); j++) {
+			_fFiles.writeByte(allDialogOptionsArray[i][j]._dialogData);
+			for (uint k = 0; k < allDialogOptionsArray[i][j]._txt.size(); k++) {
+				_fFiles.writeByte(allDialogOptionsArray[i][j]._txt[k]);
+			}
+		}
+		_fFiles.writeByte(255);
+	}
+}
+
+void PackPrince::talkTxtNoDialog() {
+	byte c;
+	std::string line;
+	Common::Array<TalkBeforeBox> normalLinesArray;
+	TalkBeforeBox tempNormalLine;
+	while (1) {
+		// Special dialog data
+		line.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			line += c;
+		}
+		_databank.readByte(); // skip '\n'
+
+		if (!line.compare("#HERO")) {
+			tempNormalLine._dialogData = 1;
+		} else if (!line.compare("#OTHER")) {
+			tempNormalLine._dialogData = 4;
+		} else if (!line.compare("#OTHER2")) {
+			tempNormalLine._dialogData = 5;
+		} else if (!line.compare("#PAUSE")) {
+			tempNormalLine._dialogData = 254;
+			tempNormalLine._txt.clear();
+			normalLinesArray.push_back(tempNormalLine);
+			continue;
+		} else if (!line.compare("#END")) {
+			break;
+		}
+
+		// Line of text
+		tempNormalLine._txt.clear();
+		while ((c = _databank.readByte()) != '\r') {
+			c = correctPolishLetter(c); // temporary
+			if (c == '|') {
+				c = 10;
+			}
+			tempNormalLine._txt += c;
+		}
+		c = 0;
+		tempNormalLine._txt += c;
+		_databank.readByte(); // skip '\n'
+
+		normalLinesArray.push_back(tempNormalLine);
+	}
+
+	// Offset counting and packing:
+	for (uint i = 0; i < normalLinesArray.size(); i++) {
+		_fFiles.writeByte(normalLinesArray[i]._dialogData);
+		for (uint j = 0; j < normalLinesArray[i]._txt.size(); j++) {
+			_fFiles.writeByte(normalLinesArray[i]._txt[j]);
+		}
+	}
+	_fFiles.writeByte(255);
+}
+
+void PackPrince::packMobs() {
+	_outputPath.setFullName("mob_translate.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create mob_translate.dat");
+	}
+
+	// File size
+	uint32 fileSize = _databank.size();
+
+	// Header test
+	byte c;
+	std::string name, examTxt;
+	while ((c = _databank.readByte()) != '\r') {
+		name += c;
+	}
+	if (name.compare("mob.lst")) {
+		error("Wrong header in mob.txt");
+	}
+	_databank.readByte(); // skip '\n'
+	
+	// Skip comment until first location nr
+	while ((c = _databank.readByte()) != '\n');
+
+	// Loading to an array:
+	Common::Array<Common::Array<Mob>> allLocations; // array of locations of all Mobs
+	Common::Array<Mob> tempLocation; // temp array of Mobs in one location
+	Mob newMob; // temp Mob
+	const int kLocations = 61; // max nr of location
+	int nr = 0; // number of current location
+
+	for (int i = 0; i < kLocations; i++) {
+		allLocations.push_back(tempLocation);
+	}
+
+	while (1) {
+		newMob._name.clear();
+		newMob._examTxt.clear();
+
+		// Test if end of location - next number
+		if ((c = _databank.readByte()) > 47 && c < 58) {
+			// Set location nr:
+			nr = c - 48;
+			while ((c = _databank.readByte()) != '.') {
+				nr *= 10;
+				nr += c - 48;
+			}
+			nr--;
+			_databank.readByte(); // skip '\r'
+			_databank.readByte(); // skip '\n'
+		} else {
+			c = correctPolishLetter(c); // temporary
+			newMob._name += c; // first letter of name
+		}
+
+		// Test for eof
+		if (_databank.pos() == fileSize) {
+			break;
+		}
+
+		// No mobs in this location
+		if ((c = _databank.readByte()) > 47 && c < 58) {
+			_databank.seek(-1, SEEK_CUR);
+			continue;
+		} else {
+			c = correctPolishLetter(c); // temporary
+			newMob._name += c;
+		}
+
+		// Name:
+		while ((c = _databank.readByte()) != '-') {
+			c = correctPolishLetter(c); // temporary
+			newMob._name += c;
+		}
+		newMob._name.pop_back(); // remove first space
+		_databank.readByte(); // skip second space
+
+		// Exam text:
+		while ((c = _databank.readByte()) != '\r') {
+			c = correctPolishLetter(c); // temporary
+			if (c == '|') {
+				c = 10;
+			}
+			if (c == '*') {
+				c = 254;
+			}
+			if (c == '+') {
+				c = 0;
+				newMob._examTxt += c;
+				c = 1;
+			}
+			newMob._examTxt += c;
+		}
+
+		// Skip '\n'
+		_databank.readByte();
+
+		// Add new item to list
+		allLocations[nr].push_back(newMob);
+	}
+	// Offset counting and packing:
+	int locationOffset = allLocations.size() * 2;
+	for (uint i = 0; i < allLocations.size(); i++) {
+		if (allLocations[i].size()) {
+			_fFiles.writeUint16LE(locationOffset);
+			for (uint j = 0; j < allLocations[i].size(); j++) {
+				locationOffset += allLocations[i][j]._name.size() + allLocations[i][j]._examTxt.size() + 5;
+			}
+		} else {
+			_fFiles.writeUint16LE(0);
+		}
+	}
+	for (uint i = 0; i < allLocations.size(); i++) {
+		for (uint j = 0; j < allLocations[i].size(); j++) {
+			_fFiles.writeByte(1);
+			for (uint k = 0; k < allLocations[i][j]._name.size(); k++) {
+				_fFiles.writeByte(allLocations[i][j]._name[k]);
+			}
+			_fFiles.writeByte(0);
+			_fFiles.writeByte(1);
+			for (uint k = 0; k < allLocations[i][j]._examTxt.size(); k++) {
+				_fFiles.writeByte(allLocations[i][j]._examTxt[k]);			
+			}
+			_fFiles.writeByte(0);
+			_fFiles.writeByte(255);
+		}
+	}
+	_fFiles.close();
+}
+
+// Conversion from Windows-1250 to Mazovia
+// temporary for not complete translation
+char PackPrince::correctPolishLetter(char c) {
+	switch (c) {
+	case '\xB9':
+		return '\x86';
+	case '\xB3':
+		return '\x92';
+	case '\x9C':
+		return '\x9E';
+	case '\xE6':
+		return '\x8D';
+	case '\xF1':
+		return '\xA4';
+	case '\x9F':
+		return '\xA6';
+	case '\xEA':
+		return '\x91';
+	case '\xF3':
+		return '\xA2';
+	case '\xBF':	
+		return '\xA7';
+	case '\xA5':
+		return '\x8F';
+	case '\xA3':
+		return '\x9C';
+	case '\x8C':
+		return '\x98';
+	case '\xC6':
+		return '\x95';
+	case '\xD1':	
+		return '\xA5';
+	case '\x8F':
+		return '\xA0';
+	case '\xCA':	
+		return '\x90';
+	case '\xD3':
+		return '\xA3';
+	case '\xAF':	
+		return '\xA1';
+	default:
+		return c;
+	}
+}
+
+#ifdef STANDALONE_MAIN
+int main(int argc, char *argv[]) {
+	ExtractCge cge(argv[0]);
+	return cge.run(argc, argv);
+}
+#endif
diff --git a/engines/prince/pack_prince.h b/engines/prince/pack_prince.h
new file mode 100644
index 0000000..72c4db5
--- /dev/null
+++ b/engines/prince/pack_prince.h
@@ -0,0 +1,67 @@
+/* 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 PACK_PRINCE_H
+#define PACK_PRINCE_H
+
+#include "tool.h"
+#include "common\array.h"
+
+class PackPrince : public Tool {
+public:
+	PackPrince(const std::string &name = "pack_prince");
+	
+	virtual void execute();
+	
+	virtual InspectionMatch inspectInput(const Common::Filename &filename);
+	
+protected:
+	struct InvTxt {
+		std::string _name;
+		std::string _examTxt;
+	};
+
+	struct VariaTxt {
+		std::string _txt;
+	};
+
+	struct Mob {
+		std::string _name;
+		std::string _examTxt;
+	};
+
+	struct TalkBeforeBox {
+		int _dialogData;
+		std::string _txt;
+	};
+
+	void packMobs();
+	void packVariaTxt();
+	void packInvTxt();
+	void packTalkTxt();
+	char correctPolishLetter(char c);
+	void talkTxtWithDialog();
+	void talkTxtNoDialog();
+
+	Common::File _databank, _fFiles;
+};
+
+#endif
diff --git a/tools.cpp b/tools.cpp
index 6ea6644..4c4d8ea 100644
--- a/tools.cpp
+++ b/tools.cpp
@@ -53,6 +53,7 @@
 #include "engines/gob/extract_fascination_cd.h"
 #include "engines/kyra/extract_kyra.h"
 #include "engines/prince/extract_prince.h"
+#include "engines/prince/pack_prince.h"
 #include "engines/scumm/extract_loom_tg16.h"
 #include "engines/scumm/extract_mm_apple.h"
 #include "engines/scumm/extract_mm_c64.h"
@@ -91,6 +92,7 @@ Tools::Tools() {
 	_tools.push_back(new ExtractFascinationCD());
 	_tools.push_back(new ExtractKyra());
 	_tools.push_back(new ExtractPrince());
+	_tools.push_back(new PackPrince());
 	_tools.push_back(new ExtractLoomTG16());
 	_tools.push_back(new ExtractMMApple());
 	_tools.push_back(new ExtractMMC64());


Commit: 00f618f29821c58ae65f56c6172d00a6a88b0af4
    https://github.com/scummvm/scummvm-tools/commit/00f618f29821c58ae65f56c6172d00a6a88b0af4
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-25T16:07:39+02:00

Commit Message:
PRINCE: Update of extracting and packing tool for credits file

Changed paths:
    engines/prince/extract_prince.cpp
    engines/prince/extract_prince.h
    engines/prince/pack_prince.cpp
    engines/prince/pack_prince.h



diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
index 2339e2d..bf6a804 100644
--- a/engines/prince/extract_prince.cpp
+++ b/engines/prince/extract_prince.cpp
@@ -68,6 +68,9 @@ void ExtractPrince::execute() {
 		if (!scumm_stricmp(_items[i]._name.c_str(), "talktxt.dat")) {
 			exportTalkTxt(loadFile(i));
 		}
+		if (!scumm_stricmp(_items[i]._name.c_str(), "credits.dat")) {
+			exportCredits(loadFile(i));
+		}
 	}
 	free(fileTable);
 	_databank.close();
@@ -329,6 +332,39 @@ void ExtractPrince::exportInvTxt(FileData fileData) {
 	}
 }
 
+void ExtractPrince::exportCredits(FileData fileData) {
+	if (fileData._fileTable != nullptr) {
+		_outputPath.setFullName("credits.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create credits.txt");
+		}
+		_fFiles.print("credits.dat\n");
+		byte c;
+		byte lastC = 10;
+		byte *creditsTxt = fileData._fileTable;
+		byte *end = fileData._fileTable + fileData._size;
+		while (creditsTxt != end) {
+			c = *creditsTxt;
+			if (c == 10) {
+				_fFiles.print("@\n");
+			}
+			if (c != 13 && c != 10) {
+				c = correctPolishLetter(c);
+				_fFiles.print("%c", c);
+			}
+			if (lastC != 10 && c == 13) {
+				_fFiles.print("\n");
+			}
+			lastC = c;
+			creditsTxt++;
+		}
+		free(fileData._fileTable);
+		_fFiles.close();
+		printf("credits.txt - done\n");
+	}
+}
+
 void ExtractPrince::exportTalkTxt(FileData fileData) {
 	if (fileData._fileTable != nullptr) {
 		_outputPath.setFullName("talktxt.txt");
diff --git a/engines/prince/extract_prince.h b/engines/prince/extract_prince.h
index 4d39306..c16b5be 100644
--- a/engines/prince/extract_prince.h
+++ b/engines/prince/extract_prince.h
@@ -54,6 +54,7 @@ protected:
 	void exportMobs(FileData fileData);
 	void exportVariaTxt(FileData fileData);
 	void exportInvTxt(FileData fileData);
+	void exportCredits(FileData fileData);
 	void exportTalkTxt(FileData fileData);
 	byte *talkTxtWithDialog(byte *talkTxt);
 	byte *talkTxtNoDialog(byte *talkTxt);
diff --git a/engines/prince/pack_prince.cpp b/engines/prince/pack_prince.cpp
index 13ecd6d..ec52c0c 100644
--- a/engines/prince/pack_prince.cpp
+++ b/engines/prince/pack_prince.cpp
@@ -74,6 +74,14 @@ void PackPrince::execute() {
 	}
 	packMobs();
 	_databank.close();
+
+	mainDir.setFullName("credits.txt");
+	_databank.open(mainDir, "rb");
+	if (!_databank.isOpen()) {
+		error("Unable to open credits.txt");
+	}
+	packCredits();
+	_databank.close();
 }
 
 // TODO
@@ -271,6 +279,45 @@ void PackPrince::packInvTxt() {
 	_fFiles.close();
 }
 
+void PackPrince::packCredits() {
+	_outputPath.setFullName("credits_translate.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create credits_translate.dat");
+	}
+
+	// File size
+	uint32 fileSize = _databank.size();
+
+	// Header test
+	byte c;
+	std::string line;
+	while ((c = _databank.readByte()) != '\r') {
+		line += c;
+	}
+	if (line.compare("credits.dat")) {
+		error("Wrong header in credits.txt");
+	}
+	_databank.readByte(); // skip '\n'
+
+	while (1) {
+		c = _databank.readByte();
+		if (c != 13 && c != 10) {
+			if (c == '@') {
+				_fFiles.writeByte(13);
+				_fFiles.writeByte(10);
+			} else {
+				c = correctPolishLetter(c);
+				_fFiles.writeByte(c);
+			}
+		}
+		if (_databank.pos() == fileSize) {
+			break;
+		}
+	}
+	_fFiles.close();
+}
+
 void PackPrince::packTalkTxt() {
 	_outputPath.setFullName("talktxt_translate.dat");
 	_fFiles.open(_outputPath, "wb");
diff --git a/engines/prince/pack_prince.h b/engines/prince/pack_prince.h
index 72c4db5..b9b4b17 100644
--- a/engines/prince/pack_prince.h
+++ b/engines/prince/pack_prince.h
@@ -56,6 +56,7 @@ protected:
 	void packMobs();
 	void packVariaTxt();
 	void packInvTxt();
+	void packCredits();
 	void packTalkTxt();
 	char correctPolishLetter(char c);
 	void talkTxtWithDialog();


Commit: d24638c0998a2d7f0e5c3a28c1a80995f2ba6b88
    https://github.com/scummvm/scummvm-tools/commit/d24638c0998a2d7f0e5c3a28c1a80995f2ba6b88
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-26T02:14:21+02:00

Commit Message:
PRINCE: Packing tool - pack all previous files to one main translation file - prince_translation.dat

Changed paths:
    engines/prince/pack_prince.cpp
    engines/prince/pack_prince.h



diff --git a/engines/prince/pack_prince.cpp b/engines/prince/pack_prince.cpp
index ec52c0c..3f8ac24 100644
--- a/engines/prince/pack_prince.cpp
+++ b/engines/prince/pack_prince.cpp
@@ -41,47 +41,92 @@ void PackPrince::execute() {
 		_outputPath.setFullPath("./");
 	}
 
+	_outputPath.setFullName("prince_translation.dat");
+	_fFiles.open(_outputPath, "wb");
+	if (!_fFiles.isOpen()) {
+		error("Unable to create prince_translation.dat");
+	}
+
+	// Export names of files
+	_fFiles.print("variatxt_translate.dat\n");
+	_fFiles.print("invtxt_translate.dat\n");
+	_fFiles.print("talktxt_translate.dat\n");
+	_fFiles.print("mob_translate.dat\n");
+	_fFiles.print("credits_translate.dat\n");
+
+
+	// Export files infomation
+	int posOfFilesInformation = _fFiles.pos();
+	FileEntry filesInfo[5];
+	int fileNr = 0;
+	for (int i = 0; i < 5; i++) {
+		_fFiles.writeUint32LE(0); // place for files offsets
+		_fFiles.writeUint32LE(0); // and size of files
+	}
+
 	printf("Packing The Prince and the Coward text data... \n");
 
+	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("variatxt.txt");
 	_databank.open(mainDir, "rb");
 	if (!_databank.isOpen()) {
 		error("Unable to open variatxt.txt");
 	}
 	packVariaTxt();
+	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
+	fileNr++;
 	_databank.close();
 
+	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("invtxt.txt");
 	_databank.open(mainDir, "rb");
 	if (!_databank.isOpen()) {
 		error("Unable to open invtxt.txt");
 	}
 	packInvTxt();
+	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
+	fileNr++;
 	_databank.close();
 
+	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("talktxt.txt");
 	_databank.open(mainDir, "rb");
 	if (!_databank.isOpen()) {
 		error("Unable to open talktxt.txt");
 	}
 	packTalkTxt();
+	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
+	fileNr++;
 	_databank.close();
 
+	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("mob.txt");
 	_databank.open(mainDir, "rb");
 	if (!_databank.isOpen()) {
 		error("Unable to open mob.txt");
 	}
 	packMobs();
+	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
+	fileNr++;
 	_databank.close();
 
+	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("credits.txt");
 	_databank.open(mainDir, "rb");
 	if (!_databank.isOpen()) {
 		error("Unable to open credits.txt");
 	}
 	packCredits();
+	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
+	fileNr++;
 	_databank.close();
+
+	_fFiles.seek(posOfFilesInformation, SEEK_SET);
+	for (int i = 0; i < fileNr; i++) {
+		_fFiles.writeUint32LE(filesInfo[i]._offset);
+		_fFiles.writeUint32LE(filesInfo[i]._size);
+	}
+	_fFiles.close();
 }
 
 // TODO
@@ -97,11 +142,6 @@ InspectionMatch PackPrince::inspectInput(const Common::Filename &filename) {
 }
 
 void PackPrince::packVariaTxt() {
-	_outputPath.setFullName("variatxt_translate.dat");
-	_fFiles.open(_outputPath, "wb");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create variatxt_translate.dat");
-	}
 	// File size
 	uint32 fileSize = _databank.size();
 
@@ -177,16 +217,9 @@ void PackPrince::packVariaTxt() {
 			_fFiles.writeByte(255);
 		}
 	}
-	_fFiles.close();
 }
 
 void PackPrince::packInvTxt() {
-	_outputPath.setFullName("invtxt_translate.dat");
-	_fFiles.open(_outputPath, "wb");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create invtxt_translate.dat");
-	}
-
 	// File size
 	uint32 fileSize = _databank.size();
 
@@ -276,16 +309,9 @@ void PackPrince::packInvTxt() {
 			_fFiles.writeByte(0);
 		}
 	}
-	_fFiles.close();
 }
 
 void PackPrince::packCredits() {
-	_outputPath.setFullName("credits_translate.dat");
-	_fFiles.open(_outputPath, "wb");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create credits_translate.dat");
-	}
-
 	// File size
 	uint32 fileSize = _databank.size();
 
@@ -315,16 +341,9 @@ void PackPrince::packCredits() {
 			break;
 		}
 	}
-	_fFiles.close();
 }
 
 void PackPrince::packTalkTxt() {
-	_outputPath.setFullName("talktxt_translate.dat");
-	_fFiles.open(_outputPath, "wb");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create talktxt_translate.dat");
-	}
-
 	// IDs array for first 2000 offsets calculation
 	const int kSetStringValues = 2000;
 	int setStringIdArray[kSetStringValues];
@@ -372,6 +391,9 @@ void PackPrince::packTalkTxt() {
 		error("Wrong header in talktxt.txt");
 	}
 	_databank.readByte(); // skip '\n'
+
+	// Start pos of talkTxt file for later offset setting
+	int startTalkTxtPos = _fFiles.pos();
 	
 	// TODO - temp, to put main offsets here
 	for (int i = 0; i < kSetStringValues; i++) {
@@ -393,7 +415,7 @@ void PackPrince::packTalkTxt() {
 
 		for (int i = 0; i < kSetStringValues; i++) {
 			if (id == setStringIdArray[i]) {
-				setStringOffsetsArray[i] = _fFiles.pos();
+				setStringOffsetsArray[i] = _fFiles.pos() - startTalkTxtPos;
 			}
 		}
 
@@ -409,14 +431,17 @@ void PackPrince::packTalkTxt() {
 			break;
 		}
 	}
+	// End of talkTxt file
+	int endTalkTxtPos = _fFiles.pos();
 
-	// Back to start of file for offsets setting
-	_fFiles.seek(0, SEEK_SET);
+	// Back to start of talkTxt file for offsets setting
+	_fFiles.seek(startTalkTxtPos, SEEK_SET);
 	for (int i = 0; i < kSetStringValues; i++) {
 		_fFiles.writeUint32LE(setStringOffsetsArray[i]);
 	}
 
-	_fFiles.close();
+	// Back to the end of talkTxt file
+	_fFiles.seek(endTalkTxtPos, SEEK_SET);
 }
 
 void PackPrince::talkTxtWithDialog() {
@@ -735,12 +760,6 @@ void PackPrince::talkTxtNoDialog() {
 }
 
 void PackPrince::packMobs() {
-	_outputPath.setFullName("mob_translate.dat");
-	_fFiles.open(_outputPath, "wb");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create mob_translate.dat");
-	}
-
 	// File size
 	uint32 fileSize = _databank.size();
 
@@ -754,7 +773,7 @@ void PackPrince::packMobs() {
 		error("Wrong header in mob.txt");
 	}
 	_databank.readByte(); // skip '\n'
-	
+
 	// Skip comment until first location nr
 	while ((c = _databank.readByte()) != '\n');
 
@@ -861,7 +880,6 @@ void PackPrince::packMobs() {
 			_fFiles.writeByte(255);
 		}
 	}
-	_fFiles.close();
 }
 
 // Conversion from Windows-1250 to Mazovia
diff --git a/engines/prince/pack_prince.h b/engines/prince/pack_prince.h
index b9b4b17..9ae8d85 100644
--- a/engines/prince/pack_prince.h
+++ b/engines/prince/pack_prince.h
@@ -34,6 +34,11 @@ public:
 	virtual InspectionMatch inspectInput(const Common::Filename &filename);
 	
 protected:
+	struct FileEntry {
+		uint32 _offset;
+		uint32 _size;
+	};
+
 	struct InvTxt {
 		std::string _name;
 		std::string _examTxt;


Commit: 061fa53d4c63187c3519cdd8c0fb11aae30bc8c6
    https://github.com/scummvm/scummvm-tools/commit/061fa53d4c63187c3519cdd8c0fb11aae30bc8c6
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-26T17:27:51+01:00

Commit Message:
PRINCE: Extraction and packing tool - rename some variables, add more printfs during packing, update comments

Changed paths:
    engines/prince/extract_prince.cpp
    engines/prince/pack_prince.cpp
    engines/prince/pack_prince.h



diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
index bf6a804..1c919a1 100644
--- a/engines/prince/extract_prince.cpp
+++ b/engines/prince/extract_prince.cpp
@@ -125,9 +125,6 @@ byte *ExtractPrince::openDatabank() {
 	uint32 fileTableOffset = _databank.readUint32LE() ^ 0x4D4F4B2D; // MOK-
 	uint32 fileTableSize = _databank.readUint32LE() ^ 0x534F4654; // SOFT
 
-	//printf("fileTableOffset : %08X\n", fileTableOffset);
-	//printf("fileTableSize: %08X\n", fileTableSize);
-
 	_databank.seek(fileTableOffset, SEEK_SET);
 
 	byte *fileTable = (byte *)malloc(fileTableSize);
@@ -141,7 +138,6 @@ byte *ExtractPrince::openDatabank() {
 		item._name = (const char *)fileItem;
 		item._offset = READ_LE_UINT32(fileItem + 24);
 		item._size = READ_LE_UINT32(fileItem + 28);
-		//printf("%12s %8X %d\n", (const char *)fileItem, item._offset, item._size);
 		_items.push_back(item);
 	}
 	return fileTable;
@@ -259,8 +255,8 @@ void ExtractPrince::exportVariaTxt(FileData fileData) {
 			error("Unable to create variatxt.txt");
 		}
 		_fFiles.print("variatxt.dat\nstringId. string\n");
-		const int variaTxtSize = 6000;
-		for (int stringId = 0; stringId < variaTxtSize; stringId++) {
+		const int kVariaTxtSize = 6000;
+		for (int stringId = 0; stringId < kVariaTxtSize; stringId++) {
 			uint32 stringOffset = READ_LE_UINT32(fileData._fileTable + stringId * 4);
 			if (stringOffset > fileData._size) {
 				assert(false);
@@ -269,7 +265,7 @@ void ExtractPrince::exportVariaTxt(FileData fileData) {
 			byte c;
 			byte *txtPointer = fileData._fileTable + stringOffset;
 			variaTxtString.clear();
-			txtPointer++; // TODO -  remove this in packing tool
+			txtPointer++;
 			while ((c = *txtPointer)) {
 				c = correctPolishLetter(c);
 				if (c == 10) {
diff --git a/engines/prince/pack_prince.cpp b/engines/prince/pack_prince.cpp
index 3f8ac24..6fc783e 100644
--- a/engines/prince/pack_prince.cpp
+++ b/engines/prince/pack_prince.cpp
@@ -64,7 +64,7 @@ void PackPrince::execute() {
 		_fFiles.writeUint32LE(0); // and size of files
 	}
 
-	printf("Packing The Prince and the Coward text data... \n");
+	printf("Packing The Prince and the Coward text data...\n");
 
 	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("variatxt.txt");
@@ -76,6 +76,7 @@ void PackPrince::execute() {
 	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
 	fileNr++;
 	_databank.close();
+	printf("variatxt_translate.dat - done\n");
 
 	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("invtxt.txt");
@@ -87,6 +88,7 @@ void PackPrince::execute() {
 	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
 	fileNr++;
 	_databank.close();
+	printf("invtxt_translate.dat - done\n");
 
 	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("talktxt.txt");
@@ -98,6 +100,7 @@ void PackPrince::execute() {
 	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
 	fileNr++;
 	_databank.close();
+	printf("talktxt_translate.dat - done\n");
 
 	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("mob.txt");
@@ -109,6 +112,7 @@ void PackPrince::execute() {
 	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
 	fileNr++;
 	_databank.close();
+	printf("mob_translate.dat - done\n");
 
 	filesInfo[fileNr]._offset = _fFiles.pos();
 	mainDir.setFullName("credits.txt");
@@ -120,25 +124,17 @@ void PackPrince::execute() {
 	filesInfo[fileNr]._size = _fFiles.pos() - filesInfo[fileNr]._offset;
 	fileNr++;
 	_databank.close();
+	printf("credits_translate.dat - done\n");
 
+	// Files offset and size setting
 	_fFiles.seek(posOfFilesInformation, SEEK_SET);
 	for (int i = 0; i < fileNr; i++) {
 		_fFiles.writeUint32LE(filesInfo[i]._offset);
 		_fFiles.writeUint32LE(filesInfo[i]._size);
 	}
 	_fFiles.close();
-}
-
-// TODO
-InspectionMatch PackPrince::inspectInput(const Common::Filename &filename) {
-	/*
-	std::string file = filename.getFullName();
-	if (scumm_stricmp(file.c_str(), "databank.ptc") == 0) {
-		return IMATCH_PERFECT;
-	}
-	return IMATCH_AWFUL;
-	*/
-	return IMATCH_PERFECT;
+	printf("All done!\n");
+	printf("File is created in %s\n", _outputPath.getFullPath().c_str());
 }
 
 void PackPrince::packVariaTxt() {
@@ -160,11 +156,11 @@ void PackPrince::packVariaTxt() {
 	_databank.readByte(); // skip '\n'
 	
 	// Loading to array:
-	const int variaTxtSize = 6000;
+	const int kVariaTxtSize = 6000;
 	Common::Array<VariaTxt> variaTxtList; // list of all txt
 	VariaTxt newVariaTxt; // temp varia txt
 	newVariaTxt._txt = "";
-	for (int i = 0; i < variaTxtSize; i++) {
+	for (int i = 0; i < kVariaTxtSize; i++) {
 		variaTxtList.push_back(newVariaTxt);
 	}
 
@@ -197,9 +193,9 @@ void PackPrince::packVariaTxt() {
 		}
 	}
 	
-	int textOffset = variaTxtSize * 4;
+	int textOffset = kVariaTxtSize * 4;
 	// Offset counting and packing:
-	for (int i = 0; i < variaTxtSize; i++) {
+	for (int i = 0; i < kVariaTxtSize; i++) {
 		if (variaTxtList[i]._txt.size()) {
 			_fFiles.writeUint32LE(textOffset);
 			textOffset += variaTxtList[i]._txt.size() + 3;
@@ -326,6 +322,7 @@ void PackPrince::packCredits() {
 	}
 	_databank.readByte(); // skip '\n'
 
+	// Packing:
 	while (1) {
 		c = _databank.readByte();
 		if (c != 13 && c != 10) {
@@ -395,7 +392,7 @@ void PackPrince::packTalkTxt() {
 	// Start pos of talkTxt file for later offset setting
 	int startTalkTxtPos = _fFiles.pos();
 	
-	// TODO - temp, to put main offsets here
+	// Making space for main offsets
 	for (int i = 0; i < kSetStringValues; i++) {
 		_fFiles.writeUint32LE(0);
 	}
@@ -447,12 +444,12 @@ void PackPrince::packTalkTxt() {
 void PackPrince::talkTxtWithDialog() {
 	byte c;
 	std::string line;
-	Common::Array<TalkBeforeBox> beforeDialogBoxArray;
-	Common::Array<Common::Array<TalkBeforeBox>> allDialogBoxesArray;
-	Common::Array<Common::Array<TalkBeforeBox>> allDialogOptionsArray;
+	Common::Array<TalkTxt> beforeDialogBoxArray;
+	Common::Array<Common::Array<TalkTxt>> allDialogBoxesArray;
+	Common::Array<Common::Array<TalkTxt>> allDialogOptionsArray;
 
 	// Intro talk before dialog box:
-	TalkBeforeBox tempTalkBeforeBox;
+	TalkTxt tempTalkBeforeBox;
 	while (1) {
 		// Special dialog data
 		line.clear();
@@ -495,8 +492,8 @@ void PackPrince::talkTxtWithDialog() {
 
 	// All dialog boxes:
 	int dbNr = 0;
-	Common::Array<TalkBeforeBox> tempDialogBoxArray;
-	TalkBeforeBox tempDialogBoxLine;
+	Common::Array<TalkTxt> tempDialogBoxArray;
+	TalkTxt tempDialogBoxLine;
 
 	while (1) {
 		// Check if @DIALOG_BOX
@@ -551,8 +548,8 @@ void PackPrince::talkTxtWithDialog() {
 
 	// All dialog options:
 	int dbOptNr = 0;
-	Common::Array<TalkBeforeBox> tempDialogOptionsArray;
-	TalkBeforeBox tempDialogOptionsLine;
+	Common::Array<TalkTxt> tempDialogOptionsArray;
+	TalkTxt tempDialogOptionsLine;
 
 	while (1) {
 		tempDialogOptionsArray.clear();
@@ -708,8 +705,8 @@ void PackPrince::talkTxtWithDialog() {
 void PackPrince::talkTxtNoDialog() {
 	byte c;
 	std::string line;
-	Common::Array<TalkBeforeBox> normalLinesArray;
-	TalkBeforeBox tempNormalLine;
+	Common::Array<TalkTxt> normalLinesArray;
+	TalkTxt tempNormalLine;
 	while (1) {
 		// Special dialog data
 		line.clear();
diff --git a/engines/prince/pack_prince.h b/engines/prince/pack_prince.h
index 9ae8d85..3c168e8 100644
--- a/engines/prince/pack_prince.h
+++ b/engines/prince/pack_prince.h
@@ -28,11 +28,9 @@
 class PackPrince : public Tool {
 public:
 	PackPrince(const std::string &name = "pack_prince");
-	
+
 	virtual void execute();
-	
-	virtual InspectionMatch inspectInput(const Common::Filename &filename);
-	
+
 protected:
 	struct FileEntry {
 		uint32 _offset;
@@ -53,7 +51,7 @@ protected:
 		std::string _examTxt;
 	};
 
-	struct TalkBeforeBox {
+	struct TalkTxt {
 		int _dialogData;
 		std::string _txt;
 	};


Commit: 9b0be70fc1aa655858c6274e9f388478b16882a1
    https://github.com/scummvm/scummvm-tools/commit/9b0be70fc1aa655858c6274e9f388478b16882a1
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-27T15:31:05+01:00

Commit Message:
PRINCE: Extraction tool - allow to extract texts from DE data

Fix for different mob data location - in DE version all of them are in main databank.ptc

Changed paths:
    engines/prince/extract_prince.cpp



diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
index 1c919a1..45c06f7 100644
--- a/engines/prince/extract_prince.cpp
+++ b/engines/prince/extract_prince.cpp
@@ -58,6 +58,7 @@ void ExtractPrince::execute() {
 		error("Unable to open all/databank.ptc");
 	}
 	byte *fileTable = openDatabank();
+	bool mobsDE = false;
 	for (size_t i = 0; i < _items.size(); i++) {
 		if (!scumm_stricmp(_items[i]._name.c_str(), "variatxt.dat")) {
 			exportVariaTxt(loadFile(i));
@@ -71,45 +72,71 @@ void ExtractPrince::execute() {
 		if (!scumm_stricmp(_items[i]._name.c_str(), "credits.dat")) {
 			exportCredits(loadFile(i));
 		}
+		if (!scumm_stricmp(_items[i]._name.c_str(), "mob01.lst")) {
+			// For DE game data
+			mobsDE = true;
+			_outputPath.setFullName("mob.txt");
+			_fFiles.open(_outputPath, "w");
+			if (!_fFiles.isOpen()) {
+				error("Unable to create mob.txt");
+			}
+			_fFiles.print("mob.lst\nmob_name - exam text\n");
+			int loc = 0;
+			for (int j = 1; j <= kNumberOfLocations; j++) {
+				_fFiles.print("%d.\n", j);
+				// no databanks for loc 44 and 45
+				if (j != 44 && j != 45) {
+					exportMobs(loadFile(i + loc));
+					loc++;
+				}
+			}
+			printf("mob.txt - done\n");
+			printf("All done!\n");
+			free(pathBuffer);
+			_fFiles.close();
+		}
 	}
 	free(fileTable);
 	_databank.close();
 	_items.clear();
 
-	_outputPath.setFullName("mob.txt");
-	_fFiles.open(_outputPath, "w");
-	if (!_fFiles.isOpen()) {
-		error("Unable to create mob.txt");
-	}
-	_fFiles.print("mob.lst\nmob_name - exam text\n");
-	for (int loc = 1; loc <= kNumberOfLocations; loc++) {
-		_fFiles.print("%d.\n", loc);
-		// no databanks for loc 44 and 45
-		if (loc != 44 && loc != 45) {
-			std::string fullName = mainDir.getFullPath();
-			sprintf(pathBuffer, "%02d/databank.ptc", loc);
-			fullName += pathBuffer;
-			Common::Filename filename(fullName);
-			_databank.open(filename, "rb");
-			if (!_databank.isOpen()) {
-				_fFiles.close();
-				error("Unable to open %02d/databank.ptc", loc);
-			}
-			byte *fileTable = openDatabank();
-			for (size_t i = 0; i < _items.size(); i++) {
-				if (!scumm_stricmp(_items[i]._name.c_str(), "mob.lst")) {
-					exportMobs(loadFile(i));
+	// For PL game data
+	if (!mobsDE) {
+		_outputPath.setFullName("mob.txt");
+		_fFiles.open(_outputPath, "w");
+		if (!_fFiles.isOpen()) {
+			error("Unable to create mob.txt");
+		}
+		_fFiles.print("mob.lst\nmob_name - exam text\n");
+		for (int loc = 1; loc <= kNumberOfLocations; loc++) {
+			_fFiles.print("%d.\n", loc);
+			// no databanks for loc 44 and 45
+			if (loc != 44 && loc != 45) {
+				std::string fullName = mainDir.getFullPath();
+				sprintf(pathBuffer, "%02d/databank.ptc", loc);
+				fullName += pathBuffer;
+				Common::Filename filename(fullName);
+				_databank.open(filename, "rb");
+				if (!_databank.isOpen()) {
+					_fFiles.close();
+					error("Unable to open %02d/databank.ptc", loc);
 				}
+				byte *fileTable = openDatabank();
+				for (size_t i = 0; i < _items.size(); i++) {
+					if (!scumm_stricmp(_items[i]._name.c_str(), "mob.lst")) {
+						exportMobs(loadFile(i));
+					}
+				}
+				free(fileTable);
+				_databank.close();
+				_items.clear();
 			}
-			free(fileTable);
-			_databank.close();
-			_items.clear();
 		}
+		printf("mob.txt - done\n");
+		printf("All done!\n");
+		free(pathBuffer);
+		_fFiles.close();
 	}
-	printf("mob.txt - done\n");
-	printf("All done!\n");
-	free(pathBuffer);
-	_fFiles.close();
 }
 
 InspectionMatch ExtractPrince::inspectInput(const Common::Filename &filename) {


Commit: 43fce1314d757224ec0cd5aa66f55ff726f96ec3
    https://github.com/scummvm/scummvm-tools/commit/43fce1314d757224ec0cd5aa66f55ff726f96ec3
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-28T16:26:19+01:00

Commit Message:
PRINCE: Fix compilation on gcc, silence warnings

Changed paths:
    Makefile.common
    engines/prince/extract_prince.cpp
    engines/prince/extract_prince.h
    engines/prince/pack_prince.cpp
    engines/prince/pack_prince.h



diff --git a/Makefile.common b/Makefile.common
index 81d9f10..b6ba5ef 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -197,6 +197,8 @@ tools_OBJS := \
 	engines/cruise/extract_cruise_pc.o \
 	engines/gob/extract_gob_stk.o \
 	engines/kyra/extract_kyra.o \
+	engines/prince/extract_prince.o \
+	engines/prince/pack_prince.o \
 	engines/parallaction/extract_parallaction.o \
 	engines/scumm/extract_loom_tg16.o \
 	engines/scumm/extract_mm_apple.o \
diff --git a/engines/prince/extract_prince.cpp b/engines/prince/extract_prince.cpp
index 45c06f7..5fd49ab 100644
--- a/engines/prince/extract_prince.cpp
+++ b/engines/prince/extract_prince.cpp
@@ -21,7 +21,7 @@
 
 #include <string.h>
 #include "extract_prince.h"
-#include "common\endian.h"
+#include "common/endian.h"
 
 struct FileData;
 
@@ -112,16 +112,16 @@ void ExtractPrince::execute() {
 			_fFiles.print("%d.\n", loc);
 			// no databanks for loc 44 and 45
 			if (loc != 44 && loc != 45) {
-				std::string fullName = mainDir.getFullPath();
+				fullName = mainDir.getFullPath();
 				sprintf(pathBuffer, "%02d/databank.ptc", loc);
 				fullName += pathBuffer;
-				Common::Filename filename(fullName);
+				filename = Common::Filename(fullName);
 				_databank.open(filename, "rb");
 				if (!_databank.isOpen()) {
 					_fFiles.close();
 					error("Unable to open %02d/databank.ptc", loc);
 				}
-				byte *fileTable = openDatabank();
+				fileTable = openDatabank();
 				for (size_t i = 0; i < _items.size(); i++) {
 					if (!scumm_stricmp(_items[i]._name.c_str(), "mob.lst")) {
 						exportMobs(loadFile(i));
@@ -182,7 +182,7 @@ void ExtractPrince::decrypt(byte *buffer, uint32 size) {
 
 ExtractPrince::FileData ExtractPrince::loadFile(int itemIndex) {
 	FileData fileData;
-	fileData._fileTable = nullptr;
+	fileData._fileTable = 0;
 	fileData._size = 0;
 
 	const FileEntry &entryHeader = _items[itemIndex];
@@ -212,7 +212,7 @@ ExtractPrince::FileData ExtractPrince::loadFile(int itemIndex) {
 }
 
 void ExtractPrince::exportMobs(FileData fileData) {
-	if (fileData._fileTable != nullptr) {
+	if (fileData._fileTable != 0) {
 		const int kMobsStructSize = 32;
 		const int kMobsTextOffsetsPos = 24;
 		int streamPos = 0;
@@ -275,7 +275,7 @@ void ExtractPrince::exportMobs(FileData fileData) {
 }
 
 void ExtractPrince::exportVariaTxt(FileData fileData) {
-	if (fileData._fileTable != nullptr) {
+	if (fileData._fileTable != 0) {
 		_outputPath.setFullName("variatxt.txt");
 		_fFiles.open(_outputPath, "w");
 		if (!_fFiles.isOpen()) {
@@ -312,7 +312,7 @@ void ExtractPrince::exportVariaTxt(FileData fileData) {
 }
 
 void ExtractPrince::exportInvTxt(FileData fileData) {
-	if (fileData._fileTable != nullptr) {
+	if (fileData._fileTable != 0) {
 		std::string itemName, itemExamText;
 		const int kItems = 100;
 		_outputPath.setFullName("invtxt.txt");
@@ -356,7 +356,7 @@ void ExtractPrince::exportInvTxt(FileData fileData) {
 }
 
 void ExtractPrince::exportCredits(FileData fileData) {
-	if (fileData._fileTable != nullptr) {
+	if (fileData._fileTable != 0) {
 		_outputPath.setFullName("credits.txt");
 		_fFiles.open(_outputPath, "w");
 		if (!_fFiles.isOpen()) {
@@ -389,7 +389,7 @@ void ExtractPrince::exportCredits(FileData fileData) {
 }
 
 void ExtractPrince::exportTalkTxt(FileData fileData) {
-	if (fileData._fileTable != nullptr) {
+	if (fileData._fileTable != 0) {
 		_outputPath.setFullName("talktxt.txt");
 		_fFiles.open(_outputPath, "w");
 		if (!_fFiles.isOpen()) {
@@ -464,7 +464,7 @@ byte *ExtractPrince::talkTxtWithDialog(byte *talkTxt) {
 	}
 
 	int16 off;
-	byte *line = nullptr;
+	byte *line = 0;
 
 	int dialogBox = 0;
 	while ((off = (int)READ_LE_UINT16(stringCurrOff)) != -1) {
@@ -788,7 +788,7 @@ int Decompressor::getBit() {
 
 #ifdef STANDALONE_MAIN
 int main(int argc, char *argv[]) {
-	ExtractCge cge(argv[0]);
-	return cge.run(argc, argv);
+	ExtractPrince prince(argv[0]);
+	return prince.run(argc, argv);
 }
 #endif
diff --git a/engines/prince/extract_prince.h b/engines/prince/extract_prince.h
index c16b5be..8d677ec 100644
--- a/engines/prince/extract_prince.h
+++ b/engines/prince/extract_prince.h
@@ -23,7 +23,7 @@
 #define EXTRACT_PRINCE_H
 
 #include "tool.h"
-#include "common\array.h"
+#include "common/array.h"
 
 class ExtractPrince : public Tool {
 public:
diff --git a/engines/prince/pack_prince.cpp b/engines/prince/pack_prince.cpp
index 6fc783e..f1547f7 100644
--- a/engines/prince/pack_prince.cpp
+++ b/engines/prince/pack_prince.cpp
@@ -21,7 +21,7 @@
 
 #include <string.h>
 #include "pack_prince.h"
-#include "common\endian.h"
+#include "common/endian.h"
 
 PackPrince::PackPrince(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
 	ToolInput input;
@@ -139,7 +139,7 @@ void PackPrince::execute() {
 
 void PackPrince::packVariaTxt() {
 	// File size
-	uint32 fileSize = _databank.size();
+	uint fileSize = _databank.size();
 
 	// Header test
 	byte c;
@@ -188,7 +188,7 @@ void PackPrince::packVariaTxt() {
 
 		// Skip '\n' and test eof
 		_databank.readByte(); 
-		if (_databank.pos() == fileSize) {
+		if ((uint)_databank.pos() == fileSize) {
 			break;
 		}
 	}
@@ -217,7 +217,7 @@ void PackPrince::packVariaTxt() {
 
 void PackPrince::packInvTxt() {
 	// File size
-	uint32 fileSize = _databank.size();
+	uint fileSize = _databank.size();
 
 	// Header test
 	byte c;
@@ -253,7 +253,7 @@ void PackPrince::packInvTxt() {
 			c = correctPolishLetter(c); // temporary
 			newInvTxt._name += c;
 		}
-		newInvTxt._name.pop_back(); // remove first space
+		newInvTxt._name.erase(newInvTxt._name.size() - 1); // remove first space
 		_databank.readByte(); // skip second space
 
 		// Exam text:
@@ -270,7 +270,7 @@ void PackPrince::packInvTxt() {
 
 		// Skip '\n' and test eof
 		_databank.readByte(); 
-		if (_databank.pos() == fileSize) {
+		if ((uint)_databank.pos() == fileSize) {
 			break;
 		} else {
 			while ((c = _databank.readByte()) != ' '); // skip item nr, space and dot
@@ -280,7 +280,7 @@ void PackPrince::packInvTxt() {
 	
 	// Offset counting and packing:
 	int nameOffset = kItems * 4 * 2;
-	for (uint i = 0; i < kItems; i++) {
+	for (int i = 0; i < kItems; i++) {
 		if (invTxtList[i]._name.size()) {
 			int examTextOffset = nameOffset + invTxtList[i]._name.size() + 1;
 			_fFiles.writeUint32LE(nameOffset);
@@ -291,7 +291,7 @@ void PackPrince::packInvTxt() {
 			_fFiles.writeUint32LE(0);
 		}
 	}
-	for (uint32 i = 0; i < invTxtList.size(); i++) {
+	for (uint i = 0; i < invTxtList.size(); i++) {
 		if (invTxtList[i]._name.size()) {
 			// Names
 			for (uint j = 0; j < invTxtList[i]._name.size(); j++) {
@@ -309,7 +309,7 @@ void PackPrince::packInvTxt() {
 
 void PackPrince::packCredits() {
 	// File size
-	uint32 fileSize = _databank.size();
+	uint fileSize = _databank.size();
 
 	// Header test
 	byte c;
@@ -334,7 +334,7 @@ void PackPrince::packCredits() {
 				_fFiles.writeByte(c);
 			}
 		}
-		if (_databank.pos() == fileSize) {
+		if ((uint)_databank.pos() == fileSize) {
 			break;
 		}
 	}
@@ -377,7 +377,7 @@ void PackPrince::packTalkTxt() {
 
 	// Main file
 	// File size
-	uint32 fileSize = _databank.size();
+	uint fileSize = _databank.size();
 
 	// Header test
 	line.clear();
@@ -424,7 +424,7 @@ void PackPrince::packTalkTxt() {
 
 		id++;
 
-		if (_databank.pos() == fileSize) {
+		if ((uint)_databank.pos() == fileSize) {
 			break;
 		}
 	}
@@ -445,8 +445,8 @@ void PackPrince::talkTxtWithDialog() {
 	byte c;
 	std::string line;
 	Common::Array<TalkTxt> beforeDialogBoxArray;
-	Common::Array<Common::Array<TalkTxt>> allDialogBoxesArray;
-	Common::Array<Common::Array<TalkTxt>> allDialogOptionsArray;
+	Common::Array<Common::Array<TalkTxt> > allDialogBoxesArray;
+	Common::Array<Common::Array<TalkTxt> > allDialogOptionsArray;
 
 	// Intro talk before dialog box:
 	TalkTxt tempTalkBeforeBox;
@@ -758,7 +758,7 @@ void PackPrince::talkTxtNoDialog() {
 
 void PackPrince::packMobs() {
 	// File size
-	uint32 fileSize = _databank.size();
+	uint fileSize = _databank.size();
 
 	// Header test
 	byte c;
@@ -775,7 +775,7 @@ void PackPrince::packMobs() {
 	while ((c = _databank.readByte()) != '\n');
 
 	// Loading to an array:
-	Common::Array<Common::Array<Mob>> allLocations; // array of locations of all Mobs
+	Common::Array<Common::Array<Mob> > allLocations; // array of locations of all Mobs
 	Common::Array<Mob> tempLocation; // temp array of Mobs in one location
 	Mob newMob; // temp Mob
 	const int kLocations = 61; // max nr of location
@@ -806,7 +806,7 @@ void PackPrince::packMobs() {
 		}
 
 		// Test for eof
-		if (_databank.pos() == fileSize) {
+		if ((uint)_databank.pos() == fileSize) {
 			break;
 		}
 
@@ -824,7 +824,7 @@ void PackPrince::packMobs() {
 			c = correctPolishLetter(c); // temporary
 			newMob._name += c;
 		}
-		newMob._name.pop_back(); // remove first space
+		newMob._name.erase(newMob._name.size() - 1);  // remove first space
 		_databank.readByte(); // skip second space
 
 		// Exam text:
@@ -926,7 +926,7 @@ char PackPrince::correctPolishLetter(char c) {
 
 #ifdef STANDALONE_MAIN
 int main(int argc, char *argv[]) {
-	ExtractCge cge(argv[0]);
-	return cge.run(argc, argv);
+	PackPrince prince(argv[0]);
+	return prince.run(argc, argv);
 }
 #endif
diff --git a/engines/prince/pack_prince.h b/engines/prince/pack_prince.h
index 3c168e8..b55b7d7 100644
--- a/engines/prince/pack_prince.h
+++ b/engines/prince/pack_prince.h
@@ -23,7 +23,7 @@
 #define PACK_PRINCE_H
 
 #include "tool.h"
-#include "common\array.h"
+#include "common/array.h"
 
 class PackPrince : public Tool {
 public:


Commit: 8b268067afda915f5ac2bd8d9f0d8e5951bbbcc9
    https://github.com/scummvm/scummvm-tools/commit/8b268067afda915f5ac2bd8d9f0d8e5951bbbcc9
Author: lukaslw (lukaslw at gmail.com)
Date: 2014-10-28T18:40:19+01:00

Commit Message:
PRINCE: Add extract/pack tools in MSVC10 build files

Changed paths:
    dists/msvc10/toolscli.vcxproj
    dists/msvc10/toolscli.vcxproj.filters



diff --git a/dists/msvc10/toolscli.vcxproj b/dists/msvc10/toolscli.vcxproj
index 616616d..ebecc74 100644
--- a/dists/msvc10/toolscli.vcxproj
+++ b/dists/msvc10/toolscli.vcxproj
@@ -97,6 +97,8 @@
     <ClCompile Include="..\..\engines\gob\compress_gob.cpp" />
     <ClCompile Include="..\..\engines\gob\extract_fascination_cd.cpp" />
     <ClCompile Include="..\..\engines\kyra\compress_kyra.cpp" />
+    <ClCompile Include="..\..\engines\prince\extract_prince.cpp" />
+    <ClCompile Include="..\..\engines\prince\pack_prince.cpp" />
     <ClCompile Include="..\..\engines\queen\compress_queen.cpp" />
     <ClCompile Include="..\..\engines\saga\compress_saga.cpp" />
     <ClCompile Include="..\..\engines\sci\compress_sci.cpp" />
@@ -144,6 +146,8 @@
     <ClInclude Include="..\..\engines\gob\compress_gob.h" />
     <ClInclude Include="..\..\engines\gob\extract_fascination_cd.h" />
     <ClInclude Include="..\..\engines\kyra\compress_kyra.h" />
+    <ClInclude Include="..\..\engines\prince\extract_prince.h" />
+    <ClInclude Include="..\..\engines\prince\pack_prince.h" />
     <ClInclude Include="..\..\engines\queen\compress_queen.h" />
     <ClInclude Include="..\..\engines\saga\compress_saga.h" />
     <ClInclude Include="..\..\engines\sci\compress_sci.h" />
@@ -198,4 +202,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/dists/msvc10/toolscli.vcxproj.filters b/dists/msvc10/toolscli.vcxproj.filters
index 4de1d72..e8a82d0 100644
--- a/dists/msvc10/toolscli.vcxproj.filters
+++ b/dists/msvc10/toolscli.vcxproj.filters
@@ -153,6 +153,12 @@
     <ClCompile Include="..\..\engines\gob\extract_fascination_cd.cpp">
       <Filter>tools</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\engines\prince\extract_prince.cpp">
+      <Filter>tools</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\engines\prince\pack_prince.cpp">
+      <Filter>tools</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\engines\agos\compress_agos.h">
@@ -299,6 +305,12 @@
     <ClInclude Include="..\..\engines\gob\extract_fascination_cd.h">
       <Filter>tools</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\engines\prince\extract_prince.h">
+      <Filter>tools</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\engines\prince\pack_prince.h">
+      <Filter>tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\gui\media\scummvmtools.ico">
@@ -310,4 +322,4 @@
       <Filter>cli</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file


Commit: d471dc8ca2ed9bb5b405974755064ed918426678
    https://github.com/scummvm/scummvm-tools/commit/d471dc8ca2ed9bb5b405974755064ed918426678
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-11-03T17:07:23+01:00

Commit Message:
Merge pull request #7 from lukaslw/prince-tools

TOOLS: The Prince and the Coward - extraction and packing tools for translation purposes

Changed paths:
  A engines/prince/extract_prince.cpp
  A engines/prince/extract_prince.h
  A engines/prince/pack_prince.cpp
  A engines/prince/pack_prince.h
    Makefile.common
    dists/msvc10/toolscli.vcxproj
    dists/msvc10/toolscli.vcxproj.filters
    tools.cpp









More information about the Scummvm-git-logs mailing list