mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-17 21:25:40 +00:00
284 lines
8.6 KiB
C++
284 lines
8.6 KiB
C++
/* $Id$ */
|
|
|
|
/*
|
|
* This file is part of OpenTTD.
|
|
* 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.
|
|
* 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.
|
|
* 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/>.
|
|
*/
|
|
|
|
/** @file base_media_base.h Generic functions for replacing base data (graphics, sounds). */
|
|
|
|
#ifndef BASE_MEDIA_BASE_H
|
|
#define BASE_MEDIA_BASE_H
|
|
|
|
#include "fileio_func.h"
|
|
#include "core/smallmap_type.hpp"
|
|
#include "gfx_type.h"
|
|
|
|
/* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
|
|
struct IniFile;
|
|
struct ContentInfo;
|
|
|
|
/** Structure holding filename and MD5 information about a single file */
|
|
struct MD5File {
|
|
/** The result of a checksum check */
|
|
enum ChecksumResult {
|
|
CR_MATCH, ///< The file did exist and the md5 checksum did match
|
|
CR_MISMATCH, ///< The file did exist, just the md5 checksum did not match
|
|
CR_NO_FILE, ///< The file did not exist
|
|
};
|
|
|
|
const char *filename; ///< filename
|
|
uint8 hash[16]; ///< md5 sum of the file
|
|
const char *missing_warning; ///< warning when this file is missing
|
|
|
|
ChecksumResult CheckMD5(Subdirectory subdir) const;
|
|
};
|
|
|
|
/**
|
|
* Information about a single base set.
|
|
* @tparam T the real class we're going to be
|
|
* @tparam Tnum_files the number of files in the set
|
|
* @tparam Tsubdir the subdirectory where to find the files
|
|
*/
|
|
template <class T, size_t Tnum_files, Subdirectory Tsubdir>
|
|
struct BaseSet {
|
|
typedef SmallMap<const char *, const char *> TranslatedStrings;
|
|
|
|
/** Number of files in this set */
|
|
static const size_t NUM_FILES = Tnum_files;
|
|
|
|
/** The sub directory to search for the files */
|
|
static const Subdirectory SUBDIR = Tsubdir;
|
|
|
|
/** Internal names of the files in this set. */
|
|
static const char * const *file_names;
|
|
|
|
const char *name; ///< The name of the base set
|
|
TranslatedStrings description; ///< Description of the base set
|
|
uint32 shortname; ///< Four letter short variant of the name
|
|
uint32 version; ///< The version of this base set
|
|
|
|
MD5File files[NUM_FILES]; ///< All files part of this set
|
|
uint found_files; ///< Number of the files that could be found
|
|
uint valid_files; ///< Number of the files that could be found and are valid
|
|
|
|
T *next; ///< The next base set in this list
|
|
|
|
/** Free everything we allocated */
|
|
~BaseSet()
|
|
{
|
|
free((void*)this->name);
|
|
|
|
for (TranslatedStrings::iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
|
free((void*)iter->first);
|
|
free((void*)iter->second);
|
|
}
|
|
|
|
for (uint i = 0; i < NUM_FILES; i++) {
|
|
free((void*)this->files[i].filename);
|
|
free((void*)this->files[i].missing_warning);
|
|
}
|
|
|
|
delete this->next;
|
|
}
|
|
|
|
/**
|
|
* Get the number of missing files.
|
|
* @return the number
|
|
*/
|
|
int GetNumMissing() const
|
|
{
|
|
return Tnum_files - this->found_files;
|
|
}
|
|
|
|
/**
|
|
* Get the number of invalid files.
|
|
* @note a missing file is invalid too!
|
|
* @return the number
|
|
*/
|
|
int GetNumInvalid() const
|
|
{
|
|
return Tnum_files - this->valid_files;
|
|
}
|
|
|
|
/**
|
|
* Read the set information from a loaded ini.
|
|
* @param ini the ini to read from
|
|
* @param path the path to this ini file (for filenames)
|
|
* @return true if loading was successful.
|
|
*/
|
|
bool FillSetDetails(IniFile *ini, const char *path);
|
|
|
|
/**
|
|
* Get the description for the given ISO code.
|
|
* It falls back to the first two characters of the ISO code in case
|
|
* no match could be made with the full ISO code. If even then the
|
|
* matching fails the default is returned.
|
|
* @param isocode the isocode to search for
|
|
* @return the description
|
|
*/
|
|
const char *GetDescription(const char *isocode = NULL) const
|
|
{
|
|
if (isocode != NULL) {
|
|
/* First the full ISO code */
|
|
for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
|
if (strcmp(iter->first, isocode) == 0) return iter->second;
|
|
}
|
|
/* Then the first two characters */
|
|
for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) {
|
|
if (strncmp(iter->first, isocode, 2) == 0) return iter->second;
|
|
}
|
|
}
|
|
/* Then fall back */
|
|
return this->description.Begin()->second;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Base for all base media (graphics, sounds)
|
|
* @tparam Tbase_set the real set we're going to be
|
|
*/
|
|
template <class Tbase_set>
|
|
class BaseMedia : FileScanner {
|
|
protected:
|
|
static Tbase_set *available_sets; ///< All available sets
|
|
static const Tbase_set *used_set; ///< The currently used set
|
|
|
|
/* virtual */ bool AddFile(const char *filename, size_t basepath_length);
|
|
|
|
/**
|
|
* Get the extension that is used to identify this set.
|
|
* @return the extension
|
|
*/
|
|
static const char *GetExtension();
|
|
public:
|
|
/** The set as saved in the config file. */
|
|
static const char *ini_set;
|
|
|
|
/**
|
|
* Determine the graphics pack that has to be used.
|
|
* The one with the most correct files wins.
|
|
* @return true if a best set has been found.
|
|
*/
|
|
static bool DetermineBestSet();
|
|
|
|
/** Do the scan for files. */
|
|
static uint FindSets()
|
|
{
|
|
BaseMedia<Tbase_set> fs;
|
|
return fs.Scan(GetExtension(), Tbase_set::SUBDIR);
|
|
}
|
|
|
|
/**
|
|
* Set the set to be used.
|
|
* @param name of the set to use
|
|
* @return true if it could be loaded
|
|
*/
|
|
static bool SetSet(const char *name);
|
|
|
|
/**
|
|
* Returns a list with the sets.
|
|
* @param p where to print to
|
|
* @param last the last character to print to
|
|
* @return the last printed character
|
|
*/
|
|
static char *GetSetsList(char *p, const char *last);
|
|
|
|
/**
|
|
* Count the number of available graphics sets.
|
|
* @return the number of sets
|
|
*/
|
|
static int GetNumSets();
|
|
|
|
/**
|
|
* Get the index of the currently active graphics set
|
|
* @return the current set's index
|
|
*/
|
|
static int GetIndexOfUsedSet();
|
|
|
|
/**
|
|
* Get the name of the graphics set at the specified index
|
|
* @return the name of the set
|
|
*/
|
|
static const Tbase_set *GetSet(int index);
|
|
/**
|
|
* Return the used set.
|
|
* @return the used set.
|
|
*/
|
|
static const Tbase_set *GetUsedSet();
|
|
|
|
/**
|
|
* Check whether we have an set with the exact characteristics as ci.
|
|
* @param ci the characteristics to search on (shortname and md5sum)
|
|
* @param md5sum whether to check the MD5 checksum
|
|
* @return true iff we have an set matching.
|
|
*/
|
|
static bool HasSet(const ContentInfo *ci, bool md5sum);
|
|
};
|
|
|
|
|
|
/** Types of graphics in the base graphics set */
|
|
enum GraphicsFileType {
|
|
GFT_BASE, ///< Base sprites for all climates
|
|
GFT_LOGOS, ///< Logos, landscape icons and original terrain generator sprites
|
|
GFT_ARCTIC, ///< Landscape replacement sprites for arctic
|
|
GFT_TROPICAL, ///< Landscape replacement sprites for tropical
|
|
GFT_TOYLAND, ///< Landscape replacement sprites for toyland
|
|
GFT_EXTRA, ///< Extra sprites that were not part of the original sprites
|
|
MAX_GFT ///< We are looking for this amount of GRFs
|
|
};
|
|
|
|
/** All data of a graphics set. */
|
|
struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, DATA_DIR> {
|
|
PaletteType palette; ///< Palette of this graphics set
|
|
|
|
bool FillSetDetails(struct IniFile *ini, const char *path);
|
|
};
|
|
|
|
/** All data/functions related with replacing the base graphics. */
|
|
class BaseGraphics : public BaseMedia<GraphicsSet> {
|
|
public:
|
|
/**
|
|
* Determine the palette of the current graphics set.
|
|
*/
|
|
static void DeterminePalette();
|
|
};
|
|
|
|
/** All data of a sounds set. */
|
|
struct SoundsSet : BaseSet<SoundsSet, 1, DATA_DIR> {
|
|
};
|
|
|
|
/** All data/functions related with replacing the base sounds */
|
|
class BaseSounds : public BaseMedia<SoundsSet> {
|
|
public:
|
|
};
|
|
|
|
/** Maximum number of songs in the 'class' playlists. */
|
|
static const uint NUM_SONGS_CLASS = 10;
|
|
/** Number of classes for songs */
|
|
static const uint NUM_SONG_CLASSES = 3;
|
|
/** Maximum number of songs in the full playlist; theme song + the classes */
|
|
static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS;
|
|
|
|
/** Maximum number of songs in the (custom) playlist */
|
|
static const uint NUM_SONGS_PLAYLIST = 32;
|
|
|
|
/** All data of a music set. */
|
|
struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, GM_DIR> {
|
|
/** The name of the different songs. */
|
|
char song_name[NUM_SONGS_AVAILABLE][32];
|
|
byte track_nr[NUM_SONGS_AVAILABLE];
|
|
byte num_available;
|
|
|
|
bool FillSetDetails(struct IniFile *ini, const char *path);
|
|
};
|
|
|
|
/** All data/functions related with replacing the base music */
|
|
class BaseMusic : public BaseMedia<MusicSet> {
|
|
public:
|
|
};
|
|
|
|
#endif /* BASE_MEDIA_BASE_H */
|