summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordominik <dominik@openttd.org>2005-01-10 01:14:26 +0000
committerdominik <dominik@openttd.org>2005-01-10 01:14:26 +0000
commitaa261049f4d3c0977555e413ab7d9807c70eef02 (patch)
treefe347108b7efcb5f55d1b2ad4f319e3710006c27
parentc77e9231efe6f362f3ddd8d059ee3a5e4d340cc5 (diff)
downloadopenttd-aa261049f4d3c0977555e413ab7d9807c70eef02.tar.xz
(svn r1453) Feature: MD5 hash check for TTD files
The original TTD files are now checked with a MD5 sum to determine which version of the grf files is used and to warn about possible file corruptions. (Thanks to ledow for the original patch)
-rw-r--r--docs/Manual.txt2
-rw-r--r--docs/OSX_where_did_the_package_go.txt2
-rw-r--r--docs/Readme_Mandrake_Linux.txt2
-rw-r--r--readme.txt7
-rw-r--r--spritecache.c147
-rw-r--r--table/files.h51
-rw-r--r--ttd.c2
7 files changed, 162 insertions, 51 deletions
diff --git a/docs/Manual.txt b/docs/Manual.txt
index 7530691bf..44ba35f94 100644
--- a/docs/Manual.txt
+++ b/docs/Manual.txt
@@ -24,7 +24,7 @@ On BeOS, run ./configure and then use jam. There are a variaty of options you ca
On Windows, insert your "Transport Tycoon Deluxe for Windows 95" disk. You can use a DOS version, but your graphics will be purple. NB: Even if your version of Transport Tycoon Deluxe ran on Windows 95, it may still be the DOS version. Then run the OpenTTD installer.
On UNIX platforms; decompress your OpenTTD archive, or otherwise run the installer. You should be left with an OpenTTD directory on your system. In this directory, make a subdirectory called 'data', and into this place the sample.cat file and all the .grf files from the install CD of 'Transport Tycoon Deluxe for Windows 95".
-(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. Those filenames have to be uppercase to be detected correctly. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
+(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
If you want MIDI music, copy the 'gm' folder from the original game directory/CD to the OpenTTD folder.
diff --git a/docs/OSX_where_did_the_package_go.txt b/docs/OSX_where_did_the_package_go.txt
index 72c3e76d0..16f6f8522 100644
--- a/docs/OSX_where_did_the_package_go.txt
+++ b/docs/OSX_where_did_the_package_go.txt
@@ -19,6 +19,6 @@ trghr.grf
trgir.grf
trgtr.grf
-(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. Those filenames have to be uppercase to be detected correctly. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
+(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
You should also use the data folder to add any custom grf files if you like \ No newline at end of file
diff --git a/docs/Readme_Mandrake_Linux.txt b/docs/Readme_Mandrake_Linux.txt
index 838b862c9..2413aac1a 100644
--- a/docs/Readme_Mandrake_Linux.txt
+++ b/docs/Readme_Mandrake_Linux.txt
@@ -39,7 +39,7 @@ Copy the following files from Transport Tycoon Deluxe to openttd/data/
trgir.grf
trgtr.grf
-(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. Those filenames have to be uppercase to be detected correctly. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
+(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF, TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. A few minor graphical glitches with the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't look as nice as with the Windows graphics.)
4.) Compiling and running:
diff --git a/readme.txt b/readme.txt
index e12182af1..6b6b3d6ad 100644
--- a/readme.txt
+++ b/readme.txt
@@ -92,10 +92,9 @@ trgir.grf
trgtr.grf
(Alternatively you can use the TTD GRF files from the DOS version: TRG1.GRF,
-TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. Those filenames have to be uppercase
-to be detected correctly. A few minor graphical glitches with the DOS
-graphics remain. E.g. the autorail button in the rail toolbar doesn't look
-as nice as with the Windows graphics.)
+TRGC.GRF, TRGH.GRF, TRGI.GRF, TRGT.GRF. A few minor graphical glitches with
+the DOS graphics remain. E.g. the autorail button in the rail toolbar doesn't
+look as nice as with the Windows graphics.)
If you want music you need to copy the gm/ folder from Windows TTD into your
OpenTTD folder, not your data folder.
diff --git a/spritecache.c b/spritecache.c
index 8ea8b0411..758f09b4e 100644
--- a/spritecache.c
+++ b/spritecache.c
@@ -3,6 +3,7 @@
#include "gfx.h"
#include "fileio.h"
#include "newgrf.h"
+#include "md5.h"
#include <ctype.h>
#define SPRITECACHE_ID 0xF00F0006
@@ -55,31 +56,17 @@ static byte *_spritecache_ptr;
static uint32 _spritecache_size;
static int _compact_cache_counter;
+typedef struct MD5File {
+ const char * const filename; // filename
+ const md5_byte_t const hash[16]; // md5 sum of the file
+} MD5File;
+
typedef struct FileList {
- const char * const basic[4]; // grf files that always have to be loaded
- const char * const landscape[3]; // landscape specific grf files
+ const MD5File basic[4]; // grf files that always have to be loaded
+ const MD5File landscape[3]; // landscape specific grf files
} FileList;
-FileList files_dos = {
- { "TRG1.GRF",
- "TRGI.GRF",
- "signalsw.grf", //0x1320 - 0x1405 inclusive
- NULL },
- { "TRGC.GRF",
- "TRGH.GRF",
- "TRGT.GRF" },
-};
-
-FileList files_win = {
- { "TRG1R.GRF",
- "TRGIR.GRF",
- "signalsw.grf", //0x1320 - 0x1405 inclusive
- NULL },
- { "TRGCR.GRF",
- "TRGHR.GRF",
- "TRGTR.GRF" },
-};
-
+#include "table/files.h"
#include "table/landscape_sprite.h"
static const uint16 * const _landscape_spriteindexes[] = {
@@ -758,28 +745,103 @@ static const uint16 _openttd_grf_indexes[] = {
0xffff,
};
+/* FUNCTIONS FOR CHECKING MD5 SUMS OF GRF FILES */
+
+/* Check that the supplied MD5 hash matches that stored for the supplied filename */
+static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn)
+{
+ int i, matching_bytes=0;
+
+ /* Loop through each byte of the file MD5 and the stored MD5... */
+ for (i = 0; i < 16; i++)
+ {
+ if (file.hash[i] == digest[i])
+ matching_bytes++;
+ };
-/* Checks, if either the Windows files exist (TRG1R.GRF) or the DOS files (TRG1.GRF).
- * _use_dos_palette is set accordingly
- * WARNING! This is case-sensitive, therefore the file has to be uppercase for correct
- * detection. If neither are found, Windows palette is assumed. */
-static void CheckGrfFile()
+ /* If all bytes of the MD5's match (i.e. the MD5's match)... */
+ if (matching_bytes == 16) {
+ return true;
+ } else {
+ if (warn) printf("MD5 of %s is ****INCORRECT**** - File Corrupt.\n", file.filename);
+ return false;
+ };
+}
+
+/* Calculate and check the MD5 hash of the supplied filename.
+ * returns true if the checksum is correct */
+static bool FileMD5(const MD5File file, bool warn)
{
FILE *f;
+ char buf[MAX_PATH];
byte *s;
- s = str_fmt("%s%s", _path.data_dir, files_win.basic[0]);
- f = fopen(s, "r");
- if (f != NULL) {
- _use_dos_palette = false;
- return;
+ md5_state_t filemd5state;
+ int len=0;
+ md5_byte_t buffer[1024], digest[16];
+
+ // open file
+ sprintf(buf, "%s%s", _path.data_dir, file.filename);
+ f = fopen(buf, "rb");
+
+#if !defined(WIN32)
+ if (f == NULL) {
+ // make lower case and check again
+ for (s=buf + strlen(_path.data_dir) - 1; *s != 0; s++)
+ *s = tolower(*s);
+ f = fopen(buf, "rb");
}
+#endif
- s = str_fmt("%s%s", _path.data_dir, files_dos.basic[0]);
- f = fopen(s, "r");
if (f != NULL) {
+ md5_init(&filemd5state);
+ while ( (len = fread (buffer, 1, 1024, f)) )
+ md5_append(&filemd5state, buffer, len);
+
+ if (ferror(f))
+ if (warn) printf ("Error Reading from %s \n", buf);
+ fclose(f);
+
+ md5_finish(&filemd5state, digest);
+ return CheckMD5Digest(file, digest, warn);
+ } else { // file not found
+ return false;
+ }
+}
+
+/* Checks, if either the Windows files exist (TRG1R.GRF) or the DOS files (TRG1.GRF)
+ * by comparing the MD5 checksums of the files. _use_dos_palette is set accordingly.
+ * If neither are found, Windows palette is assumed.
+ *
+ * (Note: Also checks sample.cat for corruption) */
+void CheckExternalFiles()
+{
+ int i;
+ int dos=0, win=0; // count of files from this version
+
+ for (i=0; i<2; i++)
+ if ( FileMD5(files_dos.basic[i], true) )
+ dos++;
+ for (i=0; i<3; i++)
+ if ( FileMD5(files_dos.landscape[i], true) )
+ dos++;
+
+ for (i=0; i<2; i++)
+ if ( FileMD5(files_win.basic[i], true) )
+ win++;
+ for (i=0; i<3; i++)
+ if ( FileMD5(files_win.landscape[i], true) )
+ win++;
+
+ if ( !FileMD5(sample_cat_win, false) && !FileMD5(sample_cat_dos, false) )
+ printf("Your sample.cat file is corrupted or missing!");
+
+ if (win == 5) { // always use the Windows palette if all Windows files are present
+ _use_dos_palette = false;
+ } else if (dos == 5) { // else use the DOS palette if all DOS files are present
_use_dos_palette = true;
- return;
+ } else { // some files are missing, regardless of palette. Use Windows
+ _use_dos_palette = false;
}
}
@@ -801,9 +863,6 @@ static void LoadSpriteTables()
* invest that further. --octo
*/
- // Check if we have the DOS or Windows version of the GRF files
- CheckGrfFile();
-
files = _use_dos_palette?(&files_dos):(&files_win);
// Try to load the sprites from cache
@@ -813,14 +872,14 @@ static void LoadSpriteTables()
int load_index = 0;
- for(i=0; files->basic[i] != NULL; i++) {
- load_index += LoadGrfFile(files->basic[i], load_index, (byte)i);
+ for(i=0; files->basic[i].filename != NULL; i++) {
+ load_index += LoadGrfFile(files->basic[i].filename, load_index, (byte)i);
}
LoadGrfIndexed("openttd.grf", _openttd_grf_indexes, i++);
if (_sprite_page_to_load != 0)
- LoadGrfIndexed(files->landscape[_sprite_page_to_load-1], _landscape_spriteindexes[_sprite_page_to_load-1], i++);
+ LoadGrfIndexed(files->landscape[_sprite_page_to_load-1].filename, _landscape_spriteindexes[_sprite_page_to_load-1], i++);
LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++);
@@ -858,13 +917,13 @@ static void LoadSpriteTables()
//
// NOTE: the order of the files must be identical as in the section above!!
- for(i = 0; files->basic[i] != NULL; i++)
- FioOpenFile(i,files->basic[i]);
+ for(i = 0; files->basic[i].filename != NULL; i++)
+ FioOpenFile(i,files->basic[i].filename);
FioOpenFile(i++, "openttd.grf");
if (_sprite_page_to_load != 0)
- FioOpenFile(i++, files->landscape[_sprite_page_to_load-1]);
+ FioOpenFile(i++, files->landscape[_sprite_page_to_load-1].filename);
FioOpenFile(i++, "trkfoundw.grf");
FioOpenFile(i++, "canalsw.grf");
diff --git a/table/files.h b/table/files.h
new file mode 100644
index 000000000..56742c64e
--- /dev/null
+++ b/table/files.h
@@ -0,0 +1,51 @@
+/*
+ MD5 sums of graphics files
+
+ DOS -
+
+ TRG1.GRF 9311676280e5b14077a8ee41c1b42192
+ TRGC.GRF ed446637e034104c5559b32c18afe78d
+ TRGH.GRF ee6616fb0e6ef6b24892c58c93d86fc9
+ TRGI.GRF da6a6c9dcc451eec88d79211437b76a8
+ TRGT.GRF fcde1d7e8a74197d72a62695884b909e
+ SAMPLE.CAT 422ea3dd074d2859bb51639a6e0e85da
+
+ WINDOWS -
+
+ TRG1R.GRF b04ce593d8c5016e07473a743d7d3358
+ TRGCR.GRF 3668f410c761a050b5e7095a2b14879b
+ TRGHR.GRF 06bf2b7a31766f048baac2ebe43457b1
+ TRGIR.GRF 0c2484ff6be49fc63a83be6ab5c38f32
+ TRGTR.GRF de53650517fe661ceaa3138c6edb0eb8
+ SAMPLE.CAT 9212e81e72badd4bbe1eaeae66458e10
+*/
+
+
+FileList files_dos = {
+ {
+ { "TRG1.GRF", {0x93,0x11,0x67,0x62,0x80,0xe5,0xb1,0x40,0x77,0xa8,0xee,0x41,0xc1,0xb4,0x21,0x92} },
+ { "TRGI.GRF", {0xda,0x6a,0x6c,0x9d,0xcc,0x45,0x1e,0xec,0x88,0xd7,0x92,0x11,0x43,0x7b,0x76,0xa8} },
+ { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, //0x1320 - 0x1405 inclusive
+ { NULL }
+ },
+ { { "TRGC.GRF", {0xed,0x44,0x66,0x37,0xe0,0x34,0x10,0x4c,0x55,0x59,0xb3,0x2c,0x18,0xaf,0xe7,0x8d} },
+ { "TRGH.GRF", {0xee,0x66,0x16,0xfb,0x0e,0x6e,0xf6,0xb2,0x48,0x92,0xc5,0x8c,0x93,0xd8,0x6f,0xc9} },
+ { "TRGT.GRF", {0xfc,0xde,0x1d,0x7e,0x8a,0x74,0x19,0x7d,0x72,0xa6,0x26,0x95,0x88,0x4b,0x90,0x9e} }
+ }
+};
+
+FileList files_win = {
+ {
+ { "TRG1R.GRF", {0xb0,0x4c,0xe5,0x93,0xd8,0xc5,0x01,0x6e,0x07,0x47,0x3a,0x74,0x3d,0x7d,0x33,0x58} },
+ { "TRGIR.GRF", {0x0c,0x24,0x84,0xff,0x6b,0xe4,0x9f,0xc6,0x3a,0x83,0xbe,0x6a,0xb5,0xc3,0x8f,0x32} },
+ { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, //0x1320 - 0x1405 inclusive
+ { NULL }
+ },
+ { { "TRGCR.GRF", {0x36,0x68,0xf4,0x10,0xc7,0x61,0xa0,0x50,0xb5,0xe7,0x09,0x5a,0x2b,0x14,0x87,0x9b} },
+ { "TRGHR.GRF", {0x06,0xbf,0x2b,0x7a,0x31,0x76,0x6f,0x04,0x8b,0xaa,0xc2,0xeb,0xe4,0x34,0x57,0xb1} },
+ { "TRGTR.GRF", {0xde,0x53,0x65,0x05,0x17,0xfe,0x66,0x1c,0xea,0xa3,0x13,0x8c,0x6e,0xdb,0x0e,0xb8} }
+ }
+};
+
+static MD5File sample_cat_win = { "SAMPLE.CAT", {0x92,0x12,0xe8,0x1e,0x72,0xba,0xdd,0x4b,0xbe,0x1e,0xae,0xae,0x66,0x45,0x8e,0x10} };
+static MD5File sample_cat_dos = { "SAMPLE.CAT", {0x42,0x2e,0xa3,0xdd,0x07,0x4d,0x28,0x59,0xbb,0x51,0x63,0x9a,0x6e,0x0e,0x85,0xda} };
diff --git a/ttd.c b/ttd.c
index ce245d8d0..d7b9a2614 100644
--- a/ttd.c
+++ b/ttd.c
@@ -545,6 +545,7 @@ void LoadIntroGame()
}
extern void DedicatedFork(void);
+extern void CheckExternalFiles();
int ttd_main(int argc, char* argv[])
{
@@ -638,6 +639,7 @@ int ttd_main(int argc, char* argv[])
}
DeterminePaths();
+ CheckExternalFiles();
#ifdef UNIX
// We must fork here, or we'll end up without some resources we need (like sockets)