15 #include "3rdparty/md5/md5.h" 24 #define SET_TYPE "graphics" 38 _landscape_spriteindexes_arctic,
39 _landscape_spriteindexes_tropic,
40 _landscape_spriteindexes_toyland,
50 static uint
LoadGrfFile(
const char *filename, uint load_index,
int file_index)
52 uint load_index_org = load_index;
57 DEBUG(sprite, 2,
"Reading grf-file '%s'", filename);
60 if (container_ver == 0)
usererror(
"Base grf '%s' is corrupt", filename);
62 if (container_ver >= 2) {
65 if (compression != 0)
usererror(
"Unsupported compression format");
68 while (
LoadNextSprite(load_index, file_index, sprite_id, container_ver)) {
72 usererror(
"Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
75 DEBUG(sprite, 2,
"Currently %i sprites are loaded", load_index);
77 return load_index - load_index_org;
94 DEBUG(sprite, 2,
"Reading indexed grf-file '%s'", filename);
97 if (container_ver == 0)
usererror(
"Base grf '%s' is corrupt", filename);
99 if (container_ver >= 2) {
102 if (compression != 0)
usererror(
"Unsupported compression format");
105 while ((start = *index_tbl++) != END) {
106 uint end = *index_tbl++;
109 bool b =
LoadNextSprite(start, file_index, sprite_id, container_ver);
112 }
while (++start <= end);
127 DEBUG(grf, 1,
"Using the %s base graphics set", used_set->
name);
129 static const size_t ERROR_MESSAGE_LENGTH = 256;
130 static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
137 char *add_pos = error_msg;
138 const char *last =
lastof(error_msg);
142 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.txt.\n\nThe following files are corrupted or missing:\n", used_set->
name);
147 add_pos +=
seprintf(add_pos, last,
"\n");
152 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.txt.\n\nThe following files are corrupted or missing:\n", sounds_set->
name);
160 if (add_pos != error_msg)
ShowInfoF(
"%s", error_msg);
228 master->
next = extra;
267 uint depth_wanted_by_grf = _support8bpp ==
S8BPP_NONE ? 32 : 8;
274 static const struct {
277 uint min_base_depth, max_base_depth, min_grf_depth, max_grf_depth;
278 } replacement_blitters[] = {
280 {
"32bpp-sse4", 0, 32, 32, 8, 32 },
281 {
"32bpp-ssse3", 0, 32, 32, 8, 32 },
282 {
"32bpp-sse2", 0, 32, 32, 8, 32 },
283 {
"32bpp-sse4-anim", 1, 32, 32, 8, 32 },
285 {
"8bpp-optimized", 2, 8, 8, 8, 8 },
286 {
"32bpp-optimized", 0, 8, 32, 8, 32 },
287 {
"32bpp-anim", 1, 8, 32, 8, 32 },
295 for (uint i = 0; i <
lengthof(replacement_blitters); i++) {
296 if (animation_wanted && (replacement_blitters[i].animation == 0))
continue;
297 if (!animation_wanted && (replacement_blitters[i].animation == 1))
continue;
299 if (!
IsInsideMM(depth_wanted_by_base, replacement_blitters[i].min_base_depth, replacement_blitters[i].max_base_depth + 1))
continue;
300 if (!
IsInsideMM(depth_wanted_by_grf, replacement_blitters[i].min_grf_depth, replacement_blitters[i].max_grf_depth + 1))
continue;
301 const char *repl_blitter = replacement_blitters[i].name;
303 if (strcmp(repl_blitter, cur_blitter) == 0) {
309 DEBUG(misc, 1,
"Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
311 if (new_blitter == NULL) NOT_REACHED();
312 DEBUG(misc, 1,
"Successfully switched to %s.", repl_blitter);
350 bool GraphicsSet::FillSetDetails(
IniFile *ini,
const char *path,
const char *full_filename)
361 item = metadata->
GetItem(
"blitter",
false);
402 FILE *f =
FioFOpenFile(this->filename,
"rb", subdir, &size);
404 if (f == NULL)
return CR_NO_FILE;
406 size =
min(size, max_size);
413 while ((len = fread(buffer, 1, (size >
sizeof(buffer)) ?
sizeof(buffer) : size, f)) != 0 && size != 0) {
415 checksum.Append(buffer, len);
420 checksum.Finish(digest);
421 return memcmp(this->hash, digest,
sizeof(this->hash)) == 0 ? CR_MATCH : CR_MISMATCH;
425 static const char *
const _graphics_file_names[] = {
"base",
"logos",
"arctic",
"tropical",
"toyland",
"extra" };
428 template <
class T,
size_t Tnum_files,
bool Tsearch_in_tars>
431 template <
class Tbase_set>
436 const Tbase_set *best = NULL;
439 if (c->GetNumMissing() != 0)
continue;
442 (best->fallback && !c->fallback) ||
443 best->valid_files < c->valid_files ||
444 (best->valid_files == c->valid_files && (
445 (best->shortname == c->shortname && best->version < c->version) ||
455 template <
class Tbase_set>
First slot usable for (New)GRFs used during the game.
A group within an ini file.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Base of all video drivers.
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
GRFConfig * _grfconfig
First item in list of current GRF set up.
byte landscape
the landscape we're currently in
Subdirectory
The different kinds of subdirectories OpenTTD uses.
size_t GRFGetSizeOfDataSection(FILE *f)
Get the data section size of a GRF.
void FioFCloseFile(FILE *f)
Close a file in a safe way.
GRF file is processed up to GLS_INIT.
byte _display_opt
What do we want to draw/do?
virtual void ReleaseBlitterLock()
Release any lock(s) required to be held when changing blitters.
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Structure holding filename and MD5 information about a single file.
int GetNumInvalid() const
Get the number of invalid files.
The NewGRF prefers a 32 bpp blitter.
uint _missing_extra_graphics
Number of sprites provided by the fallback extra GRF, i.e. missing in the baseset.
static bool SwitchNewGRFBlitter()
Check blitter needed by NewGRF config and switch if needed.
void CheckExternalFiles()
Checks whether the MD5 checksums of the files are correct.
static void LoadSpriteTables()
Actually load the sprite tables.
PaletteType palette
Palette of this graphics set.
Maximum number of sprites that can be loaded at a given time.
#define lastof(x)
Get the last element of an fixed size array.
IniGroup * GetGroup(const char *name, size_t len=0, bool create_new=true)
Get the group with the given name.
GRF file was not found in the local cache.
MD5File files[NUM_FILES]
All files part of this set.
How all blitters should look like.
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
Subdirectory for all base data (base sets, intro game)
static T max(const T a, const T b)
Returns the maximum of two values.
byte FioReadByte()
Read a byte from the file.
static void InitializeUnicodeGlyphMap()
Initialize the glyph map.
virtual const char * GetName()=0
Get the name of the blitter, the same as the Factory-instance returns.
static const char *const _graphics_file_names[]
Names corresponding to the GraphicsFileType.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
The file did exist, just the md5 checksum did not match.
A single "line" in an ini file.
const char * missing_warning
warning when this file is missing
void CDECL ShowInfoF(const char *str,...)
Shows some information on the console/a popup box depending on the OS.
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
Find the GRFID of a given grf, and calculate its md5sum.
Functions to read fonts from files and cache them.
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
const char * filename
filename
Information about GRF, used in the game and (part of it) in savegames.
static Blitter * SelectBlitter(const char *name)
Find the requested blitter and return his class.
const char * name
The name of the base set.
Functions related to the gfx engine.
static uint LoadGrfFile(const char *filename, uint load_index, int file_index)
Load an old fashioned GRF file.
FILE * FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
Definition of base types and functions in a cross-platform compatible way.
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
A number of safeguards to prevent using unsafe methods.
Offsets of sprites to replace for non-temperate landscapes.
uint8 flags
NOSAVE: GCF_Flags, bitset.
char * value
The value of this item.
virtual void AcquireBlitterLock()
Acquire any lock(s) required to be held when changing blitters.
#define lengthof(x)
Return the length of an fixed size array.
void GfxClearSpriteCache()
Remove all encoded sprites from the sprite cache without discarding sprite location information...
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
static T min(const T a, const T b)
Returns the minimum of two values.
BlitterType blitter
Blitter of this graphics set.
ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const
Calculate and check the MD5 hash of the supplied filename.
#define DEBUG(name, level,...)
Output a line of debugging information.
void FioOpenFile(int slot, const char *filename, Subdirectory subdir)
Open a slotted file.
The NewGRF says the Windows palette can be used.
No support for 8bpp by OS or hardware, force 32bpp blitters.
void ReInitAllWindows()
Re-initialize all windows.
Ini file that supports both loading and saving.
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
void UpdateCursorSize()
Update cursor dimension.
Declarations for savegames operations.
The file did exist and the md5 checksum did match.
uint8 palette
GRFPalette, bitset.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Functions related to transparency.
bool FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename=true)
Read the set information from a loaded ini.
All data of a sounds set.
All data of a graphics set.
ChecksumResult
The result of a checksum check.
IniItem * GetItem(const char *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...
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte container_version)
Load a real or recolour sprite.
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
static void LoadGrfFileIndexed(const char *filename, const SpriteID *index_tbl, int file_index)
Load an old fashioned GRF file to replace already loaded sprites.
Information about a single base set.
uint GetSpriteCountForSlot(uint file_slot, SpriteID begin, SpriteID end)
Count the sprites which originate from a specific file slot in a range of SpriteIDs.
The NewGRF says the DOS palette can be used.
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
Perform palette animation.
static const SpriteID *const _landscape_spriteindexes[]
Offsets for loading the different "replacement" sprites in the files.
static BlitterFactory * GetBlitterFactory(const char *name)
Get the blitter factory with the given name.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
Calculate and check the MD5 hash of the supplied file.
GameCreationSettings game_creation
settings used during the creation of a game (map)
Window functions not directly related to making/drawing windows.
bool _palette_remap_grf[MAX_FILE_SLOTS]
Whether the given NewGRFs must get a palette remap from windows to DOS or not.
void CheckBlitter()
Check whether we still use the right blitter, or use another (better) one.
This file contains all sprite-related enums and defines.
Factory to 'query' all available blitters.
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
Calculate and check the MD5 hash of the supplied GRF.
static const size_t NUM_FILES
Number of files in this set.
void GfxLoadSprites()
Initialise and load all the sprites.
Base for the NewGRF implementation.