OpenTTD Source 20241224-master-gf74b0cf984
newgrf_config.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "stdafx.h"
11#include "debug.h"
12#include "3rdparty/md5/md5.h"
13#include "newgrf.h"
15#include "gfx_func.h"
16#include "newgrf_text.h"
17#include "window_func.h"
18#include "progress.h"
20#include "string_func.h"
21#include "strings_func.h"
22#include "textfile_gui.h"
23#include "thread.h"
24#include "newgrf_config.h"
25#include "newgrf_text.h"
26
27#include "fileio_func.h"
28#include "fios.h"
29
30#include "safeguards.h"
31
32
37GRFConfig::GRFConfig(const std::string &filename) : filename(filename), num_valid_params(MAX_NUM_PARAMS) {}
38
45 ident(config.ident),
46 original_md5sum(config.original_md5sum),
47 filename(config.filename),
48 name(config.name),
49 info(config.info),
50 url(config.url),
51 error(config.error),
52 version(config.version),
53 min_loadable_version(config.min_loadable_version),
54 flags(config.flags & ~(1 << GCF_COPY)),
55 status(config.status),
56 grf_bugs(config.grf_bugs),
57 num_valid_params(config.num_valid_params),
58 palette(config.palette),
59 has_param_defaults(config.has_param_defaults),
60 param_info(config.param_info),
61 param(config.param)
62{
63}
64
65void GRFConfig::SetParams(std::span<const uint32_t> pars)
66{
67 this->param.assign(std::begin(pars), std::end(pars));
68}
69
73bool GRFConfig::IsCompatible(uint32_t old_version) const
74{
75 return this->min_loadable_version <= old_version && old_version <= this->version;
76}
77
83{
84 this->param = src.param;
85}
86
92const char *GRFConfig::GetName() const
93{
94 const char *name = GetGRFStringFromGRFText(this->name);
95 return StrEmpty(name) ? this->filename.c_str() : name;
96}
97
102const char *GRFConfig::GetDescription() const
103{
104 return GetGRFStringFromGRFText(this->info);
105}
106
111const char *GRFConfig::GetURL() const
112{
113 return GetGRFStringFromGRFText(this->url);
114}
115
118{
119 this->param.clear();
120
121 if (!this->has_param_defaults) return;
122
123 for (const auto &info : this->param_info) {
124 if (!info.has_value()) continue;
125 this->SetValue(info.value(), info->def_value);
126 }
127}
128
135{
136 PaletteType pal;
137 switch (this->palette & GRFP_GRF_MASK) {
138 case GRFP_GRF_DOS: pal = PAL_DOS; break;
139 case GRFP_GRF_WINDOWS: pal = PAL_WINDOWS; break;
140 default: pal = _settings_client.gui.newgrf_default_palette == 1 ? PAL_WINDOWS : PAL_DOS; break;
141 }
143}
144
149{
150 for (auto &info : this->param_info) {
151 if (!info.has_value()) continue;
152 info->Finalize();
153 }
154}
155
161
167GRFError::GRFError(StringID severity, StringID message) : message(message), severity(severity)
168{
169}
170
176uint32_t GRFConfig::GetValue(const GRFParameterInfo &info) const
177{
178 /* If the parameter is not set then it must be 0. */
179 if (info.param_nr >= std::size(this->param)) return 0;
180
181 /* GB doesn't work correctly with nbits == 32, so handle that case here. */
182 if (info.num_bit == 32) return this->param[info.param_nr];
183
184 return GB(this->param[info.param_nr], info.first_bit, info.num_bit);
185}
186
192void GRFConfig::SetValue(const GRFParameterInfo &info, uint32_t value)
193{
194 value = Clamp(value, info.min_value, info.max_value);
195
196 /* Allocate the new parameter if it's not already present. */
197 if (info.param_nr >= std::size(this->param)) this->param.resize(info.param_nr + 1);
198
199 /* SB doesn't work correctly with nbits == 32, so handle that case here. */
200 if (info.num_bit == 32) {
201 this->param[info.param_nr] = value;
202 } else {
203 SB(this->param[info.param_nr], info.first_bit, info.num_bit, value);
204 }
205
207}
208
213{
214 this->complete_labels = true;
215 for (uint32_t value = this->min_value; value <= this->max_value; value++) {
216 if (this->value_names.count(value) == 0) {
217 this->complete_labels = false;
218 break;
219 }
220 }
221}
222
228{
229 for (GRFConfig *c = _grfconfig_newgame; c != nullptr; c = c->next) c->SetSuitablePalette();
230 for (GRFConfig *c = _grfconfig_static; c != nullptr; c = c->next) c->SetSuitablePalette();
231 for (GRFConfig *c = _all_grfs; c != nullptr; c = c->next) c->SetSuitablePalette();
232}
233
240{
241 extern const uint8_t _grf_cont_v2_sig[];
242 static const uint header_len = 14;
243
244 uint8_t data[header_len];
245 if (fread(data, 1, header_len, f) == header_len) {
246 if (data[0] == 0 && data[1] == 0 && MemCmpT(data + 2, _grf_cont_v2_sig, 8) == 0) {
247 /* Valid container version 2, get data section size. */
248 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]);
249 if (offset >= 1 * 1024 * 1024 * 1024) {
250 Debug(grf, 0, "Unexpectedly large offset for NewGRF");
251 /* Having more than 1 GiB of data is very implausible. Mostly because then
252 * all pools in OpenTTD are flooded already. Or it's just Action C all over.
253 * In any case, the offsets to graphics will likely not work either. */
254 return SIZE_MAX;
255 }
256 return header_len + offset;
257 }
258 }
259
260 return SIZE_MAX;
261}
262
269static bool CalcGRFMD5Sum(GRFConfig *config, Subdirectory subdir)
270{
271 Md5 checksum;
272 uint8_t buffer[1024];
273 size_t len, size;
274
275 /* open the file */
276 auto f = FioFOpenFile(config->filename, "rb", subdir, &size);
277 if (!f.has_value()) return false;
278
279 long start = ftell(*f);
280 size = std::min(size, GRFGetSizeOfDataSection(*f));
281
282 if (start < 0 || fseek(*f, start, SEEK_SET) < 0) {
283 return false;
284 }
285
286 /* calculate md5sum */
287 while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, *f)) != 0 && size != 0) {
288 size -= len;
289 checksum.Append(buffer, len);
290 }
291 checksum.Finish(config->ident.md5sum);
292
293 return true;
294}
295
296
304bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
305{
306 if (!FioCheckFileExists(config->filename, subdir)) {
307 config->status = GCS_NOT_FOUND;
308 return false;
309 }
310
311 /* Find and load the Action 8 information */
312 LoadNewGRFFile(config, GLS_FILESCAN, subdir, true);
313 config->SetSuitablePalette();
314 config->FinalizeParameterInfo();
315
316 /* Skip if the grfid is 0 (not read) or if it is an internal GRF */
317 if (config->ident.grfid == 0 || HasBit(config->flags, GCF_SYSTEM)) return false;
318
319 if (is_static) {
320 /* Perform a 'safety scan' for static GRFs */
321 LoadNewGRFFile(config, GLS_SAFETYSCAN, subdir, true);
322
323 /* GCF_UNSAFE is set if GLS_SAFETYSCAN finds unsafe actions */
324 if (HasBit(config->flags, GCF_UNSAFE)) return false;
325 }
326
327 return CalcGRFMD5Sum(config, subdir);
328}
329
330
337{
338 GRFConfig *c, *next;
339 for (c = *config; c != nullptr; c = next) {
340 next = c->next;
341 delete c;
342 }
343 *config = nullptr;
344}
345
346
354GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only)
355{
356 /* Clear destination as it will be overwritten */
358 for (; src != nullptr; src = src->next) {
359 GRFConfig *c = new GRFConfig(*src);
360
362 if (init_only) SetBit(c->flags, GCF_INIT_ONLY);
363
364 *dst = c;
365 dst = &c->next;
366 }
367
368 return dst;
369}
370
385{
386 GRFConfig *prev;
387 GRFConfig *cur;
388
389 if (list == nullptr) return;
390
391 for (prev = list, cur = list->next; cur != nullptr; prev = cur, cur = cur->next) {
392 if (cur->ident.grfid != list->ident.grfid) continue;
393
394 prev->next = cur->next;
395 delete cur;
396 cur = prev; // Just go back one so it continues as normal later on
397 }
398
400}
401
407{
408 GRFConfig **tail = dst;
409 while (*tail != nullptr) tail = &(*tail)->next;
410
413}
414
421{
422 GRFConfig **tail = dst;
423 while (*tail != nullptr) tail = &(*tail)->next;
424 *tail = el;
425
427}
428
429
436
437
450{
452
453 for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) {
454 const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, &c->ident.md5sum);
455 if (f == nullptr || HasBit(f->flags, GCF_INVALID)) {
456 /* If we have not found the exactly matching GRF try to find one with the
457 * same grfid, as it most likely is compatible */
458 f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version);
459 if (f != nullptr) {
460 Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, FormatArrayAsHex(c->ident.md5sum));
461 if (!HasBit(c->flags, GCF_COMPATIBLE)) {
462 /* Preserve original_md5sum after it has been assigned */
463 SetBit(c->flags, GCF_COMPATIBLE);
464 c->original_md5sum = c->ident.md5sum;
465 }
466
467 /* Non-found has precedence over compatibility load */
468 if (res != GLC_NOT_FOUND) res = GLC_COMPATIBLE;
469 goto compatible_grf;
470 }
471
472 /* No compatible grf was found, mark it as disabled */
473 Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, FormatArrayAsHex(c->ident.md5sum));
474
475 c->status = GCS_NOT_FOUND;
476 res = GLC_NOT_FOUND;
477 } else {
478compatible_grf:
479 Debug(grf, 1, "Loading GRF {:08X} from {}", BSWAP32(f->ident.grfid), f->filename);
480 /* The filename could be the filename as in the savegame. As we need
481 * to load the GRF here, we need the correct filename, so overwrite that
482 * in any case and set the name and info when it is not set already.
483 * When the GCF_COPY flag is set, it is certain that the filename is
484 * already a local one, so there is no need to replace it. */
485 if (!HasBit(c->flags, GCF_COPY)) {
486 c->filename = f->filename;
487 c->ident.md5sum = f->ident.md5sum;
488 c->name = f->name;
489 c->info = f->name;
490 c->error.reset();
491 c->version = f->version;
492 c->min_loadable_version = f->min_loadable_version;
493 c->num_valid_params = f->num_valid_params;
494 c->param_info = f->param_info;
495 c->has_param_defaults = f->has_param_defaults;
496 }
497 }
498 }
499
500 return res;
501}
502
503
506
509 std::chrono::steady_clock::time_point next_update;
511
512public:
514 {
515 this->next_update = std::chrono::steady_clock::now();
516 }
517
518 bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override;
519
521 static uint DoScan()
522 {
525 return 0;
526 }
527
529 int ret = fs.Scan(".grf", NEWGRF_DIR);
530 /* The number scanned and the number returned may not be the same;
531 * duplicate NewGRFs and base sets are ignored in the return value. */
533 return ret;
534 }
535};
536
537bool GRFFileScanner::AddFile(const std::string &filename, size_t basepath_length, const std::string &)
538{
539 /* Abort if the user stopped the game during a scan. */
540 if (_exit_game) return false;
541
542 GRFConfig *c = new GRFConfig(filename.c_str() + basepath_length);
543
544 bool added = true;
545 if (FillGRFDetails(c, false)) {
546 if (_all_grfs == nullptr) {
547 _all_grfs = c;
548 } else {
549 /* Insert file into list at a position determined by its
550 * name, so the list is sorted as we go along */
551 GRFConfig **pd, *d;
552 bool stop = false;
553 for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) {
554 if (c->ident.grfid == d->ident.grfid && c->ident.md5sum == d->ident.md5sum) added = false;
555 /* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name,
556 * before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of
557 * just after the first with the same name. Avoids doubles in the list. */
558 if (StrCompareIgnoreCase(c->GetName(), d->GetName()) <= 0) {
559 stop = true;
560 } else if (stop) {
561 break;
562 }
563 }
564 if (added) {
565 c->next = d;
566 *pd = c;
567 }
568 }
569 } else {
570 added = false;
571 }
572
573 this->num_scanned++;
574
575 const char *name = nullptr;
576 if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name);
577 if (name == nullptr) name = c->filename.c_str();
580
581 if (!added) {
582 /* File couldn't be opened, or is either not a NewGRF or is a
583 * 'system' NewGRF or it's already known, so forget about it. */
584 delete c;
585 }
586
587 return added;
588}
589
596static bool GRFSorter(GRFConfig * const &c1, GRFConfig * const &c2)
597{
598 return StrNaturalCompare(c1->GetName(), c2->GetName()) < 0;
599}
600
606{
609
610 Debug(grf, 1, "Scanning for NewGRFs");
611 uint num = GRFFileScanner::DoScan();
612
613 Debug(grf, 1, "Scan complete, found {} files", num);
614 if (num != 0 && _all_grfs != nullptr) {
615 /* Sort the linked list using quicksort.
616 * For that we first have to make an array, then sort and
617 * then remake the linked list. */
618 std::vector<GRFConfig *> to_sort;
619
620 uint i = 0;
621 for (GRFConfig *p = _all_grfs; p != nullptr; p = p->next, i++) {
622 to_sort.push_back(p);
623 }
624 /* Number of files is not necessarily right */
625 num = i;
626
627 std::sort(to_sort.begin(), to_sort.end(), GRFSorter);
628
629 for (i = 1; i < num; i++) {
630 to_sort[i - 1]->next = to_sort[i];
631 }
632 to_sort[num - 1]->next = nullptr;
633 _all_grfs = to_sort[0];
634
636 }
637
638 /* Yes... these are the NewGRF windows */
641 if (!_exit_game && callback != nullptr) callback->OnNewGRFsScanned();
642
644 SetModalProgress(false);
646}
647
653{
654 /* First set the modal progress. This ensures that it will eventually let go of the paint mutex. */
655 SetModalProgress(true);
656 /* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */
658
659 DoScanNewGRFFiles(callback);
660}
661
670const GRFConfig *FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
671{
672 assert((mode == FGCM_EXACT) != (md5sum == nullptr));
673 const GRFConfig *best = nullptr;
674 for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
675 /* if md5sum is set, we look for an exact match and continue if not found */
676 if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
677 /* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */
678 if (md5sum != nullptr || mode == FGCM_ANY) return c;
679 /* Skip incompatible stuff, unless explicitly allowed */
680 if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue;
681 /* check version compatibility */
682 if (mode == FGCM_COMPATIBLE && !c->IsCompatible(desired_version)) continue;
683 /* remember the newest one as "the best" */
684 if (best == nullptr || c->version > best->version) best = c;
685 }
686
687 return best;
688}
689
696GRFConfig *GetGRFConfig(uint32_t grfid, uint32_t mask)
697{
698 GRFConfig *c;
699
700 for (c = _grfconfig; c != nullptr; c = c->next) {
701 if ((c->ident.grfid & mask) == (grfid & mask)) return c;
702 }
703
704 return nullptr;
705}
706
707
709std::string GRFBuildParamList(const GRFConfig *c)
710{
711 std::string result;
712 for (const uint32_t &value : c->param) {
713 if (!result.empty()) result += ' ';
714 result += std::to_string(value);
715 }
716 return result;
717}
718
724std::optional<std::string> GRFConfig::GetTextfile(TextfileType type) const
725{
726 return ::GetTextfile(type, NEWGRF_DIR, this->filename);
727}
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
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.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
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 T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Helper for scanning for files with a given name.
Definition fileio_func.h:37
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.
Definition fileio.cpp:1114
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.
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition fileio.cpp:375
@ NEWGRF
Scan for non-base sets.
Definition fileio_func.h:66
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.
Base class that provides memory initialization on dynamically created objects.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
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.
Definition fileio.cpp:242
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.
Definition gfx_type.h:304
@ PAL_DOS
Use the DOS palette.
Definition gfx_type.h:305
@ PAL_WINDOWS
Use the Windows palette.
Definition gfx_type.h:306
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1529
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
int MemCmpT(const T *ptr1, const T *ptr2, size_t num=1)
Type-safe version of memcmp().
Definition mem_func.hpp:63
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.
Definition newgrf.cpp:9790
Base for the NewGRF implementation.
void UpdateNewGRFConfigPalette(int32_t)
Update the palettes of the graphics from the config file.
GRFConfig * _all_grfs
First item in list of all scanned NewGRFs.
std::string GRFBuildParamList(const GRFConfig *c)
Build a string containing space separated parameter values, and terminate.
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
uint _missing_extra_graphics
Number of sprites provided by the fallback extra GRF, i.e. missing in the baseset.
void AppendToGRFConfigList(GRFConfig **dst, GRFConfig *el)
Appends an element to a list of GRFs.
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
Find the GRFID of a given grf, and calculate its md5sum.
GRFConfig * _grfconfig
First item in list of current GRF set up.
GRFConfig ** CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only)
Copy a GRF Config list.
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
static bool GRFSorter(GRFConfig *const &c1, GRFConfig *const &c2)
Simple sorter for GRFS.
void ResetGRFConfig(bool defaults)
Reset the current GRF Config to either blank or newgame settings.
static bool CalcGRFMD5Sum(GRFConfig *config, Subdirectory subdir)
Calculate the MD5 sum for a GRF, and store it in the config.
GRFConfig * _grfconfig_static
First item in list of static GRF set up.
static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list)
Removes duplicates from lists of GRFConfigs.
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
Check if all GRFs in the GRF config from a savegame can be loaded.
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
void AppendStaticGRFConfigs(GRFConfig **dst)
Appends the static GRFs to a list of 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.
GRFConfig * _grfconfig_newgame
First item in list of default GRF set up.
int _skip_all_newgrf_scanning
Set this flag to prevent any NewGRF scanning from being done.
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)
@ 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.
void UpdateNewGRFScanStatus(uint num, const char *name)
Update the NewGRF scan status.
@ GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
@ GCF_INVALID
GRF is unusable with this version of OpenTTD.
@ GCF_UNSAFE
GRF file is unsafe for static usage.
@ GCF_COMPATIBLE
GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
@ GCF_COPY
The data is copied from a grf in _all_grfs.
@ GCF_SYSTEM
GRF file is an openttd-internal system grf.
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
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.
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.
Definition progress.cpp:22
Functions related to modal progress.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
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.
Definition string.cpp:81
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition string.cpp:589
int StrCompareIgnoreCase(const std::string_view str1, const std::string_view str2)
Compares two string( view)s, while ignoring the case of the characters.
Definition string.cpp:334
Functions related to low-level strings.
bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition string_func.h:57
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.
GRFConfig(const std::string &filename=std::string{})
Create a new GRFConfig.
GRFTextWrapper url
NOSAVE: URL belonging to this GRF.
uint8_t palette
GRFPalette, bitset.
uint8_t flags
NOSAVE: GCF_Flags, 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)
struct GRFConfig * next
NOSAVE: Next item in the linked list.
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.
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=0)
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.
std::map< uint32_t, GRFTextList > value_names
Names for each value.
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.
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 threads.
Base of all video drivers.
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1152
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-...
Definition window.cpp:3219
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3101
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...
Definition window.cpp:3236
Window functions not directly related to making/drawing windows.
@ WN_GAME_OPTIONS_NEWGRF_STATE
NewGRF settings.
Definition window_type.h:25
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_SAVELOAD
Saveload window; Window numbers:
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers:
@ GOID_NEWGRF_RESCANNED
NewGRFs were just rescanned.