base_media_base.h

Go to the documentation of this file.
00001 /* $Id$ */
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 #include "textfile_type.h"
00019 #include "textfile_gui.h"
00020 
00021 /* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
00022 struct IniFile;
00023 struct ContentInfo;
00024 
00026 struct MD5File {
00028   enum ChecksumResult {
00029     CR_MATCH,    
00030     CR_MISMATCH, 
00031     CR_NO_FILE,  
00032   };
00033 
00034   const char *filename;        
00035   uint8 hash[16];              
00036   const char *missing_warning; 
00037 
00038   ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
00039 };
00040 
00047 template <class T, size_t Tnum_files, bool Tsearch_in_tars>
00048 struct BaseSet {
00049   typedef SmallMap<const char *, const char *> TranslatedStrings;
00050 
00052   static const size_t NUM_FILES = Tnum_files;
00053 
00055   static const bool SEARCH_IN_TARS = Tsearch_in_tars;
00056 
00058   static const char * const *file_names;
00059 
00060   const char *name;              
00061   TranslatedStrings description; 
00062   uint32 shortname;              
00063   uint32 version;                
00064   bool fallback;                 
00065 
00066   MD5File files[NUM_FILES];      
00067   uint found_files;              
00068   uint valid_files;              
00069 
00070   T *next;                       
00071 
00073   ~BaseSet()
00074   {
00075     free(this->name);
00076 
00077     for (TranslatedStrings::iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00078       free(iter->first);
00079       free(iter->second);
00080     }
00081 
00082     for (uint i = 0; i < NUM_FILES; i++) {
00083       free(this->files[i].filename);
00084       free(this->files[i].missing_warning);
00085     }
00086 
00087     delete this->next;
00088   }
00089 
00094   int GetNumMissing() const
00095   {
00096     return Tnum_files - this->found_files;
00097   }
00098 
00104   int GetNumInvalid() const
00105   {
00106     return Tnum_files - this->valid_files;
00107   }
00108 
00109   bool FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename = true);
00110 
00119   const char *GetDescription(const char *isocode = NULL) const
00120   {
00121     if (isocode != NULL) {
00122       /* First the full ISO code */
00123       for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00124         if (strcmp(iter->first, isocode) == 0) return iter->second;
00125       }
00126       /* Then the first two characters */
00127       for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
00128         if (strncmp(iter->first, isocode, 2) == 0) return iter->second;
00129       }
00130     }
00131     /* Then fall back */
00132     return this->description.Begin()->second;
00133   }
00134 
00144   static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
00145   {
00146     return file->CheckMD5(subdir, SIZE_MAX);
00147   }
00148 
00154   const char *GetTextfile(TextfileType type) const
00155   {
00156     for (uint i = 0; i < NUM_FILES; i++) {
00157       const char *textfile = ::GetTextfile(type, BASESET_DIR, this->files[i].filename);
00158       if (textfile != NULL) {
00159         return textfile;
00160       }
00161     }
00162     return NULL;
00163   }
00164 };
00165 
00170 template <class Tbase_set>
00171 class BaseMedia : FileScanner {
00172 protected:
00173   static Tbase_set *available_sets; 
00174   static Tbase_set *duplicate_sets; 
00175   static const Tbase_set *used_set; 
00176 
00177   /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename);
00178 
00183   static const char *GetExtension();
00184 public:
00186   static const char *ini_set;
00187 
00193   static bool DetermineBestSet();
00194 
00196   static uint FindSets()
00197   {
00198     BaseMedia<Tbase_set> fs;
00199     /* Searching in tars is only done in the old "data" directories basesets. */
00200     uint num = fs.Scan(GetExtension(), Tbase_set::SEARCH_IN_TARS ? OLD_DATA_DIR : OLD_GM_DIR, Tbase_set::SEARCH_IN_TARS);
00201     return num + fs.Scan(GetExtension(), BASESET_DIR, Tbase_set::SEARCH_IN_TARS);
00202   }
00203 
00204   static bool SetSet(const char *name);
00205   static char *GetSetsList(char *p, const char *last);
00206   static int GetNumSets();
00207   static int GetIndexOfUsedSet();
00208   static const Tbase_set *GetSet(int index);
00209   static const Tbase_set *GetUsedSet();
00210 
00217   static bool HasSet(const ContentInfo *ci, bool md5sum);
00218 };
00219 
00220 
00222 enum GraphicsFileType {
00223   GFT_BASE,     
00224   GFT_LOGOS,    
00225   GFT_ARCTIC,   
00226   GFT_TROPICAL, 
00227   GFT_TOYLAND,  
00228   GFT_EXTRA,    
00229   MAX_GFT,      
00230 };
00231 
00233 enum BlitterType {
00234   BLT_8BPP,       
00235   BLT_32BPP,      
00236 };
00237 
00239 struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
00240   PaletteType palette;       
00241   BlitterType blitter;       
00242 
00243   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
00244 
00245   static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
00246 };
00247 
00249 class BaseGraphics : public BaseMedia<GraphicsSet> {
00250 public:
00251 };
00252 
00254 struct SoundsSet : BaseSet<SoundsSet, 1, true> {
00255 };
00256 
00258 class BaseSounds : public BaseMedia<SoundsSet> {
00259 public:
00260 };
00261 
00263 static const uint NUM_SONGS_CLASS     = 10;
00265 static const uint NUM_SONG_CLASSES    = 3;
00267 static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS;
00268 
00270 static const uint NUM_SONGS_PLAYLIST  = 32;
00271 
00273 struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
00275   char song_name[NUM_SONGS_AVAILABLE][32];
00276   byte track_nr[NUM_SONGS_AVAILABLE];
00277   byte num_available;
00278 
00279   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
00280 };
00281 
00283 class BaseMusic : public BaseMedia<MusicSet> {
00284 public:
00285 };
00286 
00287 #endif /* BASE_MEDIA_BASE_H */