53 static uint _sprite_lru_counter; |
54 static uint _sprite_lru_counter; |
54 static byte *_spritecache_ptr; |
55 static byte *_spritecache_ptr; |
55 static uint32 _spritecache_size; |
56 static uint32 _spritecache_size; |
56 static int _compact_cache_counter; |
57 static int _compact_cache_counter; |
57 |
58 |
|
59 typedef struct MD5File { |
|
60 const char * const filename; // filename |
|
61 const md5_byte_t const hash[16]; // md5 sum of the file |
|
62 } MD5File; |
|
63 |
58 typedef struct FileList { |
64 typedef struct FileList { |
59 const char * const basic[4]; // grf files that always have to be loaded |
65 const MD5File basic[4]; // grf files that always have to be loaded |
60 const char * const landscape[3]; // landscape specific grf files |
66 const MD5File landscape[3]; // landscape specific grf files |
61 } FileList; |
67 } FileList; |
62 |
68 |
63 FileList files_dos = { |
69 #include "table/files.h" |
64 { "TRG1.GRF", |
|
65 "TRGI.GRF", |
|
66 "signalsw.grf", //0x1320 - 0x1405 inclusive |
|
67 NULL }, |
|
68 { "TRGC.GRF", |
|
69 "TRGH.GRF", |
|
70 "TRGT.GRF" }, |
|
71 }; |
|
72 |
|
73 FileList files_win = { |
|
74 { "TRG1R.GRF", |
|
75 "TRGIR.GRF", |
|
76 "signalsw.grf", //0x1320 - 0x1405 inclusive |
|
77 NULL }, |
|
78 { "TRGCR.GRF", |
|
79 "TRGHR.GRF", |
|
80 "TRGTR.GRF" }, |
|
81 }; |
|
82 |
|
83 #include "table/landscape_sprite.h" |
70 #include "table/landscape_sprite.h" |
84 |
71 |
85 static const uint16 * const _landscape_spriteindexes[] = { |
72 static const uint16 * const _landscape_spriteindexes[] = { |
86 _landscape_spriteindexes_1, |
73 _landscape_spriteindexes_1, |
87 _landscape_spriteindexes_2, |
74 _landscape_spriteindexes_2, |
756 634, 634, // nordic char: Ø |
743 634, 634, // nordic char: Ø |
757 SPR_OPENTTD_BASE+62, SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // more icons |
744 SPR_OPENTTD_BASE+62, SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // more icons |
758 0xffff, |
745 0xffff, |
759 }; |
746 }; |
760 |
747 |
761 |
748 /* FUNCTIONS FOR CHECKING MD5 SUMS OF GRF FILES */ |
762 /* Checks, if either the Windows files exist (TRG1R.GRF) or the DOS files (TRG1.GRF). |
749 |
763 * _use_dos_palette is set accordingly |
750 /* Check that the supplied MD5 hash matches that stored for the supplied filename */ |
764 * WARNING! This is case-sensitive, therefore the file has to be uppercase for correct |
751 static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn) |
765 * detection. If neither are found, Windows palette is assumed. */ |
752 { |
766 static void CheckGrfFile() |
753 int i, matching_bytes=0; |
|
754 |
|
755 /* Loop through each byte of the file MD5 and the stored MD5... */ |
|
756 for (i = 0; i < 16; i++) |
|
757 { |
|
758 if (file.hash[i] == digest[i]) |
|
759 matching_bytes++; |
|
760 }; |
|
761 |
|
762 /* If all bytes of the MD5's match (i.e. the MD5's match)... */ |
|
763 if (matching_bytes == 16) { |
|
764 return true; |
|
765 } else { |
|
766 if (warn) printf("MD5 of %s is ****INCORRECT**** - File Corrupt.\n", file.filename); |
|
767 return false; |
|
768 }; |
|
769 } |
|
770 |
|
771 /* Calculate and check the MD5 hash of the supplied filename. |
|
772 * returns true if the checksum is correct */ |
|
773 static bool FileMD5(const MD5File file, bool warn) |
767 { |
774 { |
768 FILE *f; |
775 FILE *f; |
|
776 char buf[MAX_PATH]; |
769 byte *s; |
777 byte *s; |
770 |
778 |
771 s = str_fmt("%s%s", _path.data_dir, files_win.basic[0]); |
779 md5_state_t filemd5state; |
772 f = fopen(s, "r"); |
780 int len=0; |
|
781 md5_byte_t buffer[1024], digest[16]; |
|
782 |
|
783 // open file |
|
784 sprintf(buf, "%s%s", _path.data_dir, file.filename); |
|
785 f = fopen(buf, "rb"); |
|
786 |
|
787 #if !defined(WIN32) |
|
788 if (f == NULL) { |
|
789 // make lower case and check again |
|
790 for (s=buf + strlen(_path.data_dir) - 1; *s != 0; s++) |
|
791 *s = tolower(*s); |
|
792 f = fopen(buf, "rb"); |
|
793 } |
|
794 #endif |
|
795 |
773 if (f != NULL) { |
796 if (f != NULL) { |
|
797 md5_init(&filemd5state); |
|
798 while ( (len = fread (buffer, 1, 1024, f)) ) |
|
799 md5_append(&filemd5state, buffer, len); |
|
800 |
|
801 if (ferror(f)) |
|
802 if (warn) printf ("Error Reading from %s \n", buf); |
|
803 fclose(f); |
|
804 |
|
805 md5_finish(&filemd5state, digest); |
|
806 return CheckMD5Digest(file, digest, warn); |
|
807 } else { // file not found |
|
808 return false; |
|
809 } |
|
810 } |
|
811 |
|
812 /* Checks, if either the Windows files exist (TRG1R.GRF) or the DOS files (TRG1.GRF) |
|
813 * by comparing the MD5 checksums of the files. _use_dos_palette is set accordingly. |
|
814 * If neither are found, Windows palette is assumed. |
|
815 * |
|
816 * (Note: Also checks sample.cat for corruption) */ |
|
817 void CheckExternalFiles() |
|
818 { |
|
819 int i; |
|
820 int dos=0, win=0; // count of files from this version |
|
821 |
|
822 for (i=0; i<2; i++) |
|
823 if ( FileMD5(files_dos.basic[i], true) ) |
|
824 dos++; |
|
825 for (i=0; i<3; i++) |
|
826 if ( FileMD5(files_dos.landscape[i], true) ) |
|
827 dos++; |
|
828 |
|
829 for (i=0; i<2; i++) |
|
830 if ( FileMD5(files_win.basic[i], true) ) |
|
831 win++; |
|
832 for (i=0; i<3; i++) |
|
833 if ( FileMD5(files_win.landscape[i], true) ) |
|
834 win++; |
|
835 |
|
836 if ( !FileMD5(sample_cat_win, false) && !FileMD5(sample_cat_dos, false) ) |
|
837 printf("Your sample.cat file is corrupted or missing!"); |
|
838 |
|
839 if (win == 5) { // always use the Windows palette if all Windows files are present |
774 _use_dos_palette = false; |
840 _use_dos_palette = false; |
775 return; |
841 } else if (dos == 5) { // else use the DOS palette if all DOS files are present |
776 } |
|
777 |
|
778 s = str_fmt("%s%s", _path.data_dir, files_dos.basic[0]); |
|
779 f = fopen(s, "r"); |
|
780 if (f != NULL) { |
|
781 _use_dos_palette = true; |
842 _use_dos_palette = true; |
782 return; |
843 } else { // some files are missing, regardless of palette. Use Windows |
|
844 _use_dos_palette = false; |
783 } |
845 } |
784 } |
846 } |
785 |
847 |
786 static void LoadSpriteTables() |
848 static void LoadSpriteTables() |
787 { |
849 { |
799 * TODO: |
861 * TODO: |
800 * I think we can live entirely without Indexed GRFs, but I have to |
862 * I think we can live entirely without Indexed GRFs, but I have to |
801 * invest that further. --octo |
863 * invest that further. --octo |
802 */ |
864 */ |
803 |
865 |
804 // Check if we have the DOS or Windows version of the GRF files |
|
805 CheckGrfFile(); |
|
806 |
|
807 files = _use_dos_palette?(&files_dos):(&files_win); |
866 files = _use_dos_palette?(&files_dos):(&files_win); |
808 |
867 |
809 // Try to load the sprites from cache |
868 // Try to load the sprites from cache |
810 if (!HandleCachedSpriteHeaders(_cached_filenames[_opt.landscape], true)) { |
869 if (!HandleCachedSpriteHeaders(_cached_filenames[_opt.landscape], true)) { |
811 // We do not have the sprites in cache yet, or cache is disabled |
870 // We do not have the sprites in cache yet, or cache is disabled |
812 // So just load all files from disk.. |
871 // So just load all files from disk.. |
813 |
872 |
814 int load_index = 0; |
873 int load_index = 0; |
815 |
874 |
816 for(i=0; files->basic[i] != NULL; i++) { |
875 for(i=0; files->basic[i].filename != NULL; i++) { |
817 load_index += LoadGrfFile(files->basic[i], load_index, (byte)i); |
876 load_index += LoadGrfFile(files->basic[i].filename, load_index, (byte)i); |
818 } |
877 } |
819 |
878 |
820 LoadGrfIndexed("openttd.grf", _openttd_grf_indexes, i++); |
879 LoadGrfIndexed("openttd.grf", _openttd_grf_indexes, i++); |
821 |
880 |
822 if (_sprite_page_to_load != 0) |
881 if (_sprite_page_to_load != 0) |
823 LoadGrfIndexed(files->landscape[_sprite_page_to_load-1], _landscape_spriteindexes[_sprite_page_to_load-1], i++); |
882 LoadGrfIndexed(files->landscape[_sprite_page_to_load-1].filename, _landscape_spriteindexes[_sprite_page_to_load-1], i++); |
824 |
883 |
825 LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++); |
884 LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++); |
826 |
885 |
827 load_index = SPR_CANALS_BASE; |
886 load_index = SPR_CANALS_BASE; |
828 load_index += LoadGrfFile("canalsw.grf", load_index, i++); |
887 load_index += LoadGrfFile("canalsw.grf", load_index, i++); |
856 // open it can not read. So all files that are in the 'if'-section |
915 // open it can not read. So all files that are in the 'if'-section |
857 // above should also be in this 'else'-section. |
916 // above should also be in this 'else'-section. |
858 // |
917 // |
859 // NOTE: the order of the files must be identical as in the section above!! |
918 // NOTE: the order of the files must be identical as in the section above!! |
860 |
919 |
861 for(i = 0; files->basic[i] != NULL; i++) |
920 for(i = 0; files->basic[i].filename != NULL; i++) |
862 FioOpenFile(i,files->basic[i]); |
921 FioOpenFile(i,files->basic[i].filename); |
863 |
922 |
864 FioOpenFile(i++, "openttd.grf"); |
923 FioOpenFile(i++, "openttd.grf"); |
865 |
924 |
866 if (_sprite_page_to_load != 0) |
925 if (_sprite_page_to_load != 0) |
867 FioOpenFile(i++, files->landscape[_sprite_page_to_load-1]); |
926 FioOpenFile(i++, files->landscape[_sprite_page_to_load-1].filename); |
868 |
927 |
869 FioOpenFile(i++, "trkfoundw.grf"); |
928 FioOpenFile(i++, "trkfoundw.grf"); |
870 FioOpenFile(i++, "canalsw.grf"); |
929 FioOpenFile(i++, "canalsw.grf"); |
871 |
930 |
872 // FIXME: if a user changes his newgrf's, the cached-sprites gets |
931 // FIXME: if a user changes his newgrf's, the cached-sprites gets |