00001
00002
00003
00004
00005
00006
00007
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
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
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
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
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 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
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