aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/agi-palex.py185
-rw-r--r--tools/create_kyradat/create_kyradat.cpp6
-rw-r--r--tools/create_kyradat/md5.cpp2
-rw-r--r--tools/scumm-md5.txt7
4 files changed, 199 insertions, 1 deletions
diff --git a/tools/agi-palex.py b/tools/agi-palex.py
new file mode 100644
index 0000000000..58306dddbe
--- /dev/null
+++ b/tools/agi-palex.py
@@ -0,0 +1,185 @@
+#!/usr/bin/python
+# Amiga AGI game palette extractor.
+# Extracts palette from an Amiga AGI game's executable file.
+# Initial version written during summer of 2007 by Buddha^.
+# Somewhat optimized. Adding the preliminary palette test helped speed a lot.
+# FIXME: Doesn't report anything about not found files when some files are found.
+# An example: palex.py SQ2 PQ1 (When file SQ2 exists but PQ1 doesn't)
+import struct, sys, os.path, glob
+
+# Constants
+maxComponentValue = 0xF
+colorsPerPalette = 16
+componentsPerColor = 3
+bytesPerComponent = 2
+bytesPerColor = componentsPerColor * bytesPerComponent
+componentsPerPalette = colorsPerPalette * componentsPerColor
+bytesPerPalette = componentsPerPalette * bytesPerComponent
+encodedBlack = '\x00' * bytesPerColor
+encodedWhite = (('\x00' * (bytesPerComponent - 1)) + ("%c" % maxComponentValue)) * componentsPerColor
+decodedBlack = tuple([0 for x in range(componentsPerColor)])
+decodedWhite = tuple([maxComponentValue for x in range(componentsPerColor)])
+blackColorNum = 0
+whiteColorNum = colorsPerPalette - 1
+encodedBlackStart = blackColorNum * bytesPerColor
+encodedBlackEnd = encodedBlackStart + bytesPerColor
+encodedWhiteStart = whiteColorNum * bytesPerColor
+encodedWhiteEnd = encodedWhiteStart + bytesPerColor
+componentPrintFormat = "0x%1X"
+arraynamePrefix = "amigaPalette"
+
+def isColor12Bit(color):
+ """Is the color 12-bit (i.e. 4 bits per color component)?"""
+ for component in color:
+ if not (0 <= component <= maxComponentValue):
+ return False
+ return True
+
+def printCommentLineList(lines):
+ """Prints list of lines inside a comment"""
+ if len(lines) > 0:
+ if len(lines) == 1:
+ print "// " + lines[0]
+ else:
+ print "/**"
+ for line in lines:
+ print " * " + line
+ print " */"
+
+def printColor(color, tabulate = True, printLastComma = True, newLine = True):
+ """Prints color with optional start tabulation, comma in the end and a newline"""
+ result = ""
+ if tabulate:
+ result += "\t"
+ for component in color[:-1]:
+ result += ((componentPrintFormat + ", ") % component)
+ result += (componentPrintFormat % color[-1])
+ if printLastComma:
+ result += ","
+ if newLine:
+ print result
+ else:
+ print result,
+
+def printPalette(palette, filename, arrayname):
+ """Prints out palette as a C-style array"""
+ # Print comments about the palette
+ comments = ["A 16-color, 12-bit RGB palette from an Amiga AGI game."]
+ comments.append("Extracted from file " + os.path.basename(filename))
+ printCommentLineList(comments)
+
+ # Print the palette as a C-style array
+ print "static const unsigned char " + arrayname + "[] = {"
+ for color in palette[:-1]:
+ printColor(color)
+ printColor(palette[-1], printLastComma = False)
+ print("};")
+
+def isAmigaPalette(palette):
+ """Test if the given palette is an Amiga-style palette"""
+ # Palette must be of correct size
+ if len(palette) != colorsPerPalette:
+ return False
+
+ # First palette color must be black and last palette color must be black
+ if palette[whiteColorNum] != decodedWhite or palette[blackColorNum] != decodedBlack:
+ return False
+
+ # All colors must be 12-bit (i.e. 4 bits per color component)
+ for color in palette:
+ if not isColor12Bit(color):
+ return False
+
+ # All colors must be unique
+ if len(set(palette)) != colorsPerPalette:
+ return False
+
+ return True
+
+def preliminaryPaletteTest(data, pos):
+ """Preliminary test for a palette (For speed's sake)."""
+ # Test that palette's last color is white
+ if data[pos + encodedWhiteStart : pos + encodedWhiteEnd] != encodedWhite:
+ return False
+ # Test that palette's first color is black
+ if data[pos + encodedBlackStart : pos + encodedBlackEnd] != encodedBlack:
+ return False
+ return True
+
+def searchForAmigaPalettes(filename):
+ """Search file for Amiga AGI game palettes and return any found unique palettes"""
+ try:
+ file = None
+ foundPalettes = []
+ # Open file and read it into memory
+ file = open(filename, 'rb')
+ data = file.read()
+ palette = [decodedBlack for x in range(colorsPerPalette)]
+ # Search through the whole file
+ for searchPosition in range(len(data) - bytesPerPalette + 1):
+ if preliminaryPaletteTest(data, searchPosition):
+ # Parse possible palette from byte data
+ for colorNum in range(colorsPerPalette):
+ colorStart = searchPosition + colorNum * bytesPerColor
+ colorEnd = colorStart + bytesPerColor
+ # Parse color components as unsigned 16-bit big endian integers
+ color = struct.unpack('>' + 'H' * componentsPerColor, data[colorStart:colorEnd])
+ palette[colorNum] = color
+ # Save good candidates to a list
+ if isAmigaPalette(palette):
+ foundPalettes.append(tuple(palette))
+ # Close source file and return unique found palettes
+ file.close()
+ return set(foundPalettes)
+ except IOError:
+ if file != None:
+ file.close()
+ return None
+
+# The main program starts here
+if len(sys.argv) < 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help":
+ quit("Usage: " + os.path.basename(sys.argv[0]) + " FILE [[FILE] ... [FILE]]\n" \
+ " Searches all FILE parameters for Amiga AGI game palettes\n" \
+ " and prints out any found candidates as C-style arrays\n" \
+ " with sequentially numbered names (" + arraynamePrefix + "1, " + arraynamePrefix + "2 etc).\n" \
+ " Supports wildcards.")
+
+# Get the list of filenames (Works with wildcards too)
+filenameList = []
+for parameter in sys.argv[1:]:
+ filenameList.extend(glob.glob(parameter))
+
+# Go through all the files and search for palettes
+totalPalettesCount = 0
+if len(filenameList) > 0:
+ negativeFiles = []
+ errorFiles = []
+ for filename in filenameList:
+ foundPalettes = searchForAmigaPalettes(filename)
+ if foundPalettes == None:
+ errorFiles.append(filename)
+ elif len(foundPalettes) == 0:
+ negativeFiles.append(filename)
+ else:
+ # Print out the found palettes
+ for palette in foundPalettes:
+ # Print palettes with sequentially numbered array names
+ totalPalettesCount = totalPalettesCount + 1
+ printPalette(palette, filename, arraynamePrefix + str(totalPalettesCount))
+ print "" # Print an extra newline to separate things
+ # Print comment about files we couldn't find any palettes in
+ if len(negativeFiles) > 0:
+ comments = []
+ comments.append("Couldn't find any palettes in the following files:")
+ comments.extend(negativeFiles)
+ printCommentLineList(comments)
+ print "" # Print an extra newline to separate things
+ # Print comment about errors handling files
+ if len(errorFiles) > 0:
+ comments = []
+ comments.append("Error handling the following files:")
+ comments.extend(errorFiles)
+ printCommentLineList(comments)
+ print "" # Print an extra newline to separate things
+else:
+ printCommentLineList(["No files found"])
diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp
index ab2d8783fa..3596751ff1 100644
--- a/tools/create_kyradat/create_kyradat.cpp
+++ b/tools/create_kyradat/create_kyradat.cpp
@@ -39,6 +39,11 @@ enum {
#include "towns.h"
#include "amiga.h"
+const Game kyra1FanTranslations[] = {
+ { kKyra1, IT_ITA, kTalkieVersion, "7a6887428c4847625db132a461cabbbf", kyra1FreCD },
+ GAME_DUMMY_ENTRY
+};
+
bool extractRaw(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0);
bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0);
bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0);
@@ -718,6 +723,7 @@ const Game *gameDescs[] = {
kyra1GerGames,
kyra1TownsGames,
kyra1AmigaGames,
+ kyra1FanTranslations,
0
};
diff --git a/tools/create_kyradat/md5.cpp b/tools/create_kyradat/md5.cpp
index abdc002eb0..78af417171 100644
--- a/tools/create_kyradat/md5.cpp
+++ b/tools/create_kyradat/md5.cpp
@@ -226,7 +226,7 @@ bool md5_file(const char *name, uint8 digest[16], uint32 length) {
f = fopen(name, "rb");
if (f == NULL) {
- printf("md5_file couldn't open '%s'", name);
+ printf("md5_file couldn't open '%s'\n", name);
return false;
}
diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt
index f97785cbe0..6db30d428d 100644
--- a/tools/scumm-md5.txt
+++ b/tools/scumm-md5.txt
@@ -204,6 +204,8 @@ monkey The Secret of Monkey Island
66fd5ff9a810dfeb6d6bdada18221140 -1 it DOS VGA VGA 4 disk Andrea Petrucci
45152f7cf2ba8f43cf8a8ea2e740ae09 8357 es DOS VGA VGA 4 disk Fingolfin
+ 8776caed014c321272af407c1502a2df 8955 en Mac CD - Mac v2.4 Petr Maruska (#1749232)
+
2d1e891fe52df707c30185e52c50cd92 8955 en DOS CD CD CD-ROM v2.3 Fingolfin
aa8a0cb65f3afbbe2c14c3f9f92775a3 8955 fr DOS CD CD CD-ROM v2.3 Fingolfin, Andrej Sinicyn, Andrea Petrucci
305d3dd57c96c65b017bc70c8c7cfb5e 8955 de DOS CD CD CD-ROM v2.3 Fingolfin
@@ -212,6 +214,7 @@ monkey The Secret of Monkey Island
2ccd8891ce4d3f1a334d21bff6a88ca2 9455 en Mac CD - Mac v2.4 Fingolfin, Lars N&aelig;sbye Christensen
b9ba19ce376efc69be78ef3baef8d2b9 -1 en Mac CD - alt? Grant Yeager
c13225cb1bbd3bc9fe578301696d8021 -1 en SEGA SEGA - -
+ 057c9b456dedcc4d71b991a3072a20b3 9465 jp SEGA SEGA - - GloKidd
8eb84cee9b429314c7f0bdcf560723eb -1 en FM-TOWNS FM-TOWNS - - Paul Priest, Andrea Petrucci
e17db1ddf91b39ca6bbc8ad3ed19e883 -1 jp FM-TOWNS FM-TOWNS - - Paul Priest, Andrea Petrucci
@@ -390,6 +393,9 @@ SoccerMLS Backyard Soccer MLS Edition
Soccer2004 Backyard Soccer 2004
c4ffae9fac495475d6bc3343ccc8faf9 -1 en All - - - Kirben, sev
+brstorm Bear Stormin'
+ 07a1eefd8ca95d77310311446c0f53d0 5433 en All - Demo - sev
+
thinker1 Big Thinkers First Grade
5c21fc49aee8f46e58fef21579e614a1 -1 us All - - - Kirben
@@ -427,6 +433,7 @@ fbear Fatty Bear's Birthday Surprise
fbpack Fatty Bear's Fun Pack
e01acc8c12ef44e8f778fe87e5f90f4e -1 en 3DO - - - sev
+ c9717ee6059f1e43b768b464493d2fba -1 jp 3DO - - - clone2727
f06e66fd45b2f8b0f4a2833ff4476050 -1 hb DOS - - - sev
freddi Freddi Fish 1: The Case of the Missing Kelp Seeds