aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile21
-rw-r--r--Makefile.common4
-rw-r--r--tools/.cvsignore3
-rw-r--r--tools/convbdf.c879
-rw-r--r--tools/md5table.c277
-rw-r--r--tools/scumm-md5.txt406
-rw-r--r--tools/simon-md5.txt29
7 files changed, 1616 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 60dffb4bb7..23b9094793 100644
--- a/Makefile
+++ b/Makefile
@@ -83,6 +83,25 @@ deb:
debian/prepare
fakeroot debian/rules binary
+#######################################################################
+# Tools directory
+#######################################################################
+
+TOOLS := tools/convbdf$(EXEEXT) tools/md5table$(EXEEXT)
+
+tools: $(TOOLS)
+
+tools/convbdf$(EXEEXT): tools/convbdf.o
+ $(CXX) -o $@ $<
+
+tools/md5table$(EXEEXT): tools/md5table.o
+ $(CXX) -o $@ $<
+
+credits:
+ ./credits.pl --text > AUTHORS
+ ./credits.pl --html > ../web/credits.inc
+ ./credits.pl --cpp > gui/credits.h
+ ./credits.pl --xml > ../docs/docbook/credits.xml
#######################################################################
# Unit/regression tests #
@@ -153,4 +172,4 @@ win32dist: scummvm$(EXEEXT)
u2d $(WIN32PATH)/*.txt
-.PHONY: deb bundle test osxsnap win32dist dist install uninstall
+.PHONY: deb bundle test osxsnap win32dist dist install uninstall credits
diff --git a/Makefile.common b/Makefile.common
index fbeffe54d2..65dc3953a1 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -5,7 +5,7 @@
######################################################################
# The defaul build target: just build the scummvm executable
######################################################################
-all: $(EXECUTABLE) plugins
+all: tools $(EXECUTABLE) plugins
######################################################################
@@ -122,7 +122,7 @@ distclean: clean
$(RM) build.rules config.h config.mak config.log
clean:
- $(RM) $(OBJS) $(EXECUTABLE)
+ $(RM) $(OBJS) $(EXECUTABLE) $(TOOLS)
.PHONY: all clean dist distclean plugins
diff --git a/tools/.cvsignore b/tools/.cvsignore
new file mode 100644
index 0000000000..39792d01ab
--- /dev/null
+++ b/tools/.cvsignore
@@ -0,0 +1,3 @@
+.deps
+convbdf
+md5table \ No newline at end of file
diff --git a/tools/convbdf.c b/tools/convbdf.c
new file mode 100644
index 0000000000..2fc60bb7ce
--- /dev/null
+++ b/tools/convbdf.c
@@ -0,0 +1,879 @@
+/*
+ * Convert BDF files to C++ source.
+ *
+ * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
+ *
+ * Originally writen for the Microwindows Project <http://microwindows.org>
+ *
+ * Greg then modified it for Rockbox <http://rockbox.haxx.se/>
+ *
+ * Max Horn took that version and changed it to work for ScummVM.
+ * Changes include: warning fixes, removed .FNT output, output C++ source,
+ * tweak code generator so that the generated code fits into ScummVM code base.
+ *
+ * What fun it is converting font data...
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* BEGIN font.h*/
+/* bitmap_t helper macros*/
+#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
+#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
+#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
+#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
+#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
+#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
+#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
+
+typedef unsigned short bitmap_t; /* bitmap image unit size*/
+
+/* builtin C-based proportional/fixed font structure */
+/* based on The Microwindows Project http://microwindows.org */
+struct font {
+ char * name; /* font name*/
+ int maxwidth; /* max width in pixels*/
+ int height; /* height in pixels*/
+ int ascent; /* ascent (baseline) height*/
+ int firstchar; /* first character in bitmap*/
+ int size; /* font size in glyphs*/
+ bitmap_t* bits; /* 16-bit right-padded bitmap data*/
+ unsigned long* offset; /* offsets into bitmap data*/
+ unsigned char* width; /* character widths or NULL if fixed*/
+ int defaultchar; /* default char (not glyph index)*/
+ long bits_size; /* # words of bitmap_t bits*/
+
+ /* unused by runtime system, read in by convbdf*/
+ char * facename; /* facename of font*/
+ char * copyright; /* copyright info for loadable fonts*/
+ int pixel_size;
+ int descent;
+ int fbbw, fbbh, fbbx, fbby;
+};
+/* END font.h*/
+
+#define isprefix(buf,str) (!strncmp(buf, str, strlen(str)))
+#define strequal(s1,s2) (!strcmp(s1, s2))
+
+#define EXTRA 300 /* # bytes extra allocation for buggy .bdf files*/
+
+int gen_map = 1;
+int start_char = 0;
+int limit_char = 65535;
+int oflag = 0;
+char outfile[256];
+
+void usage(void);
+void getopts(int *pac, char ***pav);
+int convbdf(char *path);
+
+void free_font(struct font* pf);
+struct font* bdf_read_font(char *path);
+int bdf_read_header(FILE *fp, struct font* pf);
+int bdf_read_bitmaps(FILE *fp, struct font* pf);
+char * bdf_getline(FILE *fp, char *buf, int len);
+bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2);
+
+int gen_c_source(struct font* pf, char *path);
+
+void error(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsprintf(buf, s, va);
+ va_end(va);
+
+ fprintf(stderr, "ERROR: %s!\n", buf);
+
+ exit(1);
+}
+
+void warning(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsprintf(buf, s, va);
+ va_end(va);
+
+ fprintf(stderr, "WARNING: %s!\n", buf);
+}
+
+void
+usage(void)
+{
+ char help[] = {
+ "Usage: convbdf [options] [input-files]\n"
+ " convbdf [options] [-o output-file] [single-input-file]\n"
+ "Options:\n"
+ " -s N Start output at character encodings >= N\n"
+ " -l N Limit output to character encodings <= N\n"
+ " -n Don't generate bitmaps as comments in .c file\n"
+ };
+
+ fprintf(stderr, help);
+}
+
+/* parse command line options*/
+void getopts(int *pac, char ***pav)
+{
+ const char *p;
+ char **av;
+ int ac;
+
+ ac = *pac;
+ av = *pav;
+ while (ac > 0 && av[0][0] == '-') {
+ p = &av[0][1];
+ while( *p)
+ switch(*p++) {
+ case ' ': /* multiple -args on av[]*/
+ while( *p && *p == ' ')
+ p++;
+ if( *p++ != '-') /* next option must have dash*/
+ p = "";
+ break; /* proceed to next option*/
+ case 'n': /* don't gen bitmap comments*/
+ gen_map = 0;
+ break;
+ case 'o': /* set output file*/
+ oflag = 1;
+ if (*p) {
+ strcpy(outfile, p);
+ while (*p && *p != ' ')
+ p++;
+ }
+ else {
+ av++; ac--;
+ if (ac > 0)
+ strcpy(outfile, av[0]);
+ }
+ break;
+ case 'l': /* set encoding limit*/
+ if (*p) {
+ limit_char = atoi(p);
+ while (*p && *p != ' ')
+ p++;
+ }
+ else {
+ av++; ac--;
+ if (ac > 0)
+ limit_char = atoi(av[0]);
+ }
+ break;
+ case 's': /* set encoding start*/
+ if (*p) {
+ start_char = atoi(p);
+ while (*p && *p != ' ')
+ p++;
+ }
+ else {
+ av++; ac--;
+ if (ac > 0)
+ start_char = atoi(av[0]);
+ }
+ break;
+ default:
+ fprintf(stderr, "Unknown option ignored: %c\r\n", *(p-1));
+ }
+ ++av; --ac;
+ }
+ *pac = ac;
+ *pav = av;
+}
+
+/* remove directory prefix and file suffix from full path*/
+char *basename(char *path)
+{
+ char *p, *b;
+ static char base[256];
+
+ /* remove prepended path and extension*/
+ b = path;
+ for (p=path; *p; ++p) {
+ if (*p == '/')
+ b = p + 1;
+ }
+ strcpy(base, b);
+ for (p=base; *p; ++p) {
+ if (*p == '.') {
+ *p = 0;
+ break;
+ }
+ }
+ return base;
+}
+
+int convbdf(char *path)
+{
+ struct font* pf;
+ int ret = 0;
+
+ pf = bdf_read_font(path);
+ if (!pf)
+ exit(1);
+
+ if (!oflag) {
+ strcpy(outfile, basename(path));
+ strcat(outfile, ".cpp");
+ }
+ ret |= gen_c_source(pf, outfile);
+
+ free_font(pf);
+ return ret;
+}
+
+int main(int ac, char *av[])
+{
+ int ret = 0;
+
+ ++av; --ac; /* skip av[0]*/
+ getopts(&ac, &av); /* read command line options*/
+
+ if (ac < 1) {
+ usage();
+ exit(1);
+ }
+ if (oflag && ac > 1) {
+ usage();
+ exit(1);
+ }
+
+ while (ac > 0) {
+ ret |= convbdf(av[0]);
+ ++av; --ac;
+ }
+
+ exit(ret);
+}
+
+/* free font structure*/
+void free_font(struct font* pf)
+{
+ if (!pf)
+ return;
+ free(pf->name);
+ free(pf->facename);
+ free(pf->bits);
+ free(pf->offset);
+ free(pf->width);
+ free(pf);
+}
+
+/* build incore structure from .bdf file*/
+struct font* bdf_read_font(char *path)
+{
+ FILE *fp;
+ struct font* pf;
+
+ fp = fopen(path, "rb");
+ if (!fp) {
+ fprintf(stderr, "Error opening file: %s\n", path);
+ return NULL;
+ }
+
+ pf = (struct font*)calloc(1, sizeof(struct font));
+ if (!pf)
+ goto errout;
+
+ pf->name = strdup(basename(path));
+
+ if (!bdf_read_header(fp, pf)) {
+ fprintf(stderr, "Error reading font header\n");
+ goto errout;
+ }
+
+ if (!bdf_read_bitmaps(fp, pf)) {
+ fprintf(stderr, "Error reading font bitmaps\n");
+ goto errout;
+ }
+
+ fclose(fp);
+ return pf;
+
+ errout:
+ fclose(fp);
+ free_font(pf);
+ return NULL;
+}
+
+/* read bdf font header information, return 0 on error*/
+int bdf_read_header(FILE *fp, struct font* pf)
+{
+ int encoding;
+ int nchars, maxwidth;
+ int firstchar = 65535;
+ int lastchar = -1;
+ char buf[256];
+ char facename[256];
+ char copyright[256];
+
+ /* set certain values to errors for later error checking*/
+ pf->defaultchar = -1;
+ pf->ascent = -1;
+ pf->descent = -1;
+
+ for (;;) {
+ if (!bdf_getline(fp, buf, sizeof(buf))) {
+ fprintf(stderr, "Error: EOF on file\n");
+ return 0;
+ }
+ if (isprefix(buf, "FONT ")) { /* not required*/
+ if (sscanf(buf, "FONT %[^\n]", facename) != 1) {
+ fprintf(stderr, "Error: bad 'FONT'\n");
+ return 0;
+ }
+ pf->facename = strdup(facename);
+ continue;
+ }
+ if (isprefix(buf, "COPYRIGHT ")) { /* not required*/
+ if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) {
+ fprintf(stderr, "Error: bad 'COPYRIGHT'\n");
+ return 0;
+ }
+ pf->copyright = strdup(copyright);
+ continue;
+ }
+ if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required*/
+ if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) {
+ fprintf(stderr, "Error: bad 'DEFAULT_CHAR'\n");
+ return 0;
+ }
+ }
+ if (isprefix(buf, "FONT_DESCENT ")) {
+ if (sscanf(buf, "FONT_DESCENT %d", &pf->descent) != 1) {
+ fprintf(stderr, "Error: bad 'FONT_DESCENT'\n");
+ return 0;
+ }
+ continue;
+ }
+ if (isprefix(buf, "FONT_ASCENT ")) {
+ if (sscanf(buf, "FONT_ASCENT %d", &pf->ascent) != 1) {
+ fprintf(stderr, "Error: bad 'FONT_ASCENT'\n");
+ return 0;
+ }
+ continue;
+ }
+ if (isprefix(buf, "FONTBOUNDINGBOX ")) {
+ if (sscanf(buf, "FONTBOUNDINGBOX %d %d %d %d",
+ &pf->fbbw, &pf->fbbh, &pf->fbbx, &pf->fbby) != 4) {
+ fprintf(stderr, "Error: bad 'FONTBOUNDINGBOX'\n");
+ return 0;
+ }
+ continue;
+ }
+ if (isprefix(buf, "CHARS ")) {
+ if (sscanf(buf, "CHARS %d", &nchars) != 1) {
+ fprintf(stderr, "Error: bad 'CHARS'\n");
+ return 0;
+ }
+ continue;
+ }
+
+ /*
+ * Reading ENCODING is necessary to get firstchar/lastchar
+ * which is needed to pre-calculate our offset and widths
+ * array sizes.
+ */
+ if (isprefix(buf, "ENCODING ")) {
+ if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
+ fprintf(stderr, "Error: bad 'ENCODING'\n");
+ return 0;
+ }
+ if (encoding >= 0 &&
+ encoding <= limit_char &&
+ encoding >= start_char) {
+
+ if (firstchar > encoding)
+ firstchar = encoding;
+ if (lastchar < encoding)
+ lastchar = encoding;
+ }
+ continue;
+ }
+ if (strequal(buf, "ENDFONT"))
+ break;
+ }
+
+ /* calc font height*/
+ if (pf->ascent < 0 || pf->descent < 0 || firstchar < 0) {
+ fprintf(stderr, "Error: Invalid BDF file, requires FONT_ASCENT/FONT_DESCENT/ENCODING\n");
+ return 0;
+ }
+ pf->height = pf->ascent + pf->descent;
+
+ /* calc default char*/
+ if (pf->defaultchar < 0 ||
+ pf->defaultchar < firstchar ||
+ pf->defaultchar > limit_char )
+ pf->defaultchar = firstchar;
+
+ /* calc font size (offset/width entries)*/
+ pf->firstchar = firstchar;
+ pf->size = lastchar - firstchar + 1;
+
+ /* use the font boundingbox to get initial maxwidth*/
+ /*maxwidth = pf->fbbw - pf->fbbx;*/
+ maxwidth = pf->fbbw;
+
+ /* initially use font maxwidth * height for bits allocation*/
+ pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * pf->height;
+
+ /* allocate bits, offset, and width arrays*/
+ pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
+ pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
+ pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
+
+ if (!pf->bits || !pf->offset || !pf->width) {
+ fprintf(stderr, "Error: no memory for font load\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+/* read bdf font bitmaps, return 0 on error*/
+int bdf_read_bitmaps(FILE *fp, struct font* pf)
+{
+ long ofs = 0;
+ int maxwidth = 0;
+ int i, k, encoding, width;
+ int bbw, bbh, bbx, bby;
+ int proportional = 0;
+ int encodetable = 0;
+ long l;
+ char buf[256];
+
+ /* reset file pointer*/
+ fseek(fp, 0L, SEEK_SET);
+
+ /* initially mark offsets as not used*/
+ for (i=0; i<pf->size; ++i)
+ pf->offset[i] = -1;
+
+ for (;;) {
+ if (!bdf_getline(fp, buf, sizeof(buf))) {
+ fprintf(stderr, "Error: EOF on file\n");
+ return 0;
+ }
+ if (isprefix(buf, "STARTCHAR")) {
+ encoding = width = bbw = bbh = bbx = bby = -1;
+ continue;
+ }
+ if (isprefix(buf, "ENCODING ")) {
+ if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
+ fprintf(stderr, "Error: bad 'ENCODING'\n");
+ return 0;
+ }
+ if (encoding < start_char || encoding > limit_char)
+ encoding = -1;
+ continue;
+ }
+ if (isprefix(buf, "DWIDTH ")) {
+ if (sscanf(buf, "DWIDTH %d", &width) != 1) {
+ fprintf(stderr, "Error: bad 'DWIDTH'\n");
+ return 0;
+ }
+ /* use font boundingbox width if DWIDTH <= 0*/
+ if (width <= 0)
+ width = pf->fbbw - pf->fbbx;
+ continue;
+ }
+ if (isprefix(buf, "BBX ")) {
+ if (sscanf(buf, "BBX %d %d %d %d", &bbw, &bbh, &bbx, &bby) != 4) {
+ fprintf(stderr, "Error: bad 'BBX'\n");
+ return 0;
+ }
+ continue;
+ }
+ if (strequal(buf, "BITMAP")) {
+ bitmap_t *ch_bitmap = pf->bits + ofs;
+ int ch_words;
+
+ if (encoding < 0)
+ continue;
+
+ /* set bits offset in encode map*/
+ if (pf->offset[encoding-pf->firstchar] != (unsigned long)-1) {
+ fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n",
+ encoding, encoding);
+ continue;
+ }
+ pf->offset[encoding-pf->firstchar] = ofs;
+
+ /* calc char width*/
+ if (bbx < 0) {
+ width -= bbx;
+ /*if (width > maxwidth)
+ width = maxwidth;*/
+ bbx = 0;
+ }
+ if (width > maxwidth)
+ maxwidth = width;
+ pf->width[encoding-pf->firstchar] = width;
+
+ /* clear bitmap*/
+ memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height);
+
+ ch_words = BITMAP_WORDS(width);
+#define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col)))
+#define BITMAP_NIBBLES (BITMAP_BITSPERIMAGE/4)
+
+ /* read bitmaps*/
+ for (i=0; ; ++i) {
+ int hexnibbles;
+
+ if (!bdf_getline(fp, buf, sizeof(buf))) {
+ fprintf(stderr, "Error: EOF reading BITMAP data\n");
+ return 0;
+ }
+ if (isprefix(buf, "ENDCHAR"))
+ break;
+
+ hexnibbles = strlen(buf);
+ for (k=0; k<ch_words; ++k) {
+ int ndx = k * BITMAP_NIBBLES;
+ int padnibbles = hexnibbles - ndx;
+ bitmap_t value;
+
+ if (padnibbles <= 0)
+ break;
+ if (padnibbles >= BITMAP_NIBBLES)
+ padnibbles = 0;
+
+ value = bdf_hexval((unsigned char *)buf,
+ ndx, ndx+BITMAP_NIBBLES-1-padnibbles);
+ value <<= padnibbles * BITMAP_NIBBLES;
+
+ BM(pf->height - pf->descent - bby - bbh + i, k) |=
+ value >> bbx;
+ /* handle overflow into next image word*/
+ if (bbx) {
+ BM(pf->height - pf->descent - bby - bbh + i, k+1) =
+ value << (BITMAP_BITSPERIMAGE - bbx);
+ }
+ }
+ }
+
+ ofs += BITMAP_WORDS(width) * pf->height;
+
+ continue;
+ }
+ if (strequal(buf, "ENDFONT"))
+ break;
+ }
+
+ /* set max width*/
+ pf->maxwidth = maxwidth;
+
+ /* change unused offset/width values to default char values*/
+ for (i=0; i<pf->size; ++i) {
+ int defchar = pf->defaultchar - pf->firstchar;
+
+ if (pf->offset[i] == (unsigned long)-1) {
+ pf->offset[i] = pf->offset[defchar];
+ pf->width[i] = pf->width[defchar];
+ }
+ }
+
+ /* determine whether font doesn't require encode table*/
+ l = 0;
+ for (i=0; i<pf->size; ++i) {
+ if (pf->offset[i] != l) {
+ encodetable = 1;
+ break;
+ }
+ l += BITMAP_WORDS(pf->width[i]) * pf->height;
+ }
+ if (!encodetable) {
+ free(pf->offset);
+ pf->offset = NULL;
+ }
+
+ /* determine whether font is fixed-width*/
+ for (i=0; i<pf->size; ++i) {
+ if (pf->width[i] != maxwidth) {
+ proportional = 1;
+ break;
+ }
+ }
+ if (!proportional) {
+ free(pf->width);
+ pf->width = NULL;
+ }
+
+ /* reallocate bits array to actual bits used*/
+ if (ofs < pf->bits_size) {
+ pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t));
+ pf->bits_size = ofs;
+ }
+ else {
+ if (ofs > pf->bits_size) {
+ fprintf(stderr, "Warning: DWIDTH spec > max FONTBOUNDINGBOX\n");
+ if (ofs > pf->bits_size+EXTRA) {
+ fprintf(stderr, "Error: Not enough bits initially allocated\n");
+ return 0;
+ }
+ pf->bits_size = ofs;
+ }
+ }
+
+ return 1;
+}
+
+/* read the next non-comment line, returns buf or NULL if EOF*/
+char *bdf_getline(FILE *fp, char *buf, int len)
+{
+ int c;
+ char *b;
+
+ for (;;) {
+ b = buf;
+ while ((c = getc(fp)) != EOF) {
+ if (c == '\r')
+ continue;
+ if (c == '\n')
+ break;
+ if (b - buf >= (len - 1))
+ break;
+ *b++ = c;
+ }
+ *b = '\0';
+ if (c == EOF && b == buf)
+ return NULL;
+ if (b != buf && !isprefix(buf, "COMMENT"))
+ break;
+ }
+ return buf;
+}
+
+/* return hex value of portion of buffer*/
+bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2)
+{
+ bitmap_t val = 0;
+ int i, c;
+
+ for (i=ndx1; i<=ndx2; ++i) {
+ c = buf[i];
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else
+ if (c >= 'A' && c <= 'F')
+ c = c - 'A' + 10;
+ else
+ if (c >= 'a' && c <= 'f')
+ c = c - 'a' + 10;
+ else
+ c = 0;
+ val = (val << 4) | c;
+ }
+ return val;
+}
+
+/* generate C source from in-core font*/
+int gen_c_source(struct font* pf, char *path)
+{
+ FILE *ofp;
+ int i;
+ int did_defaultchar = 0;
+ int did_syncmsg = 0;
+ time_t t = time(0);
+ bitmap_t *ofs = pf->bits;
+ char buf[256];
+ char obuf[256];
+ char hdr1[] = {
+ "/* Generated by convbdf on %s. */\n"
+ "#include \"common/stdafx.h\"\n"
+ "#include \"graphics/font.h\"\n"
+ "\n"
+ "/* Font information:\n"
+ " name: %s\n"
+ " facename: %s\n"
+ " w x h: %dx%d\n"
+ " size: %d\n"
+ " ascent: %d\n"
+ " descent: %d\n"
+ " first char: %d (0x%02x)\n"
+ " last char: %d (0x%02x)\n"
+ " default char: %d (0x%02x)\n"
+ " proportional: %s\n"
+ " %s\n"
+ "*/\n"
+ "\n"
+ "namespace Graphics {\n"
+ "\n"
+ "/* Font character bitmap data. */\n"
+ "static const bitmap_t _font_bits[] = {\n"
+ };
+
+ ofp = fopen(path, "w");
+ if (!ofp) {
+ fprintf(stderr, "Can't create %s\n", path);
+ return 1;
+ }
+
+ strcpy(buf, ctime(&t));
+ buf[strlen(buf)-1] = 0;
+
+ fprintf(ofp, hdr1, buf,
+ pf->name,
+ pf->facename? pf->facename: "",
+ pf->maxwidth, pf->height,
+ pf->size,
+ pf->ascent, pf->descent,
+ pf->firstchar, pf->firstchar,
+ pf->firstchar+pf->size-1, pf->firstchar+pf->size-1,
+ pf->defaultchar, pf->defaultchar,
+ pf->width? "yes": "no",
+ pf->copyright? pf->copyright: "");
+
+ /* generate bitmaps*/
+ for (i=0; i<pf->size; ++i) {
+ int x;
+ int bitcount = 0;
+ int width = pf->width ? pf->width[i] : pf->maxwidth;
+ int height = pf->height;
+ bitmap_t *bits = pf->bits + (pf->offset? pf->offset[i]: (height * i));
+ bitmap_t bitvalue = 0;
+
+ /*
+ * Generate bitmap bits only if not this index isn't
+ * the default character in encode map, or the default
+ * character hasn't been generated yet.
+ */
+ if (pf->offset &&
+ (pf->offset[i] == pf->offset[pf->defaultchar-pf->firstchar])) {
+ if (did_defaultchar)
+ continue;
+ did_defaultchar = 1;
+ }
+
+ fprintf(ofp, "\n/* Character %d (0x%02x):\n width %d",
+ i+pf->firstchar, i+pf->firstchar, width);
+
+ if (gen_map) {
+ fprintf(ofp, "\n +");
+ for (x=0; x<width; ++x) fprintf(ofp, "-");
+ fprintf(ofp, "+\n");
+
+ x = 0;
+ while (height > 0) {
+ if (x == 0) fprintf(ofp, " |");
+
+ if (bitcount <= 0) {
+ bitcount = BITMAP_BITSPERIMAGE;
+ bitvalue = *bits++;
+ }
+
+ fprintf(ofp, BITMAP_TESTBIT(bitvalue)? "*": " ");
+
+ bitvalue = BITMAP_SHIFTBIT(bitvalue);
+ --bitcount;
+ if (++x == width) {
+ fprintf(ofp, "|\n");
+ --height;
+ x = 0;
+ bitcount = 0;
+ }
+ }
+ fprintf(ofp, " +");
+ for (x=0; x<width; ++x)
+ fprintf(ofp, "-");
+ fprintf(ofp, "+\n*/\n");
+ } else
+ fprintf(ofp, "\n*/\n");
+
+ bits = pf->bits + (pf->offset? pf->offset[i]: (pf->height * i));
+ for (x=BITMAP_WORDS(width)*pf->height; x>0; --x) {
+ fprintf(ofp, "0x%04x,\n", *bits);
+ if (!did_syncmsg && *bits++ != *ofs++) {
+ fprintf(stderr, "Warning: found encoding values in non-sorted order (not an error).\n");
+ did_syncmsg = 1;
+ }
+ }
+ }
+ fprintf(ofp, "};\n\n");
+
+ if (pf->offset) {
+ /* output offset table*/
+ fprintf(ofp, "/* Character->glyph mapping. */\n"
+ "static const unsigned long _sysfont_offset[] = {\n");
+
+ for (i=0; i<pf->size; ++i)
+ fprintf(ofp, " %ld,\t/* (0x%02x) */\n",
+ pf->offset[i], i+pf->firstchar);
+ fprintf(ofp, "};\n\n");
+ }
+
+ /* output width table for proportional fonts*/
+ if (pf->width) {
+ fprintf(ofp, "/* Character width data. */\n"
+ "static const unsigned char _sysfont_width[] = {\n");
+
+ for (i=0; i<pf->size; ++i)
+ fprintf(ofp, " %d,\t/* (0x%02x) */\n",
+ pf->width[i], i+pf->firstchar);
+ fprintf(ofp, "};\n\n");
+ }
+
+ /* output struct font struct*/
+ if (pf->offset)
+ sprintf(obuf, "_sysfont_offset,");
+ else
+ sprintf(obuf, "0, /* no encode table*/");
+
+ if (pf->width)
+ sprintf(buf, "_sysfont_width,");
+ else
+ sprintf(buf, "0, /* fixed width*/");
+
+ fprintf(ofp,
+ "/* Exported structure definition. */\n"
+ "static const FontDesc desc = {\n"
+ "\t" "\"%s\",\n"
+ "\t" "%d,\n"
+ "\t" "%d,\n"
+ "\t" "%d,\n"
+ "\t" "%d,\n"
+ "\t" "%d,\n"
+ "\t" "_font_bits,\n"
+ "\t" "%s\n"
+ "\t" "%s\n"
+ "\t" "%d,\n"
+ "\t" "sizeof(_font_bits)/sizeof(bitmap_t)\n"
+ "};\n",
+ pf->name,
+ pf->maxwidth, pf->height,
+ pf->ascent,
+ pf->firstchar,
+ pf->size,
+ obuf,
+ buf,
+ pf->defaultchar);
+
+ fprintf(ofp, "\n" "extern const NewFont g_sysfont(desc);\n");
+ fprintf(ofp, "\n} // End of namespace Graphics\n");
+
+ return 0;
+}
diff --git a/tools/md5table.c b/tools/md5table.c
new file mode 100644
index 0000000000..06f0f5a385
--- /dev/null
+++ b/tools/md5table.c
@@ -0,0 +1,277 @@
+/* md5table - Convert a MD5 table to either PHP or C++ code
+ * Copyright (C) 2002, 2003 The ScummVM Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+void error(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsprintf(buf, s, va);
+ va_end(va);
+
+ fprintf(stderr, "ERROR: %s!\n", buf);
+
+ exit(1);
+}
+
+void warning(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsprintf(buf, s, va);
+ va_end(va);
+
+ fprintf(stderr, "WARNING: %s!\n", buf);
+}
+
+typedef struct {
+ const char *key;
+ const char *value;
+} StringMap;
+
+typedef struct {
+ const char *desc;
+ const char *platform;
+ const char *language;
+ const char *md5;
+ const char *target;
+ const char *infoSource;
+} Entry;
+
+/* Map MD5 table platform names to ScummVM constant names.
+ * Note: Currently not many constants are defined within ScummVM. However, more
+ * will probably be added eventually (see also commented out constants in
+ * common/util.h).
+ */
+static const StringMap platformMap[] = {
+ { "3DO", "kPlatformUnknown" },
+ { "Amiga", "kPlatformAmiga" },
+ { "Atari", "kPlatformAtariST" },
+ { "DOS", "kPlatformPC" },
+ { "FM-TOWNS", "kPlatformFMTowns" },
+ { "Mac", "kPlatformMacintosh" },
+ { "SEGA", "kPlatformUnknown" },
+ { "Windows", "kPlatformWindows" },
+
+ { "All?", "kPlatformUnknown" },
+ { "All", "kPlatformUnknown" },
+
+ { 0, "kPlatformUnknown" }
+};
+
+static const StringMap langMap[] = {
+ { "en", "EN_USA" },
+ { "de", "DE_DEU" },
+ { "fr", "FR_FRA" },
+ { "it", "IT_ITA" },
+ { "pt", "PT_BRA" },
+ { "es", "ES_ESP" },
+ { "jp", "JA_JPN" },
+ { "zh", "ZH_TWN" },
+ { "ko", "KO_KOR" },
+ { "se", "SE_SWE" },
+ { "en", "EN_GRB" },
+ { "hb", "HB_ISR" },
+ { "ru", "RU_RUS" },
+ { "cz", "CZ_CZE" },
+ { "nl", "NL_NLD" },
+
+ { "All", "UNK_LANG" },
+ { "All?", "UNK_LANG" },
+
+ { 0, "UNK_LANG" }
+};
+
+static const char *php_header =
+ "<!--\n"
+ " This file was generated by the md5table tool on %s"
+ " DO NOT EDIT MANUALLY!\n"
+ " -->\n"
+ "\n";
+
+static const char *c_header =
+ "/*\n"
+ " This file was generated by the md5table tool on %s"
+ " DO NOT EDIT MANUALLY!\n"
+ " */\n"
+ "\n"
+ "struct MD5Table {\n"
+ " const char *md5;\n"
+ " const char *target;\n"
+ " Common::Language language;\n"
+ " Common::Platform platform;\n"
+ "};\n"
+ "\n"
+ "static const MD5Table md5table[] = {\n";
+
+static const char *c_footer =
+ " { 0, 0, Common::UNK_LANG, Common::kPlatformUnknown }\n"
+ "};\n";
+
+static void parseEntry(Entry *entry, char *line) {
+ assert(entry);
+ assert(line);
+
+ /* Split at the tabs */
+ entry->desc = strtok(line, "\t\n\r");
+ entry->platform = strtok(NULL, "\t\n\r");
+ entry->language = strtok(NULL, "\t\n\r");
+ entry->md5 = strtok(NULL, "\t\n\r");
+ entry->target = strtok(NULL, "\t\n\r");
+ entry->infoSource = strtok(NULL, "\t\n\r");
+}
+
+static int isEmptyLine(const char *line) {
+ const char *whitespace = " \t\n\r";
+ while (*line) {
+ if (!strchr(whitespace, *line))
+ return 0;
+ line++;
+ }
+ return 1;
+}
+
+static const char *mapStr(const char *str, const StringMap *map) {
+ assert(str);
+ assert(map);
+ while (map->key) {
+ if (0 == strcmp(map->key, str))
+ return map->value;
+ map++;
+ }
+ warning("mapStr: unknown string '%s', defaulting to '%s'", str, map->value);
+ return map->value;
+}
+
+void showhelp(const char *exename)
+{
+ printf("\nUsage: %s <params>\n", exename);
+ printf("\nParams:\n");
+ printf(" --c++ output C++ code for inclusion in ScummVM (default)\n");
+ printf(" --php output PHP code for the web site\n");
+ exit(2);
+}
+
+/* needed to call from qsort */
+int strcmp_wrapper(const void *s1, const void *s2)
+{
+ return strcmp((const char *)s1, (const char *)s2);
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *inFile = stdin;
+ FILE *outFile = stdout;
+ char buffer[1024];
+ char section[1024];
+ char *line;
+ int err;
+ int i;
+ time_t theTime;
+ const char *generationDate;
+
+ const int entrySize = 256;
+ int numEntries = 0, maxEntries = 1;
+ char *entriesBuffer = malloc(maxEntries * entrySize);
+
+ int phpOutput = 0;
+
+ if (argc != 2)
+ showhelp(argv[0]);
+ if (strcmp(argv[1], "--c++") == 0) {
+ phpOutput = 0;
+ } else if (strcmp(argv[1], "--php") == 0) {
+ phpOutput = 1;
+ } else {
+ showhelp(argv[0]);
+ }
+
+ time(&theTime);
+ generationDate = strdup(asctime(gmtime(&theTime)));
+
+ if (phpOutput)
+ fprintf(outFile, php_header, generationDate);
+
+ while ((line = fgets(buffer, sizeof(buffer), inFile))) {
+ /* Parse line */
+ if (line[0] == '#' || isEmptyLine(line))
+ continue; /* Skip comments & empty lines */
+ if (line[0] == '\t') {
+ Entry entry;
+ assert(section[0]);
+ parseEntry(&entry, line+1);
+ if (phpOutput) {
+ fprintf(outFile, "\t\t<?php addEntry(");
+ fprintf(outFile, "\"%s\", ", entry.desc);
+ fprintf(outFile, "\"%s\", ", entry.platform);
+ fprintf(outFile, "\"%s\", ", entry.language);
+ fprintf(outFile, "\"%s\", ", entry.md5);
+ fprintf(outFile, "\"%s\"", entry.target);
+ if (entry.infoSource)
+ fprintf(outFile, ", \"%s\"", entry.infoSource);
+ fprintf(outFile, "); ?>\n");
+ } else if (entry.md5) {
+ if (numEntries >= maxEntries) {
+ maxEntries *= 2;
+ entriesBuffer = realloc(entriesBuffer, maxEntries * entrySize);
+ }
+ snprintf(entriesBuffer + numEntries * entrySize, entrySize, "\t{ \"%s\", \"%s\", Common::%s, Common::%s },\n",
+ entry.md5, entry.target, mapStr(entry.language, langMap), mapStr(entry.platform, platformMap));
+ numEntries++;
+ }
+ } else {
+ for (i = 0; buffer[i] && buffer[i] != '\n'; ++i)
+ section[i] = buffer[i];
+ section[i] = 0;
+ if (phpOutput) {
+ fprintf(outFile, "\t<tr><td colspan='7'><strong>%s</strong></td></tr>\n", section);
+ }
+ }
+ }
+
+ err = ferror(inFile);
+ if (err)
+ error("Failed reading from input file, error %d", err);
+
+ if (!phpOutput) {
+ /* Printf header */
+ fprintf(outFile, c_header, generationDate);
+ /* Now sort the MD5 table (this allows for binary searches) */
+ qsort(entriesBuffer, numEntries, entrySize, strcmp_wrapper);
+ /* Output the table */
+ for (i = 0; i < numEntries; ++i)
+ fprintf(outFile, entriesBuffer + i * entrySize);
+ /* Finally, print the footer */
+ fprintf(outFile, c_footer);
+ }
+
+ free(entriesBuffer);
+
+ return 0;
+}
diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt
new file mode 100644
index 0000000000..2da2ecef81
--- /dev/null
+++ b/tools/scumm-md5.txt
@@ -0,0 +1,406 @@
+Maniac Mansion
+ V1 DOS en 7f45ddd6dbfbf8f80c0c0efea4c295bc maniac
+ V2 DOS en 624cdb93654667c869d204a64af7e57f maniac Kirben, Andrea Petrucci
+ V2 (alt?) DOS en b250d0f9cc83f80ced56fe11a4fb057c maniac Andrea Petrucci
+ V2 DOS de 183d7464902d40d00800e8ee1f04117c maniac
+ V2 DOS es 0d1b69471605201ef2fa9cec1f5f02d2 maniac abnog, Andrea Petrucci
+ V2 (DOTT) DOS it 87f6e8037b7cc996e13474b491a7a98e maniac Andrea Petrucci
+ V2 DOS fr 114acdc2659a273c220f86ee9edb24c1 maniac Nicolas Sauz&egrave;de
+ V2 (DOTT) DOS fr 99a3699f80b8f776efae592b44b9b991 maniac Nicolas Sauz&egrave;de, Andrea Petrucci
+ V2 (demo) DOS en 40564ec47da48a67787d1f9bd043902a maniac
+ V2 Amiga en e781230da44a44e2f0770edb2b3b3633 maniac dhewg, Andrea Petrucci
+ V2 Amiga de 9bc548e179cdb0767009401c094d0895 maniac Norbert Lange
+ V2 Amiga fr ce7733f185b838e248927c7ba1a04204 maniac Tobias Fleischer
+ V2 Atari en a570381b028972d891052ee1e51dc011 maniac Andreas Bylund
+ V2 Atari fr dd30a53035393baa5a5e222e716559af maniac Andreas Bylund
+
+Zak McKracken and the Alien Mindbenders
+ V1 DOS en 7020931d5a2be0a49d68e7a1882363e4 zak
+ V1 (alt?) DOS en b23f7cd7c304d7dff08e92a96120d5b4 zak Andrea Petrucci
+ V2 Demo Atari en 8299d9b8a1b0e7b881bae7a9971dc5e2 zak
+ V2 DOS en 675d71151e9b5a968c8ce46d9fbf4cbf zak Kirben
+ V2 (alt?) DOS en debe337f73d660e951ece7c1f1c81add zak Andrea Petrucci
+ V2 (w/o copy protection) DOS de cdd760228cf1010c2903f37e788ea31c zak Max Horn
+ V2 (from 5\"25 floppies) DOS de d06fbe28818fef7bfc45c2cdf0c0849d zak Nicolas Sauz&egrave;de, Andrea Petrucci
+ V2 DOS fr 52a4bae0746a11d7b1e8554e91a6645c zak Andrea Petrucci
+ V2 DOS it 75ba23fff4fd63fa446c02864f2a5a4b zak Antti Leimi, Andrea Petrucci
+ V2 (alt?) DOS it 1900e501a52fbf55bde6e4196f6d2aa6 zak Andrea Petrucci
+ V2 Amiga en e94c7cc3686fce406d3c91b5eae5a72d zak dhweg
+ V2 Amiga de 6027e9ca9c35746d95dee2068cec17e5 zak Norbert Lange
+ V2 Amiga fr 91469353f7be1b122fa88d23480a1320 zak Tobias Fleischer
+ V2 Amiga it 27b3a4224ad63d5b04627595c1c1a025 zak Andrea Petrucci
+ V2 Atari fr 613f64f78ea26c7353b2a5940eb61d6a zak Andreas Bylund
+ FM-TOWNS FM-TOWNS en 2d4536a56e01da4b02eb021e7770afa2 zakTowns
+ FM-TOWNS FM-TOWNS jp ce3edc99cd4f478c5b37104d70c68ca5 zakTowns khalek
+ FM-TOWNS (alt?) FM-TOWNS jp 1ca86e2cf9aaa2068738a1e5ba477e60 zakTowns Andrea Petrucci
+
+Indiana Jones and the Last Crusade
+ EGA (1.0 7/09/89) DOS en 5fbe557049892eb4b709d90916ec97ca indy3EGA
+ EGA (1.3 8/14/89) DOS en 6b3ec67da214f558dc5ceaa2acd47453 indy3EGA tsuteiuQ, Andrea Petrucci
+ EGA DOS de 6f6ef668c608c7f534fea6e6d3878dde indy3EGA dhewg
+ EGA DOS fr 66236cd1aec24e1d4aff4c4cc93b7e18 indy3EGA Andrea Petrucci
+ EGA DOS it d62d248c3df6ec177405e2cb23d923b2 indy3EGA Andrea Petrucci
+ EGA DOS es ce7fd0c382389a6791fc3e199c117ef4 indy3EGA abnog
+ EGA (alt?) DOS es 86be8ada36371d4fdc35659d0e912a26 indy3EGA Andrea Petrucci
+
+ EGA Mac en 1dd7aa088e09f96d06818aa9a9deabe0 indy3EGA
+ EGA Amiga en 9c0fee288ad564a7d25ec3e841810d79 indy3EGA dhewg
+ EGA Amiga de 330f631502e381a4e199a3f7cb483c20 indy3EGA dhewg
+ EGA Amiga fr e689bdf67f98b1d760ce4487ec0e8d06 indy3EGA Gerald Vincent
+ EGA Amiga it df03ee021aa9b81d90cab9c26da07614 indy3EGA Andrea Petrucci
+ EGA Atari en 157367c3c21e0d03a0cba44361b4cf65 indy3EGA Andreas Bylund
+ EGA Atari fr 0f9c7a76657f0840b8f7ccb5bffeb9f4 indy3EGA Andreas Bylund
+ EGA Demo DOS en b597e0403cc0002f69170e6caba7edd9 indy3EGA
+
+ VGA DOS All 1875b90fade138c9253a8e967007031a indy3
+ VGA DOS de 399b217b0c8d65d0398076da486363a9 indy3
+ VGA DOS it 17b5d5e6af4ae89d62631641d66d5a05 indy3 Andrea Petrucci
+
+ FM-TOWNS FM-TOWNS en 04687cdf7f975a89d2474929f7b80946 indy3towns
+ FM-TOWNS FM-TOWNS jp 3a0c35f3c147b98a2bdf8d400cfc4ab5 indy3towns Paul Priest, Andrea Petrucci
+
+Loom
+ Demo DOS en 5a35e36fd777e9c37a49c5b2faca52f9 loom
+ Floppy Mac en 6f0be328c64d689bb606d22a389e1b0f loom
+ Floppy v1.0 DOS en 28ef68ee3ed76d7e2ee8ee13c15fbd5b loom
+ Floppy v1.0 alternative DOS en 73e5ab7dbb9a8061cc6d25df02dbd1e7 loom Andrea Petrucci
+ Floppy (v1.1 16 Mar 90) DOS en 37f56ceb13e401a7ac7d9e6b37fecaf7 loom Kirben, Andrea Petrucci
+ Floppy (v1.1 29 Mar 90) DOS en 22f4ea88a09da12df9308ba30bcb7d0f loom James Grosbeck
+ Floppy DOS de fa127d7c4bb47d05bb1c33ddcaa9f767 loom
+ Floppy DOS fr b886b0a5d909c7158a914e1d7c1c6c65 loom Andrea Petrucci
+ Floppy DOS it c3df37df9d3b481b45f75283a9907c47 loom Andrea Petrucci
+ Floppy DOS es 2a208ffbcd0e83e86f4356e6f64aa6e1 loom abnog, Andrea Petrucci
+ Floppy DOS hb 187d315f6b5168f68680dfe8c3d76a3e loom
+ Floppy Amiga en 4dc780f1bc587a193ce8a97652791438 loom Antti Leimi, Andrea Petrucci
+ Floppy Amiga de 2fe369ad70f52a8cf7ad6077ee64f81a loom Norbert Lange
+ Floppy (same as IT?!?) Amiga fr 39cb9dec16fa16f38d79acd80effb059 loom Gerald Vincent
+ Floppy (same as FR?!?) Amiga it 39cb9dec16fa16f38d79acd80effb059 loom Andrea Petrucci
+ Floppy Atari de c24c490373aeb48fbd54caa8e7ae376d loom Andreas Bylund
+ Talkie/CD DOS en 5d88b9d6a88e6f8e90cded9d01b7f082 loomcd
+ FM-TOWNS FM-TOWNS en c5d10e190d4b4d59114b824f2fdbd00e loomTowns dhewg, Andrea Petrucci
+ FM-TOWNS FM-TOWNS jp 31b8fda4c8c7413fa6b39997e776eba4 loomTowns khalek, Andrea Petrucci
+
+The Secret of Monkey Island
+ EGA (4 disk) DOS en 1d05cd189e4908f79b57e78a4402f292 monkeyega Andrea Petrucci
+ EGA (8 disk) DOS en 49210e124e4c2b30f1290a9ef6306301 monkeyega
+ EGA (8 disk) DOS de fc6b6148e80d67939d9a18697c0f626a monkeyega ghoostkilla
+ EGA (8 disk) DOS fr 1dd3c11ea4439adfe681e4e405b624e1 monkeyega Andrea Petrucci
+ EGA (4 disk) DOS it 477dbafbd66a53c98416dc01aef019ad monkeyega Andrea Petrucci
+ EGA (8 disk) DOS es 910e31cffb28226bd68c569668a0d6b4 monkeyega Andrea Petrucci
+ EGA Atari fr 9e5e0fb43bd22f4628719b7501adb717 monkeyega Andreas Bylund
+ EGA Demo DOS en 71523b539491527d9860f4407faf0411 monkeyega
+ EGA Demo DOS de 771bc18ec6f93837b839c992b211904b monkeyega khalek
+
+ VGA (4 disk) DOS en 15e03ffbfeddb9c2aebc13dcb2a4a8f4 monkeyvga
+ VGA (8 disk) DOS en c7890e038806df2bb5c0c8c6f1986ea2 monkeyvga Andrea Petrucci
+ VGA (4 disk) DOS de d0b531227a27c6662018d2bd05aac52a monkeyvga
+ VGA (4 disk) DOS es 45152f7cf2ba8f43cf8a8ea2e740ae09 monkeyvga
+ VGA (4 disk) DOS it 66fd5ff9a810dfeb6d6bdada18221140 monkeyvga Andrea Petrucci
+ VGA Amiga en 6c2bff0e327f2962e809c2e1a82d7309 monkeyvga dhweg
+ VGA Amiga de 319a4dde52c7960b5aae8a1ec348d918 monkeyvga ghoostkilla
+ VGA (alt?) Amiga de 0a212fa35fa8421f31c1f3961272caf0 monkeyvga Andreas Bylund
+ VGA Amiga es 870d1e3c86bc50846d808d14a36b4e08 monkeyvga Andreas Bylund
+ VGA Amiga fr 3433be9866ca4261b2d5d25374e3f243 monkeyvga Gerald Vincent
+ VGA Amiga it fb66aa42de21675116346213f176a366 monkeyvga Andrea Petrucci
+ VGA Demo Amiga en 54a936ad06161ff7bfefcb96200f7bff monkeyvga khalek
+
+ CD DOS en 2d1e891fe52df707c30185e52c50cd92 monkey
+ CD DOS de 305d3dd57c96c65b017bc70c8c7cfb5e monkey
+ CD DOS es f049e38c1f8302b5db6170f1872af89a monkey Andrej Sinicyn, Andrea Petrucci
+ CD DOS it da6269b18fcb08189c0aa9c95533cce2 monkey Andrej Sinicyn, Andrea Petrucci
+ CD DOS fr aa8a0cb65f3afbbe2c14c3f9f92775a3 monkey Andrej Sinicyn, Andrea Petrucci
+
+ - DOS fr aa8a0cb65f3afbbe2c14c3f9f92775a3 monkey1 Nicolas Sauz&egrave;de
+ - Mac en 2ccd8891ce4d3f1a334d21bff6a88ca2 monkey1 Lars N&aelig;sbye Christensen
+ - SEGA en c13225cb1bbd3bc9fe578301696d8021 game
+
+ FM-TOWNS FM-TOWNS en 8eb84cee9b429314c7f0bdcf560723eb monkey Paul Priest, Andrea Petrucci
+ FM-TOWNS FM-TOWNS jp e17db1ddf91b39ca6bbc8ad3ed19e883 monkey Paul Priest, Andrea Petrucci
+
+Misc demos
+ Passport to Adventure DOS en e6cd81b25ab1453a8a6d3482118c391e pass
+
+ indy/loom non-interactive FM-TOWNS en 2d388339d6050d8ccaa757b64633954e zakTowns khalek
+ zak/loom non-interactive FM-TOWNS en 77f5c9cc0986eb729c1a6b4c8823bbae zakTowns khalek
+ indy/zak non-interactive FM-TOWNS en 3938ee1aa4433fca9d9308c9891172b1 zakTowns khalek
+
+Monkey Island 2: LeChuck's revenge
+ - Amiga en 132bff65e6367c09cc69318ce1b59333 monkey2
+ - Amiga de da669b20271b85182e9c17a2a37ea02e monkey2 Andreas Bylund, Norbert Lange
+ - Amiga es 6ea966b4d660c870b9ee790d1fbfc535 monkey2 Andreas Bylund
+ - Amiga fr c30ef068add4277104243c31ce46c12b monkey2 Andreas Bylund
+ - Amiga it 11ddf1fde76e3156eb3a38da213f484e monkey2 Andrea Petrucci
+ - Mac en 4cb9c3618f71668f8e4346c8f323fa82 monkey2
+ - (alt?) Mac en e246e02db9630533a40d99c9f54a8e01 monkey2 Lars N&aelig;sbye Christensen
+ - DOS en 3686cf8f89e102ececf4366e1d2c8126 monkey2
+ - DOS de 6886e5d08cee329b1f2e743ae2e3ceed monkey2
+ - DOS fr 8e4ee4db46954bfe2912e259a16fad82 monkey2 Nicolas Sauz&egrave;de, Andrea Petrucci
+ CD DOS it 69ea626f1f87eecb78ea0d6c6b983a1d monkey2 Andrea Petrucci
+ Floppy DOS it bd126753de619a495f9f22adc951c8d5 monkey2 Andrea Petrucci
+ - DOS es 7974365d3dc0f43a2748c975f91ff042 monkey2 Andrea Petrucci
+ FM-TOWNS FM-TOWNS en da09e666fc8f5b78d7b0ac65d1a3b56e monkey2 dhewg, Andrea Petrucci
+ FM-TOWNS FM-TOWNS jp 430bc518017b6fac046f58bab6baad5d monkey2 Antti Leimi, Andrea Petrucci
+ Demo (non-interactive) DOS en 387a544b8b10b26912d8413bab63a853 mi2demo khalek
+
+Indiana Jones and the Fate of Atlantis
+ Talkie DOS en 182344899c2e2998fca0bebcd82aa81a atlantis
+ Talkie Mac en 1a6e5ae2777a6a33f06ffc0226210934 atlantis Scott Summers
+
+ Non-Talkie DOS en c63ee46143ba65f9ce14cf539ca51bd7 atlantis Andrea Petrucci
+ Non-Talkie DOS de 1fbebd7b2b692df5297870447a80cfed atlantis
+ Non-Talkie DOS fr edfdb24a499d92c59f824c52987c0eec atlantis Nicolas Sauz&egrave;de, Andrea Petrucci
+ Non-Talkie DOS es 9bd2a8f72613e715c199246dd511e10f atlantis abnog, Andrea Petrucci
+ Non-Talkie DOS it 8f3758ff98c9c5d78e5d635222cad026 atlantis Andrea Petrucci
+
+ Non-Talkie Amiga en 3a03dab514e4038df192d8a8de469788 atlantis dhewg
+ Non-Talkie Amiga de 4f267a901719623de7dde83e47d5b474 atlantis ghoostkilla
+ Non-Talkie Amiga de e534d29afb3c6e0ee9dc3d53c5956714 atlantis Tobias Fleischer
+ Non-Talkie Amiga it 5798972220cd458be2626d54c80f71d7 atlantis Andrea Petrucci
+
+ Non-Talkie Mac en d6dd0646404768a63e963891a96daadd atlantis Fingolfin
+ Non-Talkie Mac en 06b187468113f9ae5a400b148a847fac atlantis Lars N¾sbye Christensen
+
+ FM-TOWNS FM-TOWNS en c7be10f775404fd9785a8b92a06d240c indy4 dhewg, Andrea Petrucci
+ FM-TOWNS FM-TOWNS jp 4d34042713958b971cb139fba4658586 indy4 Andrea Petrucci
+ FM-TOWNS Demo FM-TOWNS jp 28d24a33448fab6795850bc9f159a4a2 indydemo khalek
+ Demo DOS en 035deab53b47bc43abc763560d0f8d4b playfate
+ Demo (non-interactive) DOS en 99b6f822b0b2612415407865438697d6 fate
+
+Day Of The Tentacle
+ Floppy Version A ? All? en acad97ab1c6fc2a5b2d98abf6db4a190 tentacle
+ Floppy Version B ? DOS en 2723fea3dae0cb47768c424b145ae0e7 tentacle Andrej Sinicyn, Andrea Petrucci
+ Floppy DOS de 57b0d89af79befe1cabce3bece869e7f tentacle Andrej Sinicyn, Andrea Petrucci
+ Floppy DOS fr 92b078d9d6d9d751da9c26b8b3075779 tentacle Nicolas Sauz&egrave;de, Andrea Petrucci
+ Floppy DOS it 50fcdc982a25063b78ad46bf389b8e8d tentacle Andrea Petrucci
+ Floppy DOS es ae94f110a14ce71fc515d5b648827a8f tentacle abnog, Andrea Petrucci
+ Talkie All? en 4167a92a1d46baa4f4127d918d561f88 tentacle
+ Talkie All? de 6e959d65358eedf9b68b81e304b97fa4 tentacle
+ Talkie ? All? fr 8aa05d3cdb0e795436043f0546af2da2 tentacle Andrea Petrucci
+ Talkie All? it 4fbbe9f64b8bc547503a379a301183ce tentacle Andrea Petrucci
+ Talkie All? es 883af4b0af4f77a92f1dcf1d0a283140 tentacle Andrea Petrucci
+ Demo DOS en c83079157ec765a28de445aec9768d60 dottdemo
+
+Sam &amp; Max
+ Non-Talkie DOS en a3036878840720fbefa41e6965fa4a0a samnmax Andrea Petrucci
+ Non-Talkie (alt?) DOS en 3b301b7892f883ce42ab4be6a274fea6 samnmax Andrea Petrucci
+ Non-Talkie DOS de f27b1ba0eadaf2a6617b2b58192d1dbf samnmax dhewg, Andrea Petrucci
+ Non-Talkie DOS fr ef347474f3c7be3b29584eaa133cca05 samnmax Nicolas Sauz&egrave;de, Andrea Petrucci
+ Non-Talkie DOS it b289a2a8cbedbf45786e0b4ad2f510f1 samnmax Andrea Petrucci
+ Non-Talkie DOS es fc53ce0e5f6562b1c1e1b4b8203acafb samnmax Andrea Petrucci
+ Talkie All? en d917f311a448e3cc7239c31bddb00dd2 samnmax
+ Talkie All? de 0fb73eddfcf584c02ba097984df131ba samnmax
+ Talkie All? fr 7edd665bbede7ea8b7233f8e650be6f8 samnmax Andrea Petrucci
+ Talkie All? it 0f6f2e716ba896a44e5059bba1de7ca9 samnmax Andrea Petrucci
+ Talkie All? es 4ba7fb331296c283e73d8f5b2096e551 samnmax Andrea Petrucci
+ Demo DOS en d9d0dd93d16ab4dec55cabc2b86bbd17 samdemo
+ Demo Mac en 0425954a9db5c340861672892c3e678d samdemo
+
+ interactive Demo DOS en c3196c5349e53e387aaff1533d95e53a snmdemo
+ Interactive WIP Demo DOS en 0e4c5d54a0ad4b26132e78b5ea76642a snmidemo
+
+Full Throttle
+ Version A All? en 09820417db26687bb7fe0c83cc4c553b ft
+ Version B All? en 60ba818dc3bede86d40357e3913f8505 ft sev
+
+ - All? de 8bdb0bf87b5e303dd35693afb9351215 ft dhewg
+ - All? es e72bb4c2b613db2cf50f89ff6350e70a ft
+ - All? ru 55e4cc866ff9046824e1c638ba2b8c7f ft sev
+ - All? it 55518cd73cf9c6d23ea29c51ee06bdfe ft delfino
+ - All? fr 4bedb49943df95a9c900a5a82ccbe9de ft cyx
+
+ Demo DOS en 32a433dea56b86a55b59e4ff7d755711 ftpcdemo
+ Demo Mac en 9d7b67be003fea60be4dcbd193611936 ftdemo
+
+The Dig
+ - All All d8323015ecb8b10bf53474f6e6b0ae33 dig
+ - All ru d62047a6729349ab36f7ee065bf26509 dig sev
+ Demo All en 362c1d281fb9899254cda66ad246c66a digdemo
+
+Curse of Monkey Island
+ - All All fe60d6b5ff51b0553ac59963123b5777 comi
+ Demo All All 8fec68383202d38c0d25e9e3b757c5df comidemo
+
+Backyard Baseball 2001
+ Demo Windows en a194f15f51ee62badab74b9e7da97693 bb2demo khalek, sev
+
+Backyard Football 2002
+ Demo Windows en 5bd335265a61caa3d78956ad9f88ba23 FOOTDEMO sev
+
+Big Thinkers: Kindergarten
+ - Windows en 92fc0073a4cf259ff36070ecb8628ba8 thinkerk Kirben
+ Demo All en 695fe0b3963333b7e15b37514db3c745 kinddemo khalek, sev
+
+Big Thinkers First Grade
+ Demo Windows en 0f5935bd5e88ba6f09e558d64459746d 1grademo khalek
+
+Blue's ABC Time
+ Demo Windows en 7ddeaf52c8b9a50551ce0aa2ac811d07 BluesABCTimeDemo khalek, sev
+ Demo Windows en 810a9da887aefa597b0cf3c77d262897 BluesABCTimeDemo sev
+
+Fatty Bears Birthday Surprise
+ Demo DOS en 47e75b1bdcb44c78cb94883d1731ccf8 fbdemo khalek
+ Demo Windows en 22c9eb04455440131ffc157aeb8d40a8 fbdemo khalek
+ Demo Mac en 6df20c50c1ab19799de9be7ae7716881 TODO khalek
+ - DOS en 3824e60cdf639d22f6df92a03dc4b131 fbear khalek
+ - Windows en 179879b6e35c1ead0d93aab26db0951b fbear khalek
+ - Mac en 3df6ead57930488bc61e6e41901d0e97 Fatty Bear khalek
+
+Fatty Bears Fun Pack
+ - DOS hb f06e66fd45b2f8b0f4a2833ff4476050 fbpack
+
+Freddi Fish 1: The Case of the Missing Kelp Seeds
+ - All en df047cc4792150f601290357566d36a6 freddi khalek
+ - Windows ru d4cccb5af88f3e77f370896e9ba8c5f9 freddi sev
+ Demo Windows en 084ed0fa98a6d1e9368d67fe9cfbd417 freddemo khalek
+ Demo Windows en 0855496dde35356b1a9691e22ba84cdc freddemo khalek
+ Demo Windows en 566165a7338fa11029e7c14d94fa70d0 freddemo khalek
+ Demo Mac en c8aac5e3e701874e2fa4117896f9e1b1 Freddi Demo khalek, sev
+
+Freddi Fish 2: The Case of the Haunted Schoolhouse
+ - Windows en 51305e929e330e24a75a0351c8f9975e freddi2 Kirben
+ - Windows All 5057fb0e99e5aa29df1836329232f101 freddi2 sev
+ - Windows nl ac62d50e39492ee3738b4e83a5ac780f freddi2 joostp
+ Demo All en fc8d197a22146e74766e9cb0cfcaf1da ff2-demo khalek, sev
+ Demo Windows en d37c55388294b66e53e7ced3af88fa68 ffhsdemo khalek
+
+Freddi Fish 3: The Case of the Stolen Conch Shell
+ - Windows All 8368f552b1e3eba559f8d559bcc4cadb freddi3 Kirben, sev
+ Demo All en cb1559e8405d17a5a278a6b5ad9338d1 f3-mdemo khalek, sev
+
+Freddie Fish 4: The Case of the Hogfish Rustlers of Briny Gulch
+ - Windows All 4f580a021eee026f3b4589e17d130d78 freddi4 Kirben, sev
+ Demo Windows en 7c2e76087027eeee9c8f8985f93a1cc5 f4-demo khalek
+ Demo Windows en c25755b08a8d0d47695e05f1e2111bfc f4-demo sev
+ Demo Windows en ebd324dcf06a4c49e1ba5c231eee1060 f4-demo sev
+ Demo Windows nl 16effd200aa6b8abe9c569c3e578814d ff4demo joostp
+
+Freddi Fish 5: The Case of the Creature of Coral Cave
+ - Windows en 590e6546aacd0d374b7f3a4f53013ab1 freddicove cyx
+ - Windows ru 21abe302e1b1e2b66d6f5c12e241ebfd freddicove sev
+ Demo Windows nl 6b257bb2827dd894b8109a50a1a18b5a FF5Demo Kirben
+
+Freddi Fish and Luther's Water Worries
+ - Windows ru 2012f854d83d9cc6f73b2b544cd8bbf8 water sev
+ - Windows en 4ba37f835be11a59d969f90f272f575b water Kirben
+
+Freddi Fish and Luther's Maze Madness
+ - Windows en 4f04b321a95d4315ce6d65f8e1dd0368 maze Kirben
+
+Humongous Interactive Catalog
+ - Windows en 11e6e244078ff09b0f3832e35420e0a7 catalog khalek, sev
+ - Windows en 037385a953789190298494d92b89b3d0 catalog2 khalek, sev
+
+Let's Explore the Farm with Buzzy
+ - Windows en a85856675429fe88051744f755b72f93 farm Kirben
+ - Mac en fbbbb38a81fc9d6a61d509278390a290 The Farm khalek
+ Demo Windows en 8d479e36f35e80257dfc102cf4b8a912 farmdemo khalek, sev
+ Demo Windows en bf8b52fdd9a69c67f34e8e9fec72661c farmdemo khalek, sev
+
+Let's Explore the Airport with Buzzy
+ - Windows en 07433205acdca3bc553d0e731588b35f airport Kirben
+ Demo Windows en 86c9902b7bec1a17926d4dae85beaa45 airdemo khalek
+ Demo Windows en e144f5f49d9241d2a9dee2576b3d09cb airdemo khalek
+ Demo Windows en 8ffd618a776a4c0d8922bb28b09f8ce8 airdemo khalek
+ Demo Mac en 7ea2da67ebabea4ac20cee9f4f9d2934 Airport Demo khalek
+
+Let's Explore the Jungle with Buzzy
+ - Windows en 8801fb4a1200b347f7a38523339526dd jungle Kirben
+
+Pajama Sam 1: No Need to Hide When It's Dark Outside
+ - All en 672dec94b82f7f0877ebb5b5cf7f4bc1 pajama khalek
+ - Windows nl 4fa6870d9bc8c313b65d54b1da5a1891 pajama joostp
+ Demo All en f237bf8a5ef9af78b2a6a4f3901da341 pjs-demo khalek, sev
+ Demo Windows en d7ab7cd6105546016e6a0d46fb36b964 pjsamdemo khalek
+
+Pajama Sam 2: Thunder and Lightning Aren't so Frightening
+ - Windows en d4e79c3d8645b8266cd78c325bc35154 pajama2 Kirben
+ Demo All en 36a6750e03fb505fc19fc2bf3e4dbe91 pj2demo sev
+
+Pajama Sam 3: You Are What You Eat From Your Head to Your Feet
+ - Windows en f7711f9264d4d43c2a1518ec7c10a607 pajama3 Kirben
+ Demo Windows en a654fb60c3b67d6317a7894ffd9f25c5 pj3-demo sev
+ Demo Windows en a9f2f04b1ecaab9495b59befffe9bf88 pj3-demo sev
+ Demo Windows en cf90b4db5486ef798db78fe6fbf897e5 pj3-demo khalek
+ Demo Windows en d7ab7cd6105546016e6a0d46fb36b964 PjSamDemo khalek, sev
+ Demo All nl f08145577e4f13584cc90b3d6e9caa55 pj3demo joostp
+
+Pajama Sam's Lost & Found
+ - Windows en ed361270102e355afe5236954216aba2 lost Kirben
+ Demo Windows en a2bb6aa0537402c1b3c2ea899ccef64b smaller Kirben
+
+Pajama Sam's Sock Works
+ - Windows en 5e8fb66971a60e523e5afbc4c129c0e8 socks Kirben
+
+Putt-Putt Enters the Race
+ - Windows en 981e1e1891f2be7e25a01f50ae55a5af puttrace
+ Demo All en 0ac41e2e3d2174e5a042a6b565328dba racedemo sev
+ Demo All nl aaa587701cde7e74692c68c1024b85eb racedemo joostp
+
+Putt-Putt Goes To The Moon
+ Demo DOS en aa6a91b7f6f119d1b7b1f2a4c9e24d59 moondemo
+ Demo Windows en 9c143c5905055d5df7a0f014ab379aee moondemo khalek
+ Demo Mac en 4af4a6b248103c1fe9edef619677f540 moondemo khalek
+ - DOS en 780e4a0ae2ff17dc296f4a79543b44f8 puttmoon khalek
+ - Windows en 9c92eeaf517a31b7221ec2546ab669fd puttmoon khalek
+ - Mac en 9dc02577bf50d4cfaf3de3fbac06fbe2 Putt-Putt Moon khalek
+
+Putt-Putt Joins the Circus
+ - All en ab0693e9324cfcf498fdcbb12acf8bb4 puttcircus sev
+ Demo All en a7cacad9c40c4dc9e1812abf6c8af9d5 circdemo Kirben, sev
+
+Putt-Putt Joins The Parade
+ Demo DOS en 31aa57f460a3d12429f0552a46a90b39 puttdemo
+ Demo Windows en 37ff1b308999c4cca7319edfcc1280a0 puttdemo khalek
+ Demo Mac en f40a7f495f59188ca57a9d1d50301bb6 puttdemo khalek
+ - DOS en 9708cf716ed8bcc9ff3fcfc69413b746 puttputt khalek
+ - Windows en 6a30a07f353a75cdc602db27d73e1b42 puttputt khalek
+ - Mac en 684732efb5799c0f78804c99d8de9aba Putt-Putt Parade khalek
+ - 3DO en 7e151c17adf624f1966c8fc5827c95e9 puttputt khalek
+
+Putt-Putt Saves the Zoo
+ - Windows en 1005456bfe351c1b679e1ff2dc2849e9 puttzoo khalek
+ - Windows en 92e7727e67f5cd979d8a1070e4eb8cb3 puttzoo cyx
+ - Windows nl c3b22fa4654bb580b20325ebf4174841 puttzoo joostp
+ - Mac en 58fdf4c7ad13540a734e18f8584cad89 Putt-Putt Saves the Zoo khalek
+ Demo Windows en 1005456bfe351c1b679e1ff2dc2849e9 puttzoo khalek
+ Demo Windows en f3d55aea441e260e9e9c7d2a187097e0 zoodemo khalek
+ Demo Windows en de4efb910210736813c9a1185384bace zoodemo khalek
+ Demo Mac en 3486ede0f904789267d4bcc5537a46d4 Puttzoo Demo khalek
+
+Putt-Putt Travels Through Time
+ - All? en 2108d83dcf09f8adb4bc524669c8cf51 PuttTime
+ Demo All en 4e5867848ee61bc30d157e2c94eee9b4 timedemo khalek, sev
+ Demo Windows en 0ab19be9e2a3f6938226638b2a3744fe putttime-demo khalek
+
+Putt-Putt and Pep's Balloon-O-Rama
+ - Windows en 08cc5c3eedaf72ebe12734eee94f7fa2 balloon Kirben
+
+Putt-Putt and Pep's Dog on a Stick
+ - Windows en d4b8ee426b1afd3e53bc0cf020418cf6 dog sev
+ - Windows en eae95b2b3546d8ba86ae1d397c383253 dog Kirben
+
+Putt-Putts Fun Pack
+ - DOS en 46b53fd430adcfbed791b48a0d4b079f funpack khalek
+
+Spy Fox 1: Dry Cereal
+ - Windows en 3de99ef0523f8ca7958faa3afccd035a spyfox Kirben
+ - Windows en 6bf70eee5de3d24d2403e0dd3d267e8a spyfox khalek
+ - Windows nl 9bda5fee51d2fda5253d02c642016bf4 spyfox joostp
+ Demo All en 53e94115b55dd51d4b8ff0871aa1df1e foxdemo khalek, sev
+ Demo All en fbdd947d21e8f5bac6d6f7a316af1c5a spydemo sev
+ Demo Windows en 9d4ab3e0e1d1ebc6ba8a6a4c470ed184 spydemo khalek
+
+Spy Fox 2: Some Assembly Required
+ - Windows en f79e60c17cca601e411f1f75e8ee9b5a spyfox2 Kirben
+ Demo Windows en 7222f260253f325c21fcfa68b5bfab67 sf2-demo Kirben
+ Demo All nl 1c792d28376d45e145cb916bca0400a2 sf2demo joostp
+
+Spy Fox 3: Operation Ozone
+ - Windows en 600abd3e9f47e63e670188b7e4e86ac7 spyozon Kirben
+ Demo Windows en ebd0b2c8a387f18887282afe6cad894a sf3-demo Kirben
+
+Spy Fox in Cheese Chase Game
+ - Windows en 589601b676c98b1c0c987bc031ab68b3 chase Kirben
+
+Spy Fox in Hold the Mustard
+ - Windows en 225e18566e810c634bf7de63e7568e3e mustard Kirben
diff --git a/tools/simon-md5.txt b/tools/simon-md5.txt
new file mode 100644
index 0000000000..bbe1c45c57
--- /dev/null
+++ b/tools/simon-md5.txt
@@ -0,0 +1,29 @@
+Simon the Sorcerer 1
+ - DOS en 465eed710cc242b2de7dc77edd467c4c simon1dos
+ - DOS en 48ce4ffda968cc7a38870c354571f92c simon1dos Kirben
+ - DOS fr bed9134804d96f72afa152b8ec5628c3 simon1dos
+ - DOS it c8f5b860a20dcc63915d94cf2bdcfa49 simon1dos
+ - DOS ru 3b22f3cc4ce9faa3f7830ab18235b04d simon1dos Kirben
+ - Windows en d22302abf44219f95d50f2faa807dd1a simon1talkie Kirben
+ - DOS de ecc01a02c9b97b49d0b4191a346b0940 simon1talkie SimSaw
+ - DOS en d545db8a0efae95a90b23da81aadb201 simon1talkie Kirben
+ - DOS fr 08bd7abefe9c44e43df396748640e531 simon1talkie jellby
+ - DOS hb 9d58f84988634d217c944cd4153a2a3b simon1talkie jellby
+ - DOS it 057eac98fc4d14dc7fd04341781b26b3 simon1talkie jellby
+ - DOS es e3712b3ed4429e736123a40276f533d7 simon1talkie jellby
+ - Amiga en ec5358680c117f29b128cbbb322111a4 simon1cd32 Kirben
+ AGA Amiga en 39e8f13ec29de1fcef98c81ca0a2ae57 simon1amiga
+ ECS Amiga en fa5651a5e5da0f3c89473dd62af095d8 simon1amiga
+ Demo DOS en 486f026593f894f5b6b346ef3984a7a0 simon1demo Kirben
+
+Simon the Sorcerer 2
+ - DOS en 27c8e7feada80c75b70b9c2f6088d519 simon2dos
+ - Windows de 9e858b3bb189c134c3a5f34c3385a8d3 simon2talkie DhWz
+ - Windows en bd85a8b5135592ada9cbeae49160f1d3 simon2talkie Kirben
+ - DOS de 3bdf85dc57c1abff8f05416b4571198f simon2talkie SimSaw
+ - DOS en 078b04da0974a40645b92baffdf2781e simon2talkie Kirben
+ - DOS fr c8ddd48919aa75423dd2d3e5864909df simon2talkie SimSaw
+ - DOS hb a3cbdd3450f9fccb0a9d8d6dc28f66fe simon2talkie
+ - DOS es 79a9d9357c15153c8c502dba73c3eac6 simon2talkie Samuel Suárez
+ Demo DOS en 1e11ddbad80c408031ae44a0cbce46bb simon2talkie Kirben
+ Demo DOS de 028c6240c9c8e190d86188238505c5e5 simon2talkie Kirben