OpenTTD Source  20241108-master-g80f628063a
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"
14 #include "network/network_func.h"
15 #include "gfx_func.h"
16 #include "newgrf_text.h"
17 #include "window_func.h"
18 #include "progress.h"
19 #include "video/video_driver.hpp"
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 
37 GRFConfig::GRFConfig(const std::string &filename) :
38  filename(filename), num_valid_params(ClampTo<uint8_t>(GRFConfig::param.size()))
39 {
40 }
41 
48  ident(config.ident),
49  original_md5sum(config.original_md5sum),
50  filename(config.filename),
51  name(config.name),
52  info(config.info),
53  url(config.url),
54  error(config.error),
55  version(config.version),
56  min_loadable_version(config.min_loadable_version),
57  flags(config.flags & ~(1 << GCF_COPY)),
58  status(config.status),
59  grf_bugs(config.grf_bugs),
60  param(config.param),
61  num_params(config.num_params),
62  num_valid_params(config.num_valid_params),
63  palette(config.palette),
64  param_info(config.param_info),
65  has_param_defaults(config.has_param_defaults)
66 {
67 }
68 
69 void GRFConfig::SetParams(const std::vector<uint32_t> &pars)
70 {
71  this->num_params = static_cast<uint8_t>(std::min(this->param.size(), pars.size()));
72  std::copy(pars.begin(), pars.begin() + this->num_params, this->param.begin());
73 }
74 
78 bool GRFConfig::IsCompatible(uint32_t old_version) const
79 {
80  return this->min_loadable_version <= old_version && old_version <= this->version;
81 }
82 
88 {
89  this->num_params = src.num_params;
90  this->param = src.param;
91 }
92 
98 const char *GRFConfig::GetName() const
99 {
100  const char *name = GetGRFStringFromGRFText(this->name);
101  return StrEmpty(name) ? this->filename.c_str() : name;
102 }
103 
108 const char *GRFConfig::GetDescription() const
109 {
110  return GetGRFStringFromGRFText(this->info);
111 }
112 
117 const char *GRFConfig::GetURL() const
118 {
119  return GetGRFStringFromGRFText(this->url);
120 }
121 
124 {
125  this->num_params = 0;
126  this->param = {};
127 
128  if (!this->has_param_defaults) return;
129 
130  for (uint i = 0; i < this->param_info.size(); i++) {
131  if (!this->param_info[i]) continue;
132  this->param_info[i]->SetValue(this, this->param_info[i]->def_value);
133  }
134 }
135 
142 {
143  PaletteType pal;
144  switch (this->palette & GRFP_GRF_MASK) {
145  case GRFP_GRF_DOS: pal = PAL_DOS; break;
146  case GRFP_GRF_WINDOWS: pal = PAL_WINDOWS; break;
147  default: pal = _settings_client.gui.newgrf_default_palette == 1 ? PAL_WINDOWS : PAL_DOS; break;
148  }
150 }
151 
156 {
157  for (auto &info : this->param_info) {
158  if (!info.has_value()) continue;
159  info->Finalize();
160  }
161 }
162 
168 
174 GRFError::GRFError(StringID severity, StringID message) : message(message), severity(severity)
175 {
176 }
177 
183  name(),
184  desc(),
185  type(PTYPE_UINT_ENUM),
186  min_value(0),
187  max_value(UINT32_MAX),
188  def_value(0),
189  param_nr(nr),
190  first_bit(0),
191  num_bit(32),
192  value_names(),
193  complete_labels(false)
194 {}
195 
201 uint32_t GRFParameterInfo::GetValue(struct GRFConfig *config) const
202 {
203  /* GB doesn't work correctly with nbits == 32, so handle that case here. */
204  if (this->num_bit == 32) return config->param[this->param_nr];
205  return GB(config->param[this->param_nr], this->first_bit, this->num_bit);
206 }
207 
213 void GRFParameterInfo::SetValue(struct GRFConfig *config, uint32_t value)
214 {
215  /* SB doesn't work correctly with nbits == 32, so handle that case here. */
216  if (this->num_bit == 32) {
217  config->param[this->param_nr] = value;
218  } else {
219  SB(config->param[this->param_nr], this->first_bit, this->num_bit, value);
220  }
221  config->num_params = std::max<uint>(config->num_params, this->param_nr + 1);
223 }
224 
229 {
230  this->complete_labels = true;
231  for (uint32_t value = this->min_value; value <= this->max_value; value++) {
232  if (this->value_names.count(value) == 0) {
233  this->complete_labels = false;
234  break;
235  }
236  }
237 }
238 
244 {
245  for (GRFConfig *c = _grfconfig_newgame; c != nullptr; c = c->next) c->SetSuitablePalette();
246  for (GRFConfig *c = _grfconfig_static; c != nullptr; c = c->next) c->SetSuitablePalette();
247  for (GRFConfig *c = _all_grfs; c != nullptr; c = c->next) c->SetSuitablePalette();
248 }
249 
256 {
257  extern const uint8_t _grf_cont_v2_sig[];
258  static const uint header_len = 14;
259 
260  uint8_t data[header_len];
261  if (fread(data, 1, header_len, f) == header_len) {
262  if (data[0] == 0 && data[1] == 0 && MemCmpT(data + 2, _grf_cont_v2_sig, 8) == 0) {
263  /* Valid container version 2, get data section size. */
264  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]);
265  if (offset >= 1 * 1024 * 1024 * 1024) {
266  Debug(grf, 0, "Unexpectedly large offset for NewGRF");
267  /* Having more than 1 GiB of data is very implausible. Mostly because then
268  * all pools in OpenTTD are flooded already. Or it's just Action C all over.
269  * In any case, the offsets to graphics will likely not work either. */
270  return SIZE_MAX;
271  }
272  return header_len + offset;
273  }
274  }
275 
276  return SIZE_MAX;
277 }
278 
285 static bool CalcGRFMD5Sum(GRFConfig *config, Subdirectory subdir)
286 {
287  Md5 checksum;
288  uint8_t buffer[1024];
289  size_t len, size;
290 
291  /* open the file */
292  auto f = FioFOpenFile(config->filename, "rb", subdir, &size);
293  if (!f.has_value()) return false;
294 
295  long start = ftell(*f);
296  size = std::min(size, GRFGetSizeOfDataSection(*f));
297 
298  if (start < 0 || fseek(*f, start, SEEK_SET) < 0) {
299  return false;
300  }
301 
302  /* calculate md5sum */
303  while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, *f)) != 0 && size != 0) {
304  size -= len;
305  checksum.Append(buffer, len);
306  }
307  checksum.Finish(config->ident.md5sum);
308 
309  return true;
310 }
311 
312 
320 bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
321 {
322  if (!FioCheckFileExists(config->filename, subdir)) {
323  config->status = GCS_NOT_FOUND;
324  return false;
325  }
326 
327  /* Find and load the Action 8 information */
328  LoadNewGRFFile(config, GLS_FILESCAN, subdir, true);
329  config->SetSuitablePalette();
330  config->FinalizeParameterInfo();
331 
332  /* Skip if the grfid is 0 (not read) or if it is an internal GRF */
333  if (config->ident.grfid == 0 || HasBit(config->flags, GCF_SYSTEM)) return false;
334 
335  if (is_static) {
336  /* Perform a 'safety scan' for static GRFs */
337  LoadNewGRFFile(config, GLS_SAFETYSCAN, subdir, true);
338 
339  /* GCF_UNSAFE is set if GLS_SAFETYSCAN finds unsafe actions */
340  if (HasBit(config->flags, GCF_UNSAFE)) return false;
341  }
342 
343  return CalcGRFMD5Sum(config, subdir);
344 }
345 
346 
353 {
354  GRFConfig *c, *next;
355  for (c = *config; c != nullptr; c = next) {
356  next = c->next;
357  delete c;
358  }
359  *config = nullptr;
360 }
361 
362 
370 GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only)
371 {
372  /* Clear destination as it will be overwritten */
373  ClearGRFConfigList(dst);
374  for (; src != nullptr; src = src->next) {
375  GRFConfig *c = new GRFConfig(*src);
376 
378  if (init_only) SetBit(c->flags, GCF_INIT_ONLY);
379 
380  *dst = c;
381  dst = &c->next;
382  }
383 
384  return dst;
385 }
386 
401 {
402  GRFConfig *prev;
403  GRFConfig *cur;
404 
405  if (list == nullptr) return;
406 
407  for (prev = list, cur = list->next; cur != nullptr; prev = cur, cur = cur->next) {
408  if (cur->ident.grfid != list->ident.grfid) continue;
409 
410  prev->next = cur->next;
411  delete cur;
412  cur = prev; // Just go back one so it continues as normal later on
413  }
414 
416 }
417 
423 {
424  GRFConfig **tail = dst;
425  while (*tail != nullptr) tail = &(*tail)->next;
426 
427  CopyGRFConfigList(tail, _grfconfig_static, false);
429 }
430 
437 {
438  GRFConfig **tail = dst;
439  while (*tail != nullptr) tail = &(*tail)->next;
440  *tail = el;
441 
443 }
444 
445 
447 void ResetGRFConfig(bool defaults)
448 {
451 }
452 
453 
466 {
468 
469  for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) {
470  const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, &c->ident.md5sum);
471  if (f == nullptr || HasBit(f->flags, GCF_INVALID)) {
472  /* If we have not found the exactly matching GRF try to find one with the
473  * same grfid, as it most likely is compatible */
474  f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version);
475  if (f != nullptr) {
476  Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, FormatArrayAsHex(c->ident.md5sum));
477  if (!HasBit(c->flags, GCF_COMPATIBLE)) {
478  /* Preserve original_md5sum after it has been assigned */
479  SetBit(c->flags, GCF_COMPATIBLE);
480  c->original_md5sum = c->ident.md5sum;
481  }
482 
483  /* Non-found has precedence over compatibility load */
484  if (res != GLC_NOT_FOUND) res = GLC_COMPATIBLE;
485  goto compatible_grf;
486  }
487 
488  /* No compatible grf was found, mark it as disabled */
489  Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, FormatArrayAsHex(c->ident.md5sum));
490 
491  c->status = GCS_NOT_FOUND;
492  res = GLC_NOT_FOUND;
493  } else {
494 compatible_grf:
495  Debug(grf, 1, "Loading GRF {:08X} from {}", BSWAP32(f->ident.grfid), f->filename);
496  /* The filename could be the filename as in the savegame. As we need
497  * to load the GRF here, we need the correct filename, so overwrite that
498  * in any case and set the name and info when it is not set already.
499  * When the GCF_COPY flag is set, it is certain that the filename is
500  * already a local one, so there is no need to replace it. */
501  if (!HasBit(c->flags, GCF_COPY)) {
502  c->filename = f->filename;
503  c->ident.md5sum = f->ident.md5sum;
504  c->name = f->name;
505  c->info = f->name;
506  c->error.reset();
507  c->version = f->version;
508  c->min_loadable_version = f->min_loadable_version;
509  c->num_valid_params = f->num_valid_params;
510  c->param_info = f->param_info;
511  c->has_param_defaults = f->has_param_defaults;
512  }
513  }
514  }
515 
516  return res;
517 }
518 
519 
522 
525  std::chrono::steady_clock::time_point next_update;
526  uint num_scanned;
527 
528 public:
530  {
531  this->next_update = std::chrono::steady_clock::now();
532  }
533 
534  bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override;
535 
537  static uint DoScan()
538  {
539  if (_skip_all_newgrf_scanning > 0) {
541  return 0;
542  }
543 
544  GRFFileScanner fs;
545  int ret = fs.Scan(".grf", NEWGRF_DIR);
546  /* The number scanned and the number returned may not be the same;
547  * duplicate NewGRFs and base sets are ignored in the return value. */
549  return ret;
550  }
551 };
552 
553 bool GRFFileScanner::AddFile(const std::string &filename, size_t basepath_length, const std::string &)
554 {
555  /* Abort if the user stopped the game during a scan. */
556  if (_exit_game) return false;
557 
558  GRFConfig *c = new GRFConfig(filename.c_str() + basepath_length);
559 
560  bool added = true;
561  if (FillGRFDetails(c, false)) {
562  if (_all_grfs == nullptr) {
563  _all_grfs = c;
564  } else {
565  /* Insert file into list at a position determined by its
566  * name, so the list is sorted as we go along */
567  GRFConfig **pd, *d;
568  bool stop = false;
569  for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) {
570  if (c->ident.grfid == d->ident.grfid && c->ident.md5sum == d->ident.md5sum) added = false;
571  /* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name,
572  * before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of
573  * just after the first with the same name. Avoids doubles in the list. */
574  if (StrCompareIgnoreCase(c->GetName(), d->GetName()) <= 0) {
575  stop = true;
576  } else if (stop) {
577  break;
578  }
579  }
580  if (added) {
581  c->next = d;
582  *pd = c;
583  }
584  }
585  } else {
586  added = false;
587  }
588 
589  this->num_scanned++;
590 
591  const char *name = nullptr;
592  if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name);
593  if (name == nullptr) name = c->filename.c_str();
594  UpdateNewGRFScanStatus(this->num_scanned, name);
596 
597  if (!added) {
598  /* File couldn't be opened, or is either not a NewGRF or is a
599  * 'system' NewGRF or it's already known, so forget about it. */
600  delete c;
601  }
602 
603  return added;
604 }
605 
612 static bool GRFSorter(GRFConfig * const &c1, GRFConfig * const &c2)
613 {
614  return StrNaturalCompare(c1->GetName(), c2->GetName()) < 0;
615 }
616 
622 {
625 
626  Debug(grf, 1, "Scanning for NewGRFs");
627  uint num = GRFFileScanner::DoScan();
628 
629  Debug(grf, 1, "Scan complete, found {} files", num);
630  if (num != 0 && _all_grfs != nullptr) {
631  /* Sort the linked list using quicksort.
632  * For that we first have to make an array, then sort and
633  * then remake the linked list. */
634  std::vector<GRFConfig *> to_sort;
635 
636  uint i = 0;
637  for (GRFConfig *p = _all_grfs; p != nullptr; p = p->next, i++) {
638  to_sort.push_back(p);
639  }
640  /* Number of files is not necessarily right */
641  num = i;
642 
643  std::sort(to_sort.begin(), to_sort.end(), GRFSorter);
644 
645  for (i = 1; i < num; i++) {
646  to_sort[i - 1]->next = to_sort[i];
647  }
648  to_sort[num - 1]->next = nullptr;
649  _all_grfs = to_sort[0];
650 
652  }
653 
654  /* Yes... these are the NewGRF windows */
657  if (!_exit_game && callback != nullptr) callback->OnNewGRFsScanned();
658 
660  SetModalProgress(false);
662 }
663 
669 {
670  /* First set the modal progress. This ensures that it will eventually let go of the paint mutex. */
671  SetModalProgress(true);
672  /* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */
674 
675  DoScanNewGRFFiles(callback);
676 }
677 
686 const GRFConfig *FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
687 {
688  assert((mode == FGCM_EXACT) != (md5sum == nullptr));
689  const GRFConfig *best = nullptr;
690  for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
691  /* if md5sum is set, we look for an exact match and continue if not found */
692  if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
693  /* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */
694  if (md5sum != nullptr || mode == FGCM_ANY) return c;
695  /* Skip incompatible stuff, unless explicitly allowed */
696  if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue;
697  /* check version compatibility */
698  if (mode == FGCM_COMPATIBLE && !c->IsCompatible(desired_version)) continue;
699  /* remember the newest one as "the best" */
700  if (best == nullptr || c->version > best->version) best = c;
701  }
702 
703  return best;
704 }
705 
712 GRFConfig *GetGRFConfig(uint32_t grfid, uint32_t mask)
713 {
714  GRFConfig *c;
715 
716  for (c = _grfconfig; c != nullptr; c = c->next) {
717  if ((c->ident.grfid & mask) == (grfid & mask)) return c;
718  }
719 
720  return nullptr;
721 }
722 
723 
725 std::string GRFBuildParamList(const GRFConfig *c)
726 {
727  std::string result;
728  for (uint i = 0; i < c->num_params; i++) {
729  if (!result.empty()) result += ' ';
730  result += std::to_string(c->param[i]);
731  }
732  return result;
733 }
734 
740 std::optional<std::string> GRFConfig::GetTextfile(TextfileType type) const
741 {
743 }
constexpr debug_inline 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.
constexpr static debug_inline 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
void GameLoopPause()
Pause the game-loop for a bit, releasing the game-state lock.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Base class that provides memory initialization on dynamically created objects.
Definition: alloc_type.hpp:86
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.
Definition: fileio_type.h:115
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition: fileio_type.h:124
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 To ClampTo(From value)
Clamp the given value down to lie within the requested type.
Definition: math_func.hpp:167
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:9694
Base for the NewGRF implementation.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
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.
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.
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
GRFConfig ** CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only)
Copy a GRF Config list.
void AppendStaticGRFConfigs(GRFConfig **dst)
Appends the static GRFs to a list of GRFs.
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.
Definition: newgrf_config.h:51
@ GLC_COMPATIBLE
Compatible (eg. the same ID, but different checksum) GRF found in at least one case.
Definition: newgrf_config.h:53
@ GLC_ALL_GOOD
All GRF needed by game are present.
Definition: newgrf_config.h:52
@ GLC_NOT_FOUND
At least one GRF couldn't be found (higher priority than GLC_COMPATIBLE)
Definition: newgrf_config.h:54
@ GRFP_USE_DOS
The palette state is set to use the DOS palette.
Definition: newgrf_config.h:65
@ GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
Definition: newgrf_config.h:71
@ GRFP_USE_WINDOWS
The palette state is set to use the Windows palette.
Definition: newgrf_config.h:66
@ GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
Definition: newgrf_config.h:70
@ GRFP_USE_BIT
The bit used for storing the palette to use.
Definition: newgrf_config.h:59
@ GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
Definition: newgrf_config.h:73
void UpdateNewGRFScanStatus(uint num, const char *name)
Update the NewGRF scan status.
@ GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
Definition: newgrf_config.h:27
@ GCF_INVALID
GRF is unusable with this version of OpenTTD.
Definition: newgrf_config.h:29
@ GCF_UNSAFE
GRF file is unsafe for static usage.
Definition: newgrf_config.h:23
@ GCF_COMPATIBLE
GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
Definition: newgrf_config.h:25
@ GCF_COPY
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:26
@ GCF_SYSTEM
GRF file is an openttd-internal system grf.
Definition: newgrf_config.h:22
@ PTYPE_UINT_ENUM
The parameter allows a range of numbers, each of which can have a special name.
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition: newgrf_config.h:36
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.
Definition: strings_type.h:16
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.
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)
uint8_t num_params
Number of used parameters.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
GRFStatus status
NOSAVE: GRFStatus, enum.
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.
std::array< uint32_t, 0x80 > param
GRF parameters.
GRFError(StringID severity, StringID message=0)
Construct a new GRFError.
uint32_t grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:83
MD5Hash md5sum
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Definition: newgrf_config.h:84
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.
uint8_t num_bit
Number of bits to use for this parameter.
uint32_t max_value
The maximal value of this parameter.
uint32_t GetValue(struct GRFConfig *config) const
Get the value of this user-changeable parameter from the given config.
void Finalize()
Finalize Action 14 info after file scan is finished.
GRFParameterInfo(uint nr)
Create a new empty GRFParameterInfo object.
void SetValue(struct GRFConfig *config, uint32_t value)
Set the value of this user-changeable parameter in the given config.
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.
std::optional< std::string > GetTextfile(TextfileType type, Subdirectory dir, const std::string &filename)
Search a textfile file next to the given content.
GUI functions related to textfiles.
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:14
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:3211
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3093
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:3228
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:
Definition: window_type.h:624
@ WC_SAVELOAD
Saveload window; Window numbers:
Definition: window_type.h:144
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers:
Definition: window_type.h:469
@ GOID_NEWGRF_RESCANNED
NewGRFs were just rescanned.
Definition: window_type.h:730