# base_media_base.h

Go to the documentation of this file.

    00001 /* $Id: base_media_base.h 24487 2012-08-20 21:01:40Z yexo $ */
    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 Tbase_set *GetAvailableSets();
    00205
    00206   static bool SetSet(const char *name);
    00207   static char *GetSetsList(char *p, const char *last);
    00208   static int GetNumSets();
    00209   static int GetIndexOfUsedSet();
    00210   static const Tbase_set *GetSet(int index);
    00211   static const Tbase_set *GetUsedSet();
    00212
    00219   static bool HasSet(const ContentInfo *ci, bool md5sum);
    00220 };
    00221
    00229 template <class Tbase_set>
    00230 const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s);
    00231
    00233 enum GraphicsFileType {
    00234   GFT_BASE,
    00235   GFT_LOGOS,
    00236   GFT_ARCTIC,
    00237   GFT_TROPICAL,
    00238   GFT_TOYLAND,
    00239   GFT_EXTRA,
    00240   MAX_GFT,
    00241 };
    00242
    00244 enum BlitterType {
    00245   BLT_8BPP,
    00246   BLT_32BPP,
    00247 };
    00248
    00250 struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
    00251   PaletteType palette;
    00252   BlitterType blitter;
    00253
    00254   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
    00255
    00256   static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
    00257 };
    00258
    00260 class BaseGraphics : public BaseMedia<GraphicsSet> {
    00261 public:
    00262 };
    00263
    00265 struct SoundsSet : BaseSet<SoundsSet, 1, true> {
    00266 };
    00267
    00269 class BaseSounds : public BaseMedia<SoundsSet> {
    00270 public:
    00271 };
    00272
    00274 static const uint NUM_SONGS_CLASS     = 10;
    00276 static const uint NUM_SONG_CLASSES    = 3;
    00278 static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS;
    00279
    00281 static const uint NUM_SONGS_PLAYLIST  = 32;
    00282
    00284 struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
    00286   char song_name[NUM_SONGS_AVAILABLE][32];
    00287   byte track_nr[NUM_SONGS_AVAILABLE];
    00288   byte num_available;
    00289
    00290   bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
    00291 };
    00292
    00294 class BaseMusic : public BaseMedia<MusicSet> {
    00295 public:
    00296 };
    00297
    00298 #endif /* BASE_MEDIA_BASE_H */