base_media_base.h

Go to the documentation of this file.
00001 /* $Id: base_media_base.h 23887 2012-02-04 13:29:04Z michi_cc $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD 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, version 2.
00006  * OpenTTD 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.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef BASE_MEDIA_BASE_H
00013 #define BASE_MEDIA_BASE_H
00014 
00015 #include "fileio_func.h"
00016 #include "core/smallmap_type.hpp"
00017 #include "gfx_type.h"
00018 
00019 /* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
00020 struct IniFile;
00021 struct ContentInfo;
00022 
00024 struct MD5File {
00026   enum ChecksumResult {
00027     CR_MATCH,    
00028     CR_MISMATCH, 
00029     CR_NO_FILE,  
00030   };
00031 
00032   const char *filename;        
00033   uint8 hash[16];              
00034   const char *missing_warning; 
00035 
00036   ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
00037 };
00038 
00045 template <class T, size_t Tnum_files, bool Tsearch_in_tars>
00046 struct BaseSet {
00047   typedef SmallMap<const char *, const char *> TranslatedStrings;
00048 
00050   static const size_t NUM_FILES = Tnum_files;
00051 
00053   static const bool SEARCH_IN_TARS = Tsearch_in_tars;
00054 
00056   static const char * const *file_names;
00057 
00058   const char *name;              
00059   TranslatedStrings description; 
00060   uint32 shortname;              
00061   uint32 version;                
00062   bool fallback;                 
00063 
00064   MD5File files[NUM_FILES];      
00065   uint found_files;              
00066   uint valid_files;              
00067 
00068   T *next;                       
00069 
00071   ~BaseSet()
00072   {
00073     free(this->name);
00074 
00075     for (TranslatedStrings::iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00076       free(iter->first);
00077       free(iter->second);
00078     }
00079 
00080     for (uint i = 0; i < NUM_FILES; i++) {
00081       free(this->files[i].filename);
00082       free(this->files[i].missing_warning);
00083     }
00084 
00085     delete this->next;
00086   }
00087 
00092   int GetNumMissing() const
00093   {
00094     return Tnum_files - this->found_files;
00095   }
00096 
00102   int GetNumInvalid() const
00103   {
00104     return Tnum_files - this->valid_files;
00105   }
00106 
00107   bool FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename = true);
00108 
00117   const char *GetDescription(const char *isocode = NULL) const
00118   {
00119     if (isocode != NULL) {
00120       /* First the full ISO code */
00121       for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00122         if (strcmp(iter->first, isocode) == 0) return iter->second;
00123       }
00124       /* Then the first two characters */
00125       for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00126         if (strncmp(iter->first, isocode, 2) == 0) return iter->second;
00127       }
00128     }
00129     /* Then fall back */
00130     return this->description.Begin()->second;
00131   }
00132 
00142   static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
00143   {
00144     return file->CheckMD5(subdir, SIZE_MAX);
00145   }
00146 };
00147 
00152 template <class Tbase_set>
00153 class BaseMedia : FileScanner {
00154 protected:
00155   static Tbase_set *available_sets; 
00156   static Tbase_set *duplicate_sets; 
00157   static const Tbase_set *used_set; 
00158 
00159   /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename);
00160 
00165   static const char *GetExtension();
00166 public:
00168   static const char *ini_set;
00169 
00175   static bool DetermineBestSet();
00176 
00178   static uint FindSets()
00179   {
00180     BaseMedia<Tbase_set> fs;
00181     /* Searching in tars is only done in the old "data" directories basesets. */
00182     uint num = fs.Scan(GetExtension(), Tbase_set::SEARCH_IN_TARS ? OLD_DATA_DIR : OLD_GM_DIR, Tbase_set::SEARCH_IN_TARS);
00183     return num + fs.Scan(GetExtension(), BASESET_DIR, Tbase_set::SEARCH_IN_TARS);
00184   }
00185 
00186   static bool SetSet(const char *name);
00187   static char *GetSetsList(char *p, const char *last);
00188   static int GetNumSets();
00189   static int GetIndexOfUsedSet();
00190   static const Tbase_set *GetSet(int index);
00191   static const Tbase_set *GetUsedSet();
00192 
00199   static bool HasSet(const ContentInfo *ci, bool md5sum);
00200 };
00201 
00202 
00204 enum GraphicsFileType {
00205   GFT_BASE,     
00206   GFT_LOGOS,    
00207   GFT_ARCTIC,   
00208   GFT_TROPICAL, 
00209   GFT_TOYLAND,  
00210   GFT_EXTRA,    
00211   MAX_GFT,      
00212 };
00213 
00215 enum BlitterType {
00216   BLT_8BPP,       
00217   BLT_32BPP,      
00218 };
00219 
00221 struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
00222   PaletteType palette;       
00223   BlitterType blitter;       
00224 
00225   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
00226 
00227   static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
00228 };
00229 
00231 class BaseGraphics : public BaseMedia<GraphicsSet> {
00232 public:
00233 };
00234 
00236 struct SoundsSet : BaseSet<SoundsSet, 1, true> {
00237 };
00238 
00240 class BaseSounds : public BaseMedia<SoundsSet> {
00241 public:
00242 };
00243 
00245 static const uint NUM_SONGS_CLASS     = 10;
00247 static const uint NUM_SONG_CLASSES    = 3;
00249 static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS;
00250 
00252 static const uint NUM_SONGS_PLAYLIST  = 32;
00253 
00255 struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
00257   char song_name[NUM_SONGS_AVAILABLE][32];
00258   byte track_nr[NUM_SONGS_AVAILABLE];
00259   byte num_available;
00260 
00261   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
00262 };
00263 
00265 class BaseMusic : public BaseMedia<MusicSet> {
00266 public:
00267 };
00268 
00269 #endif /* BASE_MEDIA_BASE_H */