Go to the documentation of this file.
13 #include "3rdparty/md5/md5.h"
22 #define SET_TYPE "graphics"
36 _landscape_spriteindexes_arctic,
37 _landscape_spriteindexes_tropic,
38 _landscape_spriteindexes_toyland,
48 static uint
LoadGrfFile(
const char *filename, uint load_index,
int file_index)
50 uint load_index_org = load_index;
55 DEBUG(sprite, 2,
"Reading grf-file '%s'", filename);
58 if (container_ver == 0)
usererror(
"Base grf '%s' is corrupt", filename);
60 if (container_ver >= 2) {
63 if (compression != 0)
usererror(
"Unsupported compression format");
66 while (
LoadNextSprite(load_index, file_index, sprite_id, container_ver)) {
70 usererror(
"Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
73 DEBUG(sprite, 2,
"Currently %i sprites are loaded", load_index);
75 return load_index - load_index_org;
92 DEBUG(sprite, 2,
"Reading indexed grf-file '%s'", filename);
95 if (container_ver == 0)
usererror(
"Base grf '%s' is corrupt", filename);
97 if (container_ver >= 2) {
100 if (compression != 0)
usererror(
"Unsupported compression format");
103 while ((start = *index_tbl++) != END) {
104 uint end = *index_tbl++;
107 bool b =
LoadNextSprite(start, file_index, sprite_id, container_ver);
111 }
while (++start <= end);
126 DEBUG(grf, 1,
"Using the %s base graphics set", used_set->
name.c_str());
128 static const size_t ERROR_MESSAGE_LENGTH = 256;
129 static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
136 char *add_pos = error_msg;
137 const char *last =
lastof(error_msg);
141 add_pos +=
seprintf(add_pos, last,
"Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->
name.c_str());
146 add_pos +=
seprintf(add_pos, last,
"\n");
151 add_pos +=
seprintf(add_pos, last,
"Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->
name.c_str());
159 if (add_pos != error_msg)
ShowInfoF(
"%s", error_msg);
227 master->
next = extra;
247 static void RealChangeBlitter(
const char *repl_blitter)
250 if (strcmp(cur_blitter, repl_blitter) == 0)
return;
252 DEBUG(driver, 1,
"Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
254 if (new_blitter ==
nullptr) NOT_REACHED();
255 DEBUG(driver, 1,
"Successfully switched to %s.", repl_blitter);
288 uint depth_wanted_by_grf = _support8bpp !=
S8BPP_NONE ? 8 : 32;
297 static const struct {
300 uint min_base_depth, max_base_depth, min_grf_depth, max_grf_depth;
301 } replacement_blitters[] = {
302 {
"8bpp-optimized", 2, 8, 8, 8, 8 },
303 {
"40bpp-anim", 2, 8, 32, 8, 32 },
305 {
"32bpp-sse4", 0, 32, 32, 8, 32 },
306 {
"32bpp-ssse3", 0, 32, 32, 8, 32 },
307 {
"32bpp-sse2", 0, 32, 32, 8, 32 },
308 {
"32bpp-sse4-anim", 1, 32, 32, 8, 32 },
310 {
"32bpp-optimized", 0, 8, 32, 8, 32 },
312 {
"32bpp-sse2-anim", 1, 8, 32, 8, 32 },
314 {
"32bpp-anim", 1, 8, 32, 8, 32 },
320 for (uint i = 0; i <
lengthof(replacement_blitters); i++) {
321 if (animation_wanted && (replacement_blitters[i].animation == 0))
continue;
322 if (!animation_wanted && (replacement_blitters[i].animation == 1))
continue;
324 if (!
IsInsideMM(depth_wanted_by_base, replacement_blitters[i].min_base_depth, replacement_blitters[i].max_base_depth + 1))
continue;
325 if (!
IsInsideMM(depth_wanted_by_grf, replacement_blitters[i].min_grf_depth, replacement_blitters[i].max_grf_depth + 1))
continue;
326 const char *repl_blitter = replacement_blitters[i].name;
328 if (strcmp(repl_blitter, cur_blitter) == 0) {
366 bool GraphicsSet::FillSetDetails(
IniFile *ini,
const char *path,
const char *full_filename)
377 item = metadata->
GetItem(
"blitter",
false);
422 size = std::min(size, max_size);
429 while ((len = fread(buffer, 1, (size >
sizeof(buffer)) ?
sizeof(buffer) : size, f)) != 0 && size != 0) {
431 checksum.Append(buffer, len);
436 checksum.Finish(digest);
441 static const char *
const _graphics_file_names[] = {
"base",
"logos",
"arctic",
"tropical",
"toyland",
"extra" };
444 template <
class T,
size_t Tnum_files,
bool Tsearch_in_tars>
447 template <
class Tbase_set>
452 const Tbase_set *best =
nullptr;
455 if (c->GetNumMissing() != 0)
continue;
457 if (best ==
nullptr ||
458 (best->fallback && !c->fallback) ||
459 best->valid_files < c->valid_files ||
460 (best->valid_files == c->valid_files && (
461 (best->shortname == c->shortname && best->version < c->version) ||
471 template <
class Tbase_set>
@ PAL_DOS
Use the DOS palette.
void ReInitAllWindows()
Re-initialize all windows.
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
All data of a sounds set.
static void LoadSpriteTables()
Actually load the sprite tables.
byte landscape
the landscape we're currently in
void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir)
Open a slotted file.
How all blitters should look like.
@ CR_MISMATCH
The file did exist, just the md5 checksum did not match.
ChecksumResult
The result of a checksum check.
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
std::string name
The name of the base set.
A single "line" in an ini file.
static const size_t NUM_FILES
Number of files in this set.
A group within an ini file.
@ FIRST_GRF_SLOT
First slot usable for (New)GRFs used during the game.
static Blitter * SelectBlitter(const std::string &name)
Find the requested blitter and return his class.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
byte _display_opt
What do we want to draw/do?
virtual void ClearSystemSprites()
Clear all cached sprites.
GameCreationSettings game_creation
settings used during the creation of a game (map)
@ GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
void UpdateCursorSize()
Update cursor dimension.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
@ CR_MATCH
The file did exist and the md5 checksum did match.
@ DO_FULL_ANIMATION
Perform palette animation.
@ GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
static const SpriteID *const _landscape_spriteindexes[]
Offsets for loading the different "replacement" sprites in the files.
const char * missing_warning
warning when this file is missing
uint8 hash[16]
md5 sum of the file
Information about GRF, used in the game and (part of it) in savegames.
@ MAX_SPRITES
Maximum number of sprites that can be loaded at a given time.
void GfxClearSpriteCache()
Remove all encoded sprites from the sprite cache without discarding sprite location information.
@ S8BPP_NONE
No support for 8bpp by OS or hardware, force 32bpp blitters.
bool _palette_remap_grf[MAX_FILE_SLOTS]
Whether the given NewGRFs must get a palette remap from windows to DOS or not.
#define DEBUG(name, level,...)
Output a line of debugging information.
FILE * FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
static bool SwitchNewGRFBlitter()
Check blitter needed by NewGRF config and switch if needed.
std::optional< std::string > value
The value of this item.
uint8 flags
NOSAVE: GCF_Flags, bitset.
uint _missing_extra_graphics
Number of sprites provided by the fallback extra GRF, i.e. missing in the baseset.
bool HasAntialiasedFonts()
Should any of the active fonts be anti-aliased?
GameSettings _settings_game
Game settings of a running game or the scenario editor.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
@ MAX_FILE_SLOTS
Maximum number of slots.
size_t GRFGetSizeOfDataSection(FILE *f)
Get the data section size of a GRF.
@ GRFP_BLT_32BPP
The NewGRF prefers a 32 bpp blitter.
ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const
Calculate and check the MD5 hash of the supplied filename.
void CheckExternalFiles()
Checks whether the MD5 checksums of the files are correct.
BlitterType blitter
Blitter of this graphics set.
void QueueOnMainThread(std::function< void()> &&func)
Queue a function to be called on the main thread with game state lock held and video buffer locked.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
static const char *const _graphics_file_names[]
Names corresponding to the GraphicsFileType.
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte container_version)
Load a real or recolour sprite.
byte FioReadByte()
Read a byte from the file.
void CheckBlitter()
Check whether we still use the right blitter, or use another (better) one.
virtual const char * GetName()=0
Get the name of the blitter, the same as the Factory-instance returns.
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
@ GCS_DISABLED
GRF file is disabled.
@ GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
Ini file that supports both loading and saving.
Structure holding filename and MD5 information about a single file.
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
Calculate and check the MD5 hash of the supplied GRF.
static BlitterFactory * GetBlitterFactory(const std::string &name)
Get the blitter factory with the given name.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
PaletteType palette
Palette of this graphics set.
Information about a single base set.
@ CR_NO_FILE
The file did not exist.
void CDECL ShowInfoF(const char *str,...)
Shows some information on the console/a popup box depending on the OS.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Subdirectory
The different kinds of subdirectories OpenTTD uses.
static uint LoadGrfFile(const char *filename, uint load_index, int file_index)
Load an old fashioned GRF file.
static void LoadGrfFileIndexed(const char *filename, const SpriteID *index_tbl, int file_index)
Load an old fashioned GRF file to replace already loaded sprites.
void GfxLoadSprites()
Initialise and load all the sprites.
static void InitializeUnicodeGlyphMap()
Initialize the glyph map.
uint8 palette
GRFPalette, bitset.
const char * filename
filename
GRFConfig * _grfconfig
First item in list of current GRF set up.
#define lengthof(x)
Return the length of an fixed size array.
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
IniItem * GetItem(const std::string &name, bool create)
Get the item with the given name, and if it doesn't exist and create is true it creates a new item.
@ PAL_WINDOWS
Use the Windows palette.
int GetNumInvalid() const
Get the number of invalid files.
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
Calculate and check the MD5 hash of the supplied file.
bool FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename=true)
Read the set information from a loaded ini.
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
Find the GRFID of a given grf, and calculate its md5sum.
#define lastof(x)
Get the last element of an fixed size array.
All data of a graphics set.
MD5File files[NUM_FILES]
All files part of this set.
void FioFCloseFile(FILE *f)
Close a file in a safe way.
uint GetSpriteCountForSlot(uint file_slot, SpriteID begin, SpriteID end)
Count the sprites which originate from a specific file slot in a range of SpriteIDs.
IniGroup * GetGroup(const std::string &name, bool create_new=true)
Get the group with the given name.