12#include "3rdparty/md5/md5.h"
38 original_md5sum(config.original_md5sum),
39 filename(config.filename),
44 version(config.version),
45 min_loadable_version(config.min_loadable_version),
47 status(config.status),
48 grf_bugs(config.grf_bugs),
49 num_valid_params(config.num_valid_params),
50 palette(config.palette),
51 has_param_defaults(config.has_param_defaults),
52 param_info(config.param_info),
58void GRFConfig::SetParams(std::span<const uint32_t> pars)
60 this->
param.assign(std::begin(pars), std::end(pars));
117 if (!
info.has_value())
continue;
144 if (!
info.has_value())
continue;
172 if (
info.param_nr >= std::size(this->param))
return 0;
190 if (
info.param_nr >= std::size(this->param)) this->
param.resize(info.
param_nr + 1);
193 if (
info.num_bit == 32) {
209 [
this](
const ValueName &vn) {
return vn.first < this->
min_value || vn.first > this->
max_value; });
224 for (
const auto &c :
_all_grfs ) c->SetSuitablePalette();
235 static const uint header_len = 14;
237 uint8_t data[header_len];
238 if (fread(data, 1, header_len, f) == header_len) {
241 size_t offset = (
static_cast<size_t>(data[13]) << 24) | (
static_cast<size_t>(data[12]) << 16) | (
static_cast<size_t>(data[11]) << 8) |
static_cast<size_t>(data[10]);
242 if (offset >= 1 * 1024 * 1024 * 1024) {
243 Debug(grf, 0,
"Unexpectedly large offset for NewGRF");
249 return header_len + offset;
265 uint8_t buffer[1024];
270 if (!f.has_value())
return false;
272 long start = ftell(*f);
275 if (start < 0 || fseek(*f, start, SEEK_SET) < 0) {
280 while ((len = fread(buffer, 1, (size >
sizeof(buffer)) ?
sizeof(buffer) : size, *f)) != 0 && size != 0) {
282 checksum.Append(buffer, len);
342 for (
const auto &s : src) {
343 auto &c = dst.emplace_back(std::make_unique<GRFConfig>(*s));
380 if (list.empty())
return;
382 auto last = std::end(list);
383 for (
auto it = std::begin(list); it != last; ++it) {
384 auto remove = std::remove_if(std::next(it), last, [&grfid = (*it)->ident.grfid](
const auto &c) { return grfid == c->ident.grfid; });
385 last = list.erase(remove, last);
406 dst.push_back(std::move(el));
434 for (
auto &c : grfconfig) {
441 Debug(grf, 1,
"NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", std::byteswap(c->ident.grfid), c->filename,
FormatArrayAsHex(c->ident.md5sum));
445 c->original_md5sum = c->ident.md5sum;
454 Debug(grf, 0,
"NewGRF {:08X} ({}) not found; checksum {}", std::byteswap(c->ident.grfid), c->filename,
FormatArrayAsHex(c->ident.md5sum));
496 this->next_update = std::chrono::steady_clock::now();
499 bool AddFile(
const std::string &filename,
size_t basepath_length,
const std::string &tar_filename)
override;
521 if (_exit_game)
return false;
524 auto c = std::make_unique<GRFConfig>(filename.substr(basepath_length));
527 if (std::ranges::none_of(
_all_grfs, [&c](
const auto &gc) {
return c->ident.grfid == gc->ident.grfid && c->ident.md5sum == gc->ident.md5sum; })) {
535 const char *name =
nullptr;
537 if (name ==
nullptr) name = grfconfig->
filename.c_str();
550static bool GRFSorter(std::unique_ptr<GRFConfig>
const &c1, std::unique_ptr<GRFConfig>
const &c2)
564 Debug(grf, 1,
"Scanning for NewGRFs");
567 Debug(grf, 1,
"Scan complete, found {} files", num);
605 assert((mode ==
FGCM_EXACT) != (md5sum ==
nullptr));
609 if (!c->ident.HasGrfIdentifier(grfid, md5sum))
continue;
611 if (md5sum !=
nullptr || mode ==
FGCM_ANY)
return c.get();
615 if (mode ==
FGCM_COMPATIBLE && !c->IsCompatible(desired_version))
continue;
617 if (best ==
nullptr || c->
version > best->
version) best = c.get();
631 auto it = std::ranges::find_if(
_grfconfig, [grfid, mask](
const auto &c) {
return (c->ident.grfid & mask) == (grfid & mask); });
632 if (it != std::end(
_grfconfig))
return it->get();
642 for (
const uint32_t &value : c.
param) {
643 if (!result.empty()) result +=
' ';
644 result += std::to_string(value);
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr EnumBitSet & Reset(Tenum value)
Reset the enum value to not set.
constexpr bool Test(Tenum value) const
Test if the enum value is set.
Helper for scanning for files with a given name.
uint Scan(std::string_view extension, Subdirectory sd, bool tars=true, bool recursive=true)
Scan for files with the given extension in the given search path.
Helper for scanning for files with GRF as extension.
static uint DoScan()
Do the scan for GRFs.
std::chrono::steady_clock::time_point next_update
The next moment we do update the screen.
bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override
Add a file with the given filename.
uint num_scanned
The number of GRFs we have scanned.
@ NEWGRF
Scan for non-base sets.
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
void GameLoopPause()
Pause the game-loop for a bit, releasing the game-state lock.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
std::optional< FileHandle > FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
Functions for Standard In/Out file operations.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Declarations for savegames operations.
Functions related to the gfx engine.
PaletteType
Palettes OpenTTD supports.
@ PAL_DOS
Use the DOS palette.
@ PAL_WINDOWS
Use the Windows palette.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
int MemCmpT(const T *ptr1, const T *ptr2, size_t num=1)
Type-safe version of memcmp().
Network functions used by other parts of OpenTTD.
void NetworkAfterNewGRFScan()
Rebuild the GRFConfig's of the servers in the game list as we did a rescan and might have found new N...
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Base for the NewGRF implementation.
void UpdateNewGRFConfigPalette(int32_t)
Update the palettes of the graphics from the config file.
GRFConfigList _grfconfig
First item in list of current GRF set up.
GRFConfigList _grfconfig_static
First item in list of static GRF set up.
void CopyGRFConfigList(GRFConfigList &dst, const GRFConfigList &src, bool init_only)
Copy a GRF Config list.
GRFListCompatibility IsGoodGRFConfigList(GRFConfigList &grfconfig)
Check if all GRFs in the GRF config from a savegame can be loaded.
static bool CalcGRFMD5Sum(GRFConfig &config, Subdirectory subdir)
Calculate the MD5 sum for a GRF, and store it in the config.
std::string GRFBuildParamList(const GRFConfig &c)
Build a string containing space separated parameter values, and terminate.
uint _missing_extra_graphics
Number of sprites provided by the fallback extra GRF, i.e. missing in the baseset.
static void RemoveDuplicatesFromGRFConfigList(GRFConfigList &list)
Removes duplicates from lists of GRFConfigs.
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
void ResetGRFConfig(bool defaults)
Reset the current GRF Config to either blank or newgame settings.
GRFConfigList _grfconfig_newgame
First item in list of default GRF set up.
GRFConfigList _all_grfs
First item in list of all scanned NewGRFs.
bool FillGRFDetails(GRFConfig &config, bool is_static, Subdirectory subdir)
Find the GRFID of a given grf, and calculate its md5sum.
static void AppendGRFConfigList(GRFConfigList &dst, const GRFConfigList &src, bool init_only)
Append a GRF Config list onto another list.
void AppendStaticGRFConfigs(GRFConfigList &dst)
Appends the static GRFs to a list of GRFs.
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
static bool GRFSorter(std::unique_ptr< GRFConfig > const &c1, std::unique_ptr< GRFConfig > const &c2)
Simple sorter for GRFS.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
size_t GRFGetSizeOfDataSection(FileHandle &f)
Get the data section size of a GRF.
void DoScanNewGRFFiles(NewGRFScanCallback *callback)
Really perform the scan for all NewGRFs.
int _skip_all_newgrf_scanning
Set this flag to prevent any NewGRF scanning from being done.
void AppendToGRFConfigList(GRFConfigList &dst, std::unique_ptr< GRFConfig > &&el)
Appends an element to a list of GRFs.
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
Functions to find and configure NewGRFs.
GRFListCompatibility
Status of post-gameload GRF compatibility check.
@ GLC_COMPATIBLE
Compatible (eg. the same ID, but different checksum) GRF found in at least one case.
@ GLC_ALL_GOOD
All GRF needed by game are present.
@ GLC_NOT_FOUND
At least one GRF couldn't be found (higher priority than GLC_COMPATIBLE)
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
void UpdateNewGRFScanStatus(uint num, const char *name)
Update the NewGRF scan status.
@ InitOnly
GRF file is processed up to GLS_INIT.
@ System
GRF file is an openttd-internal system grf.
@ Copy
The data is copied from a grf in _all_grfs.
@ Compatible
GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
@ Unsafe
GRF file is unsafe for static usage.
@ Invalid
GRF is unusable with this version of OpenTTD.
FindGRFConfigMode
Method to find GRFs using FindGRFConfig.
@ FGCM_NEWEST
Find newest Grf.
@ FGCM_ANY
Use first found.
@ FGCM_EXACT
Only find Grfs matching md5sum.
@ FGCM_COMPATIBLE
Find best compatible Grf wrt. desired_version.
@ GRFP_USE_DOS
The palette state is set to use the DOS palette.
@ GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
@ GRFP_USE_WINDOWS
The palette state is set to use the Windows palette.
@ GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
@ GRFP_USE_BIT
The bit used for storing the palette to use.
@ GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
const char * GetGRFStringFromGRFText(const GRFTextList &text_list)
Get a C-string from a GRFText-list.
Header of Action 04 "universal holder" structure and functions.
void SetModalProgress(bool state)
Set the modal progress state.
Functions related to modal progress.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
const uint8_t _grf_cont_v2_sig[8]
Signature of a container version 2 GRF.
Definition of base types and functions in a cross-platform compatible way.
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Functions related to low-level strings.
bool StrEmpty(const char *s)
Check if a string buffer is empty.
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
GUISettings gui
settings related to the GUI
Information about GRF, used in the game and (part of it) in savegames.
void SetParameterDefaults()
Set the default value for all parameters as specified by action14.
const char * GetURL() const
Get the grf url.
GRFTextWrapper url
NOSAVE: URL belonging to this GRF.
uint8_t palette
GRFPalette, bitset.
const char * GetDescription() const
Get the grf info.
GRFTextWrapper info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
std::vector< std::optional< GRFParameterInfo > > param_info
NOSAVE: extra information about the parameters.
uint32_t version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
std::vector< uint32_t > param
GRF parameters.
void FinalizeParameterInfo()
Finalize Action 14 info after file scan is finished.
bool has_param_defaults
NOSAVE: did this newgrf specify any defaults for it's parameters.
GRFTextWrapper name
NOSAVE: GRF name (Action 0x08)
GRFStatus status
NOSAVE: GRFStatus, enum.
void SetValue(const GRFParameterInfo &info, uint32_t value)
Set the value of the given user-changeable parameter.
bool IsCompatible(uint32_t old_version) const
Return whether this NewGRF can replace an older version of the same NewGRF.
void CopyParams(const GRFConfig &src)
Copy the parameter information from the src config.
std::optional< std::string > GetTextfile(TextfileType type) const
Search a textfile file next to this NewGRF.
GRFConfigFlags flags
NOSAVE: GCF_Flags, bitset.
uint8_t num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
std::string filename
Filename - either with or without full path.
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
const char * GetName() const
Get the name of this grf.
void SetSuitablePalette()
Set the palette of this GRFConfig to something suitable.
uint32_t min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
uint32_t GetValue(const GRFParameterInfo &info) const
Get the value of the given user-changeable parameter.
GRFError(StringID severity, StringID message={})
Construct a new GRFError.
uint32_t grfid
GRF ID (defined by Action 0x08)
MD5Hash md5sum
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Information about one grf parameter.
bool complete_labels
True if all values have a label.
uint8_t param_nr
GRF parameter to store content in.
uint32_t min_value
The minimal value this parameter can have.
uint32_t max_value
The maximal value of this parameter.
std::vector< ValueName > value_names
Names for each value.
void Finalize()
Finalize Action 14 info after file scan is finished.
uint32_t last_newgrf_count
the numbers of NewGRFs we found during the last scan
uint8_t newgrf_default_palette
default palette to use for NewGRFs without action 14 palette information
Callback for NewGRF scanning.
virtual void OnNewGRFsScanned()=0
Called whenever the NewGRF scan completed.
GUI functions related to textfiles.
TextfileType
Additional text files accompanying Tar archives.
Base of all video drivers.
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Window functions not directly related to making/drawing windows.
@ WN_GAME_OPTIONS_NEWGRF_STATE
NewGRF settings.
@ GOID_NEWGRF_RESCANNED
NewGRFs were just rescanned.
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_SAVELOAD
Saveload window; Window numbers:
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers: