OpenTTD
newgrf.cpp
Go to the documentation of this file.
1 /* $Id: newgrf.cpp 27989 2018-03-11 15:08:51Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 
14 #include <stdarg.h>
15 #include <algorithm>
16 
17 #include "debug.h"
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
21 #include "bridge.h"
22 #include "town.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
26 #include "currency.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
39 #include "rev.h"
40 #include "fios.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
45 #include <map>
46 #include "smallmap_gui.h"
47 #include "genworld.h"
48 #include "error.h"
49 #include "vehicle_func.h"
50 #include "language.h"
51 #include "vehicle_base.h"
52 
53 #include "table/strings.h"
54 #include "table/build_industry.h"
55 
56 #include "safeguards.h"
57 
58 /* TTDPatch extended GRF format codec
59  * (c) Petr Baudis 2004 (GPL'd)
60  * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61  *
62  * Contains portions of documentation by TTDPatch team.
63  * Thanks especially to Josef Drexler for the documentation as well as a lot
64  * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
65  * served as subject to the initial testing of this codec. */
66 
69 
72 
74 static uint32 _ttdpatch_flags[8];
75 
78 
79 static const uint MAX_SPRITEGROUP = UINT8_MAX;
80 
83 private:
85  struct SpriteSet {
87  uint num_sprites;
88  };
89 
91  std::map<uint, SpriteSet> spritesets[GSF_END];
92 
93 public:
94  /* Global state */
95  GrfLoadingStage stage;
97 
98  /* Local state in the file */
99  uint file_index;
102  uint32 nfo_line;
104 
105  /* Kind of return values when processing certain actions */
107 
108  /* Currently referenceable spritegroups */
109  SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
110 
113  {
114  this->nfo_line = 0;
115  this->skip_sprites = 0;
116 
117  for (uint i = 0; i < GSF_END; i++) {
118  this->spritesets[i].clear();
119  }
120 
121  memset(this->spritegroups, 0, sizeof(this->spritegroups));
122  }
123 
132  void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
133  {
134  assert(feature < GSF_END);
135  for (uint i = 0; i < numsets; i++) {
136  SpriteSet &set = this->spritesets[feature][first_set + i];
137  set.sprite = first_sprite + i * numents;
138  set.num_sprites = numents;
139  }
140  }
141 
148  bool HasValidSpriteSets(byte feature) const
149  {
150  assert(feature < GSF_END);
151  return !this->spritesets[feature].empty();
152  }
153 
161  bool IsValidSpriteSet(byte feature, uint set) const
162  {
163  assert(feature < GSF_END);
164  return this->spritesets[feature].find(set) != this->spritesets[feature].end();
165  }
166 
173  SpriteID GetSprite(byte feature, uint set) const
174  {
175  assert(IsValidSpriteSet(feature, set));
176  return this->spritesets[feature].find(set)->second.sprite;
177  }
178 
185  uint GetNumEnts(byte feature, uint set) const
186  {
187  assert(IsValidSpriteSet(feature, set));
188  return this->spritesets[feature].find(set)->second.num_sprites;
189  }
190 };
191 
192 static GrfProcessingState _cur;
193 
194 
201 template <VehicleType T>
202 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
203 {
204  return image_index == 0xFD || IsValidImageIndex<T>(image_index);
205 }
206 
208 
210 class ByteReader {
211 protected:
212  byte *data;
213  byte *end;
214 
215 public:
216  ByteReader(byte *data, byte *end) : data(data), end(end) { }
217 
218  inline byte ReadByte()
219  {
220  if (data < end) return *(data)++;
221  throw OTTDByteReaderSignal();
222  }
223 
224  uint16 ReadWord()
225  {
226  uint16 val = ReadByte();
227  return val | (ReadByte() << 8);
228  }
229 
230  uint16 ReadExtendedByte()
231  {
232  uint16 val = ReadByte();
233  return val == 0xFF ? ReadWord() : val;
234  }
235 
236  uint32 ReadDWord()
237  {
238  uint32 val = ReadWord();
239  return val | (ReadWord() << 16);
240  }
241 
242  uint32 ReadVarSize(byte size)
243  {
244  switch (size) {
245  case 1: return ReadByte();
246  case 2: return ReadWord();
247  case 4: return ReadDWord();
248  default:
249  NOT_REACHED();
250  return 0;
251  }
252  }
253 
254  const char *ReadString()
255  {
256  char *string = reinterpret_cast<char *>(data);
257  size_t string_length = ttd_strnlen(string, Remaining());
258 
259  if (string_length == Remaining()) {
260  /* String was not NUL terminated, so make sure it is now. */
261  string[string_length - 1] = '\0';
262  grfmsg(7, "String was not terminated with a zero byte.");
263  } else {
264  /* Increase the string length to include the NUL byte. */
265  string_length++;
266  }
267  Skip(string_length);
268 
269  return string;
270  }
271 
272  inline size_t Remaining() const
273  {
274  return end - data;
275  }
276 
277  inline bool HasData(size_t count = 1) const
278  {
279  return data + count <= end;
280  }
281 
282  inline byte *Data()
283  {
284  return data;
285  }
286 
287  inline void Skip(size_t len)
288  {
289  data += len;
290  /* It is valid to move the buffer to exactly the end of the data,
291  * as there may not be any more data read. */
292  if (data > end) throw OTTDByteReaderSignal();
293  }
294 };
295 
296 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
297 
298 static const uint NUM_STATIONS_PER_GRF = 255;
299 
304  UNSET = 0,
307  };
308 
309  uint16 cargo_allowed;
310  uint16 cargo_disallowed;
311  RailTypeLabel railtypelabel;
314  bool prop27_set;
315  uint8 rv_max_speed;
318 
323  void UpdateRefittability(bool non_empty)
324  {
325  if (non_empty) {
326  this->refittability = NONEMPTY;
327  } else if (this->refittability == UNSET) {
328  this->refittability = EMPTY;
329  }
330  }
331 };
332 
334 
339 static uint32 _grm_engines[256];
340 
342 static uint32 _grm_cargoes[NUM_CARGO * 2];
343 
344 struct GRFLocation {
345  uint32 grfid;
346  uint32 nfoline;
347 
348  GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
349 
350  bool operator<(const GRFLocation &other) const
351  {
352  return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
353  }
354 
355  bool operator == (const GRFLocation &other) const
356  {
357  return this->grfid == other.grfid && this->nfoline == other.nfoline;
358  }
359 };
360 
361 static std::map<GRFLocation, SpriteID> _grm_sprites;
362 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
364 
375 void CDECL grfmsg(int severity, const char *str, ...)
376 {
377  char buf[1024];
378  va_list va;
379 
380  va_start(va, str);
381  vseprintf(buf, lastof(buf), str, va);
382  va_end(va);
383 
384  DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
385 }
386 
392 static GRFFile *GetFileByGRFID(uint32 grfid)
393 {
394  const GRFFile * const *end = _grf_files.End();
395  for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
396  if ((*file)->grfid == grfid) return *file;
397  }
398  return NULL;
399 }
400 
406 static GRFFile *GetFileByFilename(const char *filename)
407 {
408  const GRFFile * const *end = _grf_files.End();
409  for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
410  if (strcmp((*file)->filename, filename) == 0) return *file;
411  }
412  return NULL;
413 }
414 
417 {
418  /* Clear the GOTO labels used for GRF processing */
419  for (GRFLabel *l = gf->label; l != NULL;) {
420  GRFLabel *l2 = l->next;
421  free(l);
422  l = l2;
423  }
424  gf->label = NULL;
425 }
426 
433 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
434 {
435  GRFFile *file;
436  if (config != NULL) {
437  file = GetFileByGRFID(config->ident.grfid);
438  } else {
439  config = _cur.grfconfig;
440  file = _cur.grffile;
441  }
442 
443  config->status = GCS_DISABLED;
444  if (file != NULL) ClearTemporaryNewGRFData(file);
445  if (config == _cur.grfconfig) _cur.skip_sprites = -1;
446 
447  if (message != STR_NULL) {
448  delete config->error;
449  config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
450  if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
451  }
452 
453  return config->error;
454 }
455 
460  uint32 grfid;
463 };
465 static StringIDMappingVector _string_to_grf_mapping;
466 
472 static void AddStringForMapping(StringID source, StringID *target)
473 {
474  *target = STR_UNDEFINED;
475  StringIDMapping *item = _string_to_grf_mapping.Append();
476  item->grfid = _cur.grffile->grfid;
477  item->source = source;
478  item->target = target;
479 }
480 
489 {
490  /* StringID table for TextIDs 0x4E->0x6D */
491  static const StringID units_volume[] = {
492  STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
493  STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
494  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
496  STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
497  STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
498  STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
499  STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
500  };
501 
502  /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503  assert(!IsInsideMM(str, 0xD000, 0xD7FF));
504 
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506  assert_compile(stringend - stringid == end - begin); \
507  if (str >= begin && str <= end) return str + (stringid - begin)
508 
509  /* We have some changes in our cargo strings, resulting in some missing. */
510  TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
511  TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
512  if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
513  TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
514  TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
515  TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
516 
517  /* Map building names according to our lang file changes. There are several
518  * ranges of house ids, all of which need to be remapped to allow newgrfs
519  * to use original house names. */
520  TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
521  TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
522  TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
523 
524  /* Same thing for industries */
525  TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
526  TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
527  TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
528  TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
529  TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
530 
531  switch (str) {
532  case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
533  case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
534  case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535  }
536 #undef TEXTID_TO_STRINGID
537 
538  if (str == STR_NULL) return STR_EMPTY;
539 
540  DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
541 
542  return STR_EMPTY;
543 }
544 
552 StringID MapGRFStringID(uint32 grfid, StringID str)
553 {
554  if (IsInsideMM(str, 0xD800, 0xE000)) {
555  /* General text provided by NewGRF.
556  * In the specs this is called the 0xDCxx range (misc presistent texts),
557  * but we meanwhile extended the range to 0xD800-0xDFFF.
558  * Note: We are not involved in the "persistent" business, since we do not store
559  * any NewGRF strings in savegames. */
560  return GetGRFStringID(grfid, str);
561  } else if (IsInsideMM(str, 0xD000, 0xD800)) {
562  /* Callback text provided by NewGRF.
563  * In the specs this is called the 0xD0xx range (misc graphics texts).
564  * These texts can be returned by various callbacks.
565  *
566  * Due to how TTDP implements the GRF-local- to global-textid translation
567  * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568  * We do not care about that difference and just mask out the 0x400 bit.
569  */
570  str &= ~0x400;
571  return GetGRFStringID(grfid, str);
572  } else {
573  /* The NewGRF wants to include/reference an original TTD string.
574  * Try our best to find an equivalent one. */
576  }
577 }
578 
579 static std::map<uint32, uint32> _grf_id_overrides;
580 
586 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
587 {
588  _grf_id_overrides[source_grfid] = target_grfid;
589  grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
590 }
591 
600 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
601 {
602  /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603  * them use the same engine slots. */
604  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
606  /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607  scope_grfid = file->grfid;
608  uint32 override = _grf_id_overrides[file->grfid];
609  if (override != 0) {
610  scope_grfid = override;
611  const GRFFile *grf_match = GetFileByGRFID(override);
612  if (grf_match == NULL) {
613  grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
614  } else {
615  grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
616  }
617  }
618 
619  /* Check if the engine is registered in the override manager */
620  EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
621  if (engine != INVALID_ENGINE) {
622  Engine *e = Engine::Get(engine);
623  if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
624  return e;
625  }
626  }
627 
628  /* Check if there is an unreserved slot */
629  EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
630  if (engine != INVALID_ENGINE) {
631  Engine *e = Engine::Get(engine);
632 
633  if (e->grf_prop.grffile == NULL) {
634  e->grf_prop.grffile = file;
635  grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
636  }
637 
638  /* Reserve the engine slot */
639  if (!static_access) {
640  EngineIDMapping *eid = _engine_mngr.Get(engine);
641  eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
642  }
643 
644  return e;
645  }
646 
647  if (static_access) return NULL;
648 
649  if (!Engine::CanAllocateItem()) {
650  grfmsg(0, "Can't allocate any more engines");
651  return NULL;
652  }
653 
654  size_t engine_pool_size = Engine::GetPoolSize();
655 
656  /* ... it's not, so create a new one based off an existing engine */
657  Engine *e = new Engine(type, internal_id);
658  e->grf_prop.grffile = file;
659 
660  /* Reserve the engine slot */
661  assert(_engine_mngr.Length() == e->index);
662  EngineIDMapping *eid = _engine_mngr.Append();
663  eid->type = type;
664  eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
665  eid->internal_id = internal_id;
666  eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
667 
668  if (engine_pool_size != Engine::GetPoolSize()) {
669  /* Resize temporary engine data ... */
670  _gted = ReallocT(_gted, Engine::GetPoolSize());
671 
672  /* and blank the new block. */
673  size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
674  memset(_gted + engine_pool_size, 0, len);
675  }
676  if (type == VEH_TRAIN) {
677  _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
678  }
679 
680  grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
681 
682  return e;
683 }
684 
695 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
696 {
697  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
699  scope_grfid = file->grfid;
700  uint32 override = _grf_id_overrides[file->grfid];
701  if (override != 0) scope_grfid = override;
702  }
703 
704  return _engine_mngr.GetID(type, internal_id, scope_grfid);
705 }
706 
711 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
712 {
713  if (HasBit(grf_sprite->pal, 14)) {
714  ClrBit(grf_sprite->pal, 14);
715  SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
716  }
717 
718  if (HasBit(grf_sprite->sprite, 14)) {
719  ClrBit(grf_sprite->sprite, 14);
721  }
722 
723  if (HasBit(grf_sprite->sprite, 15)) {
724  ClrBit(grf_sprite->sprite, 15);
725  SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
726  }
727 }
728 
742 static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
743 {
744  grf_sprite->sprite = buf->ReadWord();
745  grf_sprite->pal = buf->ReadWord();
746  TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
747 
748  MapSpriteMappingRecolour(grf_sprite);
749 
750  bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
751  ClrBit(grf_sprite->pal, 15);
752  if (custom_sprite) {
753  /* Use sprite from Action 1 */
754  uint index = GB(grf_sprite->sprite, 0, 14);
755  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
756  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757  grf_sprite->sprite = SPR_IMG_QUERY;
758  grf_sprite->pal = PAL_NONE;
759  } else {
760  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
761  if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
762  SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
764  }
765  } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
766  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
768  return flags;
769  }
770 
771  if (flags & TLF_CUSTOM_PALETTE) {
772  /* Use palette from Action 1 */
773  uint index = GB(grf_sprite->pal, 0, 14);
774  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
775  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776  grf_sprite->pal = PAL_NONE;
777  } else {
778  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
779  if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
780  SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
782  }
783  } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
784  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
786  return flags;
787  }
788 
789  return flags;
790 }
791 
800 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
801 {
802  if (!(flags & TLF_DRAWING_FLAGS)) return;
803 
804  if (dts->registers == NULL) dts->AllocateRegisters();
805  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
806  regs.flags = flags & TLF_DRAWING_FLAGS;
807 
808  if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
809  if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
810  if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
811 
812  if (is_parent) {
813  if (flags & TLF_BB_XY_OFFSET) {
814  regs.delta.parent[0] = buf->ReadByte();
815  regs.delta.parent[1] = buf->ReadByte();
816  }
817  if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
818  } else {
819  if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
820  if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
821  }
822 
823  if (flags & TLF_SPRITE_VAR10) {
824  regs.sprite_var10 = buf->ReadByte();
825  if (regs.sprite_var10 > TLR_MAX_VAR10) {
826  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
827  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
828  return;
829  }
830  }
831 
832  if (flags & TLF_PALETTE_VAR10) {
833  regs.palette_var10 = buf->ReadByte();
834  if (regs.palette_var10 > TLR_MAX_VAR10) {
835  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
836  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
837  return;
838  }
839  }
840 }
841 
853 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
854 {
855  bool has_flags = HasBit(num_building_sprites, 6);
856  ClrBit(num_building_sprites, 6);
857  TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
858  if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
859  dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
860 
861  uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
862  uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
863  MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864  MemSetT(max_palette_offset, 0, num_building_sprites + 1);
865 
866  /* Groundsprite */
867  TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
868  if (_cur.skip_sprites < 0) return true;
869 
870  if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
871  grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
872  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
873  return true;
874  }
875 
876  ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
877  if (_cur.skip_sprites < 0) return true;
878 
879  for (uint i = 0; i < num_building_sprites; i++) {
880  DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
881 
882  flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
883  if (_cur.skip_sprites < 0) return true;
884 
885  if (flags & ~valid_flags) {
886  grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
888  return true;
889  }
890 
891  seq->delta_x = buf->ReadByte();
892  seq->delta_y = buf->ReadByte();
893 
894  if (!no_z_position) seq->delta_z = buf->ReadByte();
895 
896  if (seq->IsParentSprite()) {
897  seq->size_x = buf->ReadByte();
898  seq->size_y = buf->ReadByte();
899  seq->size_z = buf->ReadByte();
900  }
901 
902  ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
903  if (_cur.skip_sprites < 0) return true;
904  }
905 
906  /* Check if the number of sprites per spriteset is consistent */
907  bool is_consistent = true;
908  dts->consistent_max_offset = 0;
909  for (uint i = 0; i < num_building_sprites + 1; i++) {
910  if (max_sprite_offset[i] > 0) {
911  if (dts->consistent_max_offset == 0) {
912  dts->consistent_max_offset = max_sprite_offset[i];
913  } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
914  is_consistent = false;
915  break;
916  }
917  }
918  if (max_palette_offset[i] > 0) {
919  if (dts->consistent_max_offset == 0) {
920  dts->consistent_max_offset = max_palette_offset[i];
921  } else if (dts->consistent_max_offset != max_palette_offset[i]) {
922  is_consistent = false;
923  break;
924  }
925  }
926  }
927 
928  /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929  assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
930 
931  if (!is_consistent || dts->registers != NULL) {
932  dts->consistent_max_offset = 0;
933  if (dts->registers == NULL) dts->AllocateRegisters();
934 
935  for (uint i = 0; i < num_building_sprites + 1; i++) {
936  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
937  regs.max_sprite_offset = max_sprite_offset[i];
938  regs.max_palette_offset = max_palette_offset[i];
939  }
940  }
941 
942  return false;
943 }
944 
948 static uint32 TranslateRefitMask(uint32 refit_mask)
949 {
950  uint32 result = 0;
951  uint8 bit;
952  FOR_EACH_SET_BIT(bit, refit_mask) {
953  CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
954  if (cargo != CT_INVALID) SetBit(result, cargo);
955  }
956  return result;
957 }
958 
966 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
967 {
968  /* Special value for 'none' */
969  if (base_pointer == 0) {
970  *index = INVALID_PRICE;
971  return;
972  }
973 
974  static const uint32 start = 0x4B34;
975  static const uint32 size = 6;
976 
977  if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978  grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
979  return;
980  }
981 
982  *index = (Price)((base_pointer - start) / size);
983 }
984 
992 };
993 
994 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
995 
1004 {
1005  switch (prop) {
1006  case 0x00: // Introduction date
1007  ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1008  break;
1009 
1010  case 0x02: // Decay speed
1011  ei->decay_speed = buf->ReadByte();
1012  break;
1013 
1014  case 0x03: // Vehicle life
1015  ei->lifelength = buf->ReadByte();
1016  break;
1017 
1018  case 0x04: // Model life
1019  ei->base_life = buf->ReadByte();
1020  break;
1021 
1022  case 0x06: // Climates available
1023  ei->climates = buf->ReadByte();
1024  break;
1025 
1026  case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1027  /* Amount of cargo loaded during a vehicle's "loading tick" */
1028  ei->load_amount = buf->ReadByte();
1029  break;
1030 
1031  default:
1032  return CIR_UNKNOWN;
1033  }
1034 
1035  return CIR_SUCCESS;
1036 }
1037 
1046 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1047 {
1049 
1050  for (int i = 0; i < numinfo; i++) {
1051  Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1052  if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1053 
1054  EngineInfo *ei = &e->info;
1055  RailVehicleInfo *rvi = &e->u.rail;
1056 
1057  switch (prop) {
1058  case 0x05: { // Track type
1059  uint8 tracktype = buf->ReadByte();
1060 
1061  if (tracktype < _cur.grffile->railtype_list.Length()) {
1062  _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1063  break;
1064  }
1065 
1066  switch (tracktype) {
1067  case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1068  case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1069  case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1070  default:
1071  grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1072  break;
1073  }
1074  break;
1075  }
1076 
1077  case 0x08: // AI passenger service
1078  /* Tells the AI that this engine is designed for
1079  * passenger services and shouldn't be used for freight. */
1080  rvi->ai_passenger_only = buf->ReadByte();
1081  break;
1082 
1083  case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084  uint16 speed = buf->ReadWord();
1085  if (speed == 0xFFFF) speed = 0;
1086 
1087  rvi->max_speed = speed;
1088  break;
1089  }
1090 
1091  case PROP_TRAIN_POWER: // 0x0B Power
1092  rvi->power = buf->ReadWord();
1093 
1094  /* Set engine / wagon state based on power */
1095  if (rvi->power != 0) {
1096  if (rvi->railveh_type == RAILVEH_WAGON) {
1097  rvi->railveh_type = RAILVEH_SINGLEHEAD;
1098  }
1099  } else {
1100  rvi->railveh_type = RAILVEH_WAGON;
1101  }
1102  break;
1103 
1104  case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1105  rvi->running_cost = buf->ReadByte();
1106  break;
1107 
1108  case 0x0E: // Running cost base
1109  ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1110  break;
1111 
1112  case 0x12: { // Sprite ID
1113  uint8 spriteid = buf->ReadByte();
1114  uint8 orig_spriteid = spriteid;
1115 
1116  /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117  * as an array index, so we need it to be half the original value. */
1118  if (spriteid < 0xFD) spriteid >>= 1;
1119 
1120  if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121  rvi->image_index = spriteid;
1122  } else {
1123  grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124  rvi->image_index = 0;
1125  }
1126  break;
1127  }
1128 
1129  case 0x13: { // Dual-headed
1130  uint8 dual = buf->ReadByte();
1131 
1132  if (dual != 0) {
1133  rvi->railveh_type = RAILVEH_MULTIHEAD;
1134  } else {
1135  rvi->railveh_type = rvi->power == 0 ?
1137  }
1138  break;
1139  }
1140 
1141  case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1142  rvi->capacity = buf->ReadByte();
1143  break;
1144 
1145  case 0x15: { // Cargo type
1146  _gted[e->index].defaultcargo_grf = _cur.grffile;
1147  uint8 ctype = buf->ReadByte();
1148 
1149  if (ctype == 0xFF) {
1150  /* 0xFF is specified as 'use first refittable' */
1151  ei->cargo_type = CT_INVALID;
1152  } else if (_cur.grffile->grf_version >= 8) {
1153  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1155  } else if (ctype < NUM_CARGO) {
1156  /* Use untranslated cargo. */
1157  ei->cargo_type = ctype;
1158  } else {
1159  ei->cargo_type = CT_INVALID;
1160  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1161  }
1162  break;
1163  }
1164 
1165  case PROP_TRAIN_WEIGHT: // 0x16 Weight
1166  SB(rvi->weight, 0, 8, buf->ReadByte());
1167  break;
1168 
1169  case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1170  rvi->cost_factor = buf->ReadByte();
1171  break;
1172 
1173  case 0x18: // AI rank
1174  grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1175  buf->ReadByte();
1176  break;
1177 
1178  case 0x19: { // Engine traction type
1179  /* What do the individual numbers mean?
1180  * 0x00 .. 0x07: Steam
1181  * 0x08 .. 0x27: Diesel
1182  * 0x28 .. 0x31: Electric
1183  * 0x32 .. 0x37: Monorail
1184  * 0x38 .. 0x41: Maglev
1185  */
1186  uint8 traction = buf->ReadByte();
1187  EngineClass engclass;
1188 
1189  if (traction <= 0x07) {
1190  engclass = EC_STEAM;
1191  } else if (traction <= 0x27) {
1192  engclass = EC_DIESEL;
1193  } else if (traction <= 0x31) {
1194  engclass = EC_ELECTRIC;
1195  } else if (traction <= 0x37) {
1196  engclass = EC_MONORAIL;
1197  } else if (traction <= 0x41) {
1198  engclass = EC_MAGLEV;
1199  } else {
1200  break;
1201  }
1202 
1203  if (_cur.grffile->railtype_list.Length() == 0) {
1204  /* Use traction type to select between normal and electrified
1205  * rail only when no translation list is in place. */
1206  if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1207  if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1208  }
1209 
1210  rvi->engclass = engclass;
1211  break;
1212  }
1213 
1214  case 0x1A: // Alter purchase list sort order
1215  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1216  break;
1217 
1218  case 0x1B: // Powered wagons power bonus
1219  rvi->pow_wag_power = buf->ReadWord();
1220  break;
1221 
1222  case 0x1C: // Refit cost
1223  ei->refit_cost = buf->ReadByte();
1224  break;
1225 
1226  case 0x1D: { // Refit cargo
1227  uint32 mask = buf->ReadDWord();
1228  _gted[e->index].UpdateRefittability(mask != 0);
1229  ei->refit_mask = TranslateRefitMask(mask);
1230  _gted[e->index].defaultcargo_grf = _cur.grffile;
1231  break;
1232  }
1233 
1234  case 0x1E: // Callback
1235  ei->callback_mask = buf->ReadByte();
1236  break;
1237 
1238  case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1239  rvi->tractive_effort = buf->ReadByte();
1240  break;
1241 
1242  case 0x20: // Air drag
1243  rvi->air_drag = buf->ReadByte();
1244  break;
1245 
1246  case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1247  rvi->shorten_factor = buf->ReadByte();
1248  break;
1249 
1250  case 0x22: // Visual effect
1251  rvi->visual_effect = buf->ReadByte();
1252  /* Avoid accidentally setting visual_effect to the default value
1253  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254  if (rvi->visual_effect == VE_DEFAULT) {
1255  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1257  }
1258  break;
1259 
1260  case 0x23: // Powered wagons weight bonus
1261  rvi->pow_wag_weight = buf->ReadByte();
1262  break;
1263 
1264  case 0x24: { // High byte of vehicle weight
1265  byte weight = buf->ReadByte();
1266 
1267  if (weight > 4) {
1268  grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1269  } else {
1270  SB(rvi->weight, 8, 8, weight);
1271  }
1272  break;
1273  }
1274 
1275  case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276  rvi->user_def_data = buf->ReadByte();
1277  break;
1278 
1279  case 0x26: // Retire vehicle early
1280  ei->retire_early = buf->ReadByte();
1281  break;
1282 
1283  case 0x27: // Miscellaneous flags
1284  ei->misc_flags = buf->ReadByte();
1285  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1286  _gted[e->index].prop27_set = true;
1287  break;
1288 
1289  case 0x28: // Cargo classes allowed
1290  _gted[e->index].cargo_allowed = buf->ReadWord();
1291  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1292  _gted[e->index].defaultcargo_grf = _cur.grffile;
1293  break;
1294 
1295  case 0x29: // Cargo classes disallowed
1296  _gted[e->index].cargo_disallowed = buf->ReadWord();
1297  _gted[e->index].UpdateRefittability(false);
1298  break;
1299 
1300  case 0x2A: // Long format introduction date (days since year 0)
1301  ei->base_intro = buf->ReadDWord();
1302  break;
1303 
1304  case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1305  ei->cargo_age_period = buf->ReadWord();
1306  break;
1307 
1308  case 0x2C: // CTT refit include list
1309  case 0x2D: { // CTT refit exclude list
1310  uint8 count = buf->ReadByte();
1311  _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1312  if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1313  uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1314  ctt = 0;
1315  while (count--) {
1316  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1317  if (ctype == CT_INVALID) continue;
1318  SetBit(ctt, ctype);
1319  }
1320  break;
1321  }
1322 
1323  default:
1324  ret = CommonVehicleChangeInfo(ei, prop, buf);
1325  break;
1326  }
1327  }
1328 
1329  return ret;
1330 }
1331 
1340 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1341 {
1343 
1344  for (int i = 0; i < numinfo; i++) {
1345  Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1346  if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1347 
1348  EngineInfo *ei = &e->info;
1349  RoadVehicleInfo *rvi = &e->u.road;
1350 
1351  switch (prop) {
1352  case 0x08: // Speed (1 unit is 0.5 kmh)
1353  rvi->max_speed = buf->ReadByte();
1354  break;
1355 
1356  case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1357  rvi->running_cost = buf->ReadByte();
1358  break;
1359 
1360  case 0x0A: // Running cost base
1361  ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1362  break;
1363 
1364  case 0x0E: { // Sprite ID
1365  uint8 spriteid = buf->ReadByte();
1366  uint8 orig_spriteid = spriteid;
1367 
1368  /* cars have different custom id in the GRF file */
1369  if (spriteid == 0xFF) spriteid = 0xFD;
1370 
1371  if (spriteid < 0xFD) spriteid >>= 1;
1372 
1373  if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1374  rvi->image_index = spriteid;
1375  } else {
1376  grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1377  rvi->image_index = 0;
1378  }
1379  break;
1380  }
1381 
1382  case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1383  rvi->capacity = buf->ReadByte();
1384  break;
1385 
1386  case 0x10: { // Cargo type
1387  _gted[e->index].defaultcargo_grf = _cur.grffile;
1388  uint8 ctype = buf->ReadByte();
1389 
1390  if (ctype == 0xFF) {
1391  /* 0xFF is specified as 'use first refittable' */
1392  ei->cargo_type = CT_INVALID;
1393  } else if (_cur.grffile->grf_version >= 8) {
1394  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1395  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1396  } else if (ctype < NUM_CARGO) {
1397  /* Use untranslated cargo. */
1398  ei->cargo_type = ctype;
1399  } else {
1400  ei->cargo_type = CT_INVALID;
1401  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1402  }
1403  break;
1404  }
1405 
1406  case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1407  rvi->cost_factor = buf->ReadByte();
1408  break;
1409 
1410  case 0x12: // SFX
1411  rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1412  break;
1413 
1414  case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1415  rvi->power = buf->ReadByte();
1416  break;
1417 
1418  case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1419  rvi->weight = buf->ReadByte();
1420  break;
1421 
1422  case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1423  _gted[e->index].rv_max_speed = buf->ReadByte();
1424  break;
1425 
1426  case 0x16: { // Cargoes available for refitting
1427  uint32 mask = buf->ReadDWord();
1428  _gted[e->index].UpdateRefittability(mask != 0);
1429  ei->refit_mask = TranslateRefitMask(mask);
1430  _gted[e->index].defaultcargo_grf = _cur.grffile;
1431  break;
1432  }
1433 
1434  case 0x17: // Callback mask
1435  ei->callback_mask = buf->ReadByte();
1436  break;
1437 
1438  case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1439  rvi->tractive_effort = buf->ReadByte();
1440  break;
1441 
1442  case 0x19: // Air drag
1443  rvi->air_drag = buf->ReadByte();
1444  break;
1445 
1446  case 0x1A: // Refit cost
1447  ei->refit_cost = buf->ReadByte();
1448  break;
1449 
1450  case 0x1B: // Retire vehicle early
1451  ei->retire_early = buf->ReadByte();
1452  break;
1453 
1454  case 0x1C: // Miscellaneous flags
1455  ei->misc_flags = buf->ReadByte();
1456  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1457  break;
1458 
1459  case 0x1D: // Cargo classes allowed
1460  _gted[e->index].cargo_allowed = buf->ReadWord();
1461  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1462  _gted[e->index].defaultcargo_grf = _cur.grffile;
1463  break;
1464 
1465  case 0x1E: // Cargo classes disallowed
1466  _gted[e->index].cargo_disallowed = buf->ReadWord();
1467  _gted[e->index].UpdateRefittability(false);
1468  break;
1469 
1470  case 0x1F: // Long format introduction date (days since year 0)
1471  ei->base_intro = buf->ReadDWord();
1472  break;
1473 
1474  case 0x20: // Alter purchase list sort order
1475  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1476  break;
1477 
1478  case 0x21: // Visual effect
1479  rvi->visual_effect = buf->ReadByte();
1480  /* Avoid accidentally setting visual_effect to the default value
1481  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1482  if (rvi->visual_effect == VE_DEFAULT) {
1483  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1485  }
1486  break;
1487 
1488  case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1489  ei->cargo_age_period = buf->ReadWord();
1490  break;
1491 
1492  case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1493  rvi->shorten_factor = buf->ReadByte();
1494  break;
1495 
1496  case 0x24: // CTT refit include list
1497  case 0x25: { // CTT refit exclude list
1498  uint8 count = buf->ReadByte();
1499  _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1500  if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1501  uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1502  ctt = 0;
1503  while (count--) {
1504  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1505  if (ctype == CT_INVALID) continue;
1506  SetBit(ctt, ctype);
1507  }
1508  break;
1509  }
1510 
1511  default:
1512  ret = CommonVehicleChangeInfo(ei, prop, buf);
1513  break;
1514  }
1515  }
1516 
1517  return ret;
1518 }
1519 
1528 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1529 {
1531 
1532  for (int i = 0; i < numinfo; i++) {
1533  Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1534  if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1535 
1536  EngineInfo *ei = &e->info;
1537  ShipVehicleInfo *svi = &e->u.ship;
1538 
1539  switch (prop) {
1540  case 0x08: { // Sprite ID
1541  uint8 spriteid = buf->ReadByte();
1542  uint8 orig_spriteid = spriteid;
1543 
1544  /* ships have different custom id in the GRF file */
1545  if (spriteid == 0xFF) spriteid = 0xFD;
1546 
1547  if (spriteid < 0xFD) spriteid >>= 1;
1548 
1549  if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1550  svi->image_index = spriteid;
1551  } else {
1552  grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1553  svi->image_index = 0;
1554  }
1555  break;
1556  }
1557 
1558  case 0x09: // Refittable
1559  svi->old_refittable = (buf->ReadByte() != 0);
1560  break;
1561 
1562  case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1563  svi->cost_factor = buf->ReadByte();
1564  break;
1565 
1566  case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1567  svi->max_speed = buf->ReadByte();
1568  break;
1569 
1570  case 0x0C: { // Cargo type
1571  _gted[e->index].defaultcargo_grf = _cur.grffile;
1572  uint8 ctype = buf->ReadByte();
1573 
1574  if (ctype == 0xFF) {
1575  /* 0xFF is specified as 'use first refittable' */
1576  ei->cargo_type = CT_INVALID;
1577  } else if (_cur.grffile->grf_version >= 8) {
1578  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1579  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1580  } else if (ctype < NUM_CARGO) {
1581  /* Use untranslated cargo. */
1582  ei->cargo_type = ctype;
1583  } else {
1584  ei->cargo_type = CT_INVALID;
1585  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1586  }
1587  break;
1588  }
1589 
1590  case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1591  svi->capacity = buf->ReadWord();
1592  break;
1593 
1594  case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1595  svi->running_cost = buf->ReadByte();
1596  break;
1597 
1598  case 0x10: // SFX
1599  svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1600  break;
1601 
1602  case 0x11: { // Cargoes available for refitting
1603  uint32 mask = buf->ReadDWord();
1604  _gted[e->index].UpdateRefittability(mask != 0);
1605  ei->refit_mask = TranslateRefitMask(mask);
1606  _gted[e->index].defaultcargo_grf = _cur.grffile;
1607  break;
1608  }
1609 
1610  case 0x12: // Callback mask
1611  ei->callback_mask = buf->ReadByte();
1612  break;
1613 
1614  case 0x13: // Refit cost
1615  ei->refit_cost = buf->ReadByte();
1616  break;
1617 
1618  case 0x14: // Ocean speed fraction
1619  svi->ocean_speed_frac = buf->ReadByte();
1620  break;
1621 
1622  case 0x15: // Canal speed fraction
1623  svi->canal_speed_frac = buf->ReadByte();
1624  break;
1625 
1626  case 0x16: // Retire vehicle early
1627  ei->retire_early = buf->ReadByte();
1628  break;
1629 
1630  case 0x17: // Miscellaneous flags
1631  ei->misc_flags = buf->ReadByte();
1632  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1633  break;
1634 
1635  case 0x18: // Cargo classes allowed
1636  _gted[e->index].cargo_allowed = buf->ReadWord();
1637  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1638  _gted[e->index].defaultcargo_grf = _cur.grffile;
1639  break;
1640 
1641  case 0x19: // Cargo classes disallowed
1642  _gted[e->index].cargo_disallowed = buf->ReadWord();
1643  _gted[e->index].UpdateRefittability(false);
1644  break;
1645 
1646  case 0x1A: // Long format introduction date (days since year 0)
1647  ei->base_intro = buf->ReadDWord();
1648  break;
1649 
1650  case 0x1B: // Alter purchase list sort order
1651  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1652  break;
1653 
1654  case 0x1C: // Visual effect
1655  svi->visual_effect = buf->ReadByte();
1656  /* Avoid accidentally setting visual_effect to the default value
1657  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1658  if (svi->visual_effect == VE_DEFAULT) {
1659  assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1661  }
1662  break;
1663 
1664  case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1665  ei->cargo_age_period = buf->ReadWord();
1666  break;
1667 
1668  case 0x1E: // CTT refit include list
1669  case 0x1F: { // CTT refit exclude list
1670  uint8 count = buf->ReadByte();
1671  _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1672  if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1673  uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1674  ctt = 0;
1675  while (count--) {
1676  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1677  if (ctype == CT_INVALID) continue;
1678  SetBit(ctt, ctype);
1679  }
1680  break;
1681  }
1682 
1683  default:
1684  ret = CommonVehicleChangeInfo(ei, prop, buf);
1685  break;
1686  }
1687  }
1688 
1689  return ret;
1690 }
1691 
1700 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1701 {
1703 
1704  for (int i = 0; i < numinfo; i++) {
1705  Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1706  if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1707 
1708  EngineInfo *ei = &e->info;
1709  AircraftVehicleInfo *avi = &e->u.air;
1710 
1711  switch (prop) {
1712  case 0x08: { // Sprite ID
1713  uint8 spriteid = buf->ReadByte();
1714  uint8 orig_spriteid = spriteid;
1715 
1716  /* aircraft have different custom id in the GRF file */
1717  if (spriteid == 0xFF) spriteid = 0xFD;
1718 
1719  if (spriteid < 0xFD) spriteid >>= 1;
1720 
1721  if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1722  avi->image_index = spriteid;
1723  } else {
1724  grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1725  avi->image_index = 0;
1726  }
1727  break;
1728  }
1729 
1730  case 0x09: // Helicopter
1731  if (buf->ReadByte() == 0) {
1732  avi->subtype = AIR_HELI;
1733  } else {
1734  SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1735  }
1736  break;
1737 
1738  case 0x0A: // Large
1739  SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1740  break;
1741 
1742  case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1743  avi->cost_factor = buf->ReadByte();
1744  break;
1745 
1746  case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1747  avi->max_speed = (buf->ReadByte() * 128) / 10;
1748  break;
1749 
1750  case 0x0D: // Acceleration
1751  avi->acceleration = buf->ReadByte();
1752  break;
1753 
1754  case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1755  avi->running_cost = buf->ReadByte();
1756  break;
1757 
1758  case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1759  avi->passenger_capacity = buf->ReadWord();
1760  break;
1761 
1762  case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1763  avi->mail_capacity = buf->ReadByte();
1764  break;
1765 
1766  case 0x12: // SFX
1767  avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1768  break;
1769 
1770  case 0x13: { // Cargoes available for refitting
1771  uint32 mask = buf->ReadDWord();
1772  _gted[e->index].UpdateRefittability(mask != 0);
1773  ei->refit_mask = TranslateRefitMask(mask);
1774  _gted[e->index].defaultcargo_grf = _cur.grffile;
1775  break;
1776  }
1777 
1778  case 0x14: // Callback mask
1779  ei->callback_mask = buf->ReadByte();
1780  break;
1781 
1782  case 0x15: // Refit cost
1783  ei->refit_cost = buf->ReadByte();
1784  break;
1785 
1786  case 0x16: // Retire vehicle early
1787  ei->retire_early = buf->ReadByte();
1788  break;
1789 
1790  case 0x17: // Miscellaneous flags
1791  ei->misc_flags = buf->ReadByte();
1792  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1793  break;
1794 
1795  case 0x18: // Cargo classes allowed
1796  _gted[e->index].cargo_allowed = buf->ReadWord();
1797  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1798  _gted[e->index].defaultcargo_grf = _cur.grffile;
1799  break;
1800 
1801  case 0x19: // Cargo classes disallowed
1802  _gted[e->index].cargo_disallowed = buf->ReadWord();
1803  _gted[e->index].UpdateRefittability(false);
1804  break;
1805 
1806  case 0x1A: // Long format introduction date (days since year 0)
1807  ei->base_intro = buf->ReadDWord();
1808  break;
1809 
1810  case 0x1B: // Alter purchase list sort order
1811  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1812  break;
1813 
1814  case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1815  ei->cargo_age_period = buf->ReadWord();
1816  break;
1817 
1818  case 0x1D: // CTT refit include list
1819  case 0x1E: { // CTT refit exclude list
1820  uint8 count = buf->ReadByte();
1821  _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1822  if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1823  uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1824  ctt = 0;
1825  while (count--) {
1826  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1827  if (ctype == CT_INVALID) continue;
1828  SetBit(ctt, ctype);
1829  }
1830  break;
1831  }
1832 
1833  case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1834  avi->max_range = buf->ReadWord();
1835  break;
1836 
1837  default:
1838  ret = CommonVehicleChangeInfo(ei, prop, buf);
1839  break;
1840  }
1841  }
1842 
1843  return ret;
1844 }
1845 
1854 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1855 {
1857 
1858  if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1859  grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1860  return CIR_INVALID_ID;
1861  }
1862 
1863  /* Allocate station specs if necessary */
1864  if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1865 
1866  for (int i = 0; i < numinfo; i++) {
1867  StationSpec *statspec = _cur.grffile->stations[stid + i];
1868 
1869  /* Check that the station we are modifying is defined. */
1870  if (statspec == NULL && prop != 0x08) {
1871  grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1872  return CIR_INVALID_ID;
1873  }
1874 
1875  switch (prop) {
1876  case 0x08: { // Class ID
1877  StationSpec **spec = &_cur.grffile->stations[stid + i];
1878 
1879  /* Property 0x08 is special; it is where the station is allocated */
1880  if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1881 
1882  /* Swap classid because we read it in BE meaning WAYP or DFLT */
1883  uint32 classid = buf->ReadDWord();
1884  (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1885  break;
1886  }
1887 
1888  case 0x09: // Define sprite layout
1889  statspec->tiles = buf->ReadExtendedByte();
1890  delete[] statspec->renderdata; // delete earlier loaded stuff
1891  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1892 
1893  for (uint t = 0; t < statspec->tiles; t++) {
1894  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1895  dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1896 
1897  if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1898  buf->Skip(4);
1899  extern const DrawTileSprites _station_display_datas_rail[8];
1900  dts->Clone(&_station_display_datas_rail[t % 8]);
1901  continue;
1902  }
1903 
1904  ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1905  /* On error, bail out immediately. Temporary GRF data was already freed */
1906  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1907 
1908  static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1909  tmp_layout.Clear();
1910  for (;;) {
1911  /* no relative bounding box support */
1912  DrawTileSeqStruct *dtss = tmp_layout.Append();
1913  MemSetT(dtss, 0);
1914 
1915  dtss->delta_x = buf->ReadByte();
1916  if (dtss->IsTerminator()) break;
1917  dtss->delta_y = buf->ReadByte();
1918  dtss->delta_z = buf->ReadByte();
1919  dtss->size_x = buf->ReadByte();
1920  dtss->size_y = buf->ReadByte();
1921  dtss->size_z = buf->ReadByte();
1922 
1923  ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1924  /* On error, bail out immediately. Temporary GRF data was already freed */
1925  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1926  }
1927  dts->Clone(tmp_layout.Begin());
1928  }
1929  break;
1930 
1931  case 0x0A: { // Copy sprite layout
1932  byte srcid = buf->ReadByte();
1933  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1934 
1935  if (srcstatspec == NULL) {
1936  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1937  continue;
1938  }
1939 
1940  delete[] statspec->renderdata; // delete earlier loaded stuff
1941 
1942  statspec->tiles = srcstatspec->tiles;
1943  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1944  for (uint t = 0; t < statspec->tiles; t++) {
1945  statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1946  }
1947  break;
1948  }
1949 
1950  case 0x0B: // Callback mask
1951  statspec->callback_mask = buf->ReadByte();
1952  break;
1953 
1954  case 0x0C: // Disallowed number of platforms
1955  statspec->disallowed_platforms = buf->ReadByte();
1956  break;
1957 
1958  case 0x0D: // Disallowed platform lengths
1959  statspec->disallowed_lengths = buf->ReadByte();
1960  break;
1961 
1962  case 0x0E: // Define custom layout
1963  statspec->copied_layouts = false;
1964 
1965  while (buf->HasData()) {
1966  byte length = buf->ReadByte();
1967  byte number = buf->ReadByte();
1968  StationLayout layout;
1969  uint l, p;
1970 
1971  if (length == 0 || number == 0) break;
1972 
1973  if (length > statspec->lengths) {
1974  statspec->platforms = ReallocT(statspec->platforms, length);
1975  memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1976 
1977  statspec->layouts = ReallocT(statspec->layouts, length);
1978  memset(statspec->layouts + statspec->lengths, 0,
1979  (length - statspec->lengths) * sizeof(*statspec->layouts));
1980 
1981  statspec->lengths = length;
1982  }
1983  l = length - 1; // index is zero-based
1984 
1985  if (number > statspec->platforms[l]) {
1986  statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1987  /* We expect NULL being 0 here, but C99 guarantees that. */
1988  memset(statspec->layouts[l] + statspec->platforms[l], 0,
1989  (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1990 
1991  statspec->platforms[l] = number;
1992  }
1993 
1994  p = 0;
1995  layout = MallocT<byte>(length * number);
1996  try {
1997  for (l = 0; l < length; l++) {
1998  for (p = 0; p < number; p++) {
1999  layout[l * number + p] = buf->ReadByte();
2000  }
2001  }
2002  } catch (...) {
2003  free(layout);
2004  throw;
2005  }
2006 
2007  l--;
2008  p--;
2009  free(statspec->layouts[l][p]);
2010  statspec->layouts[l][p] = layout;
2011  }
2012  break;
2013 
2014  case 0x0F: { // Copy custom layout
2015  byte srcid = buf->ReadByte();
2016  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2017 
2018  if (srcstatspec == NULL) {
2019  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2020  continue;
2021  }
2022 
2023  statspec->lengths = srcstatspec->lengths;
2024  statspec->platforms = srcstatspec->platforms;
2025  statspec->layouts = srcstatspec->layouts;
2026  statspec->copied_layouts = true;
2027  break;
2028  }
2029 
2030  case 0x10: // Little/lots cargo threshold
2031  statspec->cargo_threshold = buf->ReadWord();
2032  break;
2033 
2034  case 0x11: // Pylon placement
2035  statspec->pylons = buf->ReadByte();
2036  break;
2037 
2038  case 0x12: // Cargo types for random triggers
2039  statspec->cargo_triggers = buf->ReadDWord();
2040  if (_cur.grffile->grf_version >= 7) {
2041  statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2042  }
2043  break;
2044 
2045  case 0x13: // General flags
2046  statspec->flags = buf->ReadByte();
2047  break;
2048 
2049  case 0x14: // Overhead wire placement
2050  statspec->wires = buf->ReadByte();
2051  break;
2052 
2053  case 0x15: // Blocked tiles
2054  statspec->blocked = buf->ReadByte();
2055  break;
2056 
2057  case 0x16: // Animation info
2058  statspec->animation.frames = buf->ReadByte();
2059  statspec->animation.status = buf->ReadByte();
2060  break;
2061 
2062  case 0x17: // Animation speed
2063  statspec->animation.speed = buf->ReadByte();
2064  break;
2065 
2066  case 0x18: // Animation triggers
2067  statspec->animation.triggers = buf->ReadWord();
2068  break;
2069 
2070  case 0x1A: // Advanced sprite layout
2071  statspec->tiles = buf->ReadExtendedByte();
2072  delete[] statspec->renderdata; // delete earlier loaded stuff
2073  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2074 
2075  for (uint t = 0; t < statspec->tiles; t++) {
2076  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2077  uint num_building_sprites = buf->ReadByte();
2078  /* On error, bail out immediately. Temporary GRF data was already freed */
2079  if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2080  }
2081  break;
2082 
2083  default:
2084  ret = CIR_UNKNOWN;
2085  break;
2086  }
2087  }
2088 
2089  return ret;
2090 }
2091 
2100 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2101 {
2103 
2104  if (id + numinfo > CF_END) {
2105  grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2106  return CIR_INVALID_ID;
2107  }
2108 
2109  for (int i = 0; i < numinfo; i++) {
2110  CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2111 
2112  switch (prop) {
2113  case 0x08:
2114  cp->callback_mask = buf->ReadByte();
2115  break;
2116 
2117  case 0x09:
2118  cp->flags = buf->ReadByte();
2119  break;
2120 
2121  default:
2122  ret = CIR_UNKNOWN;
2123  break;
2124  }
2125  }
2126 
2127  return ret;
2128 }
2129 
2138 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2139 {
2141 
2142  if (brid + numinfo > MAX_BRIDGES) {
2143  grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2144  return CIR_INVALID_ID;
2145  }
2146 
2147  for (int i = 0; i < numinfo; i++) {
2148  BridgeSpec *bridge = &_bridge[brid + i];
2149 
2150  switch (prop) {
2151  case 0x08: { // Year of availability
2152  /* We treat '0' as always available */
2153  byte year = buf->ReadByte();
2154  bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2155  break;
2156  }
2157 
2158  case 0x09: // Minimum length
2159  bridge->min_length = buf->ReadByte();
2160  break;
2161 
2162  case 0x0A: // Maximum length
2163  bridge->max_length = buf->ReadByte();
2164  if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2165  break;
2166 
2167  case 0x0B: // Cost factor
2168  bridge->price = buf->ReadByte();
2169  break;
2170 
2171  case 0x0C: // Maximum speed
2172  bridge->speed = buf->ReadWord();
2173  break;
2174 
2175  case 0x0D: { // Bridge sprite tables
2176  byte tableid = buf->ReadByte();
2177  byte numtables = buf->ReadByte();
2178 
2179  if (bridge->sprite_table == NULL) {
2180  /* Allocate memory for sprite table pointers and zero out */
2181  bridge->sprite_table = CallocT<PalSpriteID*>(7);
2182  }
2183 
2184  for (; numtables-- != 0; tableid++) {
2185  if (tableid >= 7) { // skip invalid data
2186  grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2187  for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2188  continue;
2189  }
2190 
2191  if (bridge->sprite_table[tableid] == NULL) {
2192  bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2193  }
2194 
2195  for (byte sprite = 0; sprite < 32; sprite++) {
2196  SpriteID image = buf->ReadWord();
2197  PaletteID pal = buf->ReadWord();
2198 
2199  bridge->sprite_table[tableid][sprite].sprite = image;
2200  bridge->sprite_table[tableid][sprite].pal = pal;
2201 
2202  MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2203  }
2204  }
2205  break;
2206  }
2207 
2208  case 0x0E: // Flags; bit 0 - disable far pillars
2209  bridge->flags = buf->ReadByte();
2210  break;
2211 
2212  case 0x0F: // Long format year of availability (year since year 0)
2213  bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2214  break;
2215 
2216  case 0x10: { // purchase string
2217  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2218  if (newone != STR_UNDEFINED) bridge->material = newone;
2219  break;
2220  }
2221 
2222  case 0x11: // description of bridge with rails or roads
2223  case 0x12: {
2224  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2225  if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2226  break;
2227  }
2228 
2229  case 0x13: // 16 bits cost multiplier
2230  bridge->price = buf->ReadWord();
2231  break;
2232 
2233  default:
2234  ret = CIR_UNKNOWN;
2235  break;
2236  }
2237  }
2238 
2239  return ret;
2240 }
2241 
2249 {
2251 
2252  switch (prop) {
2253  case 0x09:
2254  case 0x0B:
2255  case 0x0C:
2256  case 0x0D:
2257  case 0x0E:
2258  case 0x0F:
2259  case 0x11:
2260  case 0x14:
2261  case 0x15:
2262  case 0x16:
2263  case 0x18:
2264  case 0x19:
2265  case 0x1A:
2266  case 0x1B:
2267  case 0x1C:
2268  case 0x1D:
2269  case 0x1F:
2270  buf->ReadByte();
2271  break;
2272 
2273  case 0x0A:
2274  case 0x10:
2275  case 0x12:
2276  case 0x13:
2277  case 0x21:
2278  case 0x22:
2279  buf->ReadWord();
2280  break;
2281 
2282  case 0x1E:
2283  buf->ReadDWord();
2284  break;
2285 
2286  case 0x17:
2287  for (uint j = 0; j < 4; j++) buf->ReadByte();
2288  break;
2289 
2290  case 0x20: {
2291  byte count = buf->ReadByte();
2292  for (byte j = 0; j < count; j++) buf->ReadByte();
2293  break;
2294  }
2295 
2296  default:
2297  ret = CIR_UNKNOWN;
2298  break;
2299  }
2300  return ret;
2301 }
2302 
2311 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2312 {
2314 
2315  if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2316  grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2317  return CIR_INVALID_ID;
2318  }
2319 
2320  /* Allocate house specs if they haven't been allocated already. */
2321  if (_cur.grffile->housespec == NULL) {
2322  _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2323  }
2324 
2325  for (int i = 0; i < numinfo; i++) {
2326  HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2327 
2328  if (prop != 0x08 && housespec == NULL) {
2329  /* If the house property 08 is not yet set, ignore this property */
2330  ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2331  if (cir > ret) ret = cir;
2332  continue;
2333  }
2334 
2335  switch (prop) {
2336  case 0x08: { // Substitute building type, and definition of a new house
2337  HouseSpec **house = &_cur.grffile->housespec[hid + i];
2338  byte subs_id = buf->ReadByte();
2339 
2340  if (subs_id == 0xFF) {
2341  /* Instead of defining a new house, a substitute house id
2342  * of 0xFF disables the old house with the current id. */
2343  HouseSpec::Get(hid + i)->enabled = false;
2344  continue;
2345  } else if (subs_id >= NEW_HOUSE_OFFSET) {
2346  /* The substitute id must be one of the original houses. */
2347  grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2348  continue;
2349  }
2350 
2351  /* Allocate space for this house. */
2352  if (*house == NULL) *house = CallocT<HouseSpec>(1);
2353 
2354  housespec = *house;
2355 
2356  MemCpyT(housespec, HouseSpec::Get(subs_id));
2357 
2358  housespec->enabled = true;
2359  housespec->grf_prop.local_id = hid + i;
2360  housespec->grf_prop.subst_id = subs_id;
2361  housespec->grf_prop.grffile = _cur.grffile;
2362  housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2363  housespec->random_colour[1] = 0x08; // for all new houses
2364  housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2365  housespec->random_colour[3] = 0x06;
2366 
2367  /* Make sure that the third cargo type is valid in this
2368  * climate. This can cause problems when copying the properties
2369  * of a house that accepts food, where the new house is valid
2370  * in the temperate climate. */
2371  if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2372  housespec->cargo_acceptance[2] = 0;
2373  }
2374 
2375  _loaded_newgrf_features.has_newhouses = true;
2376  break;
2377  }
2378 
2379  case 0x09: // Building flags
2380  housespec->building_flags = (BuildingFlags)buf->ReadByte();
2381  break;
2382 
2383  case 0x0A: { // Availability years
2384  uint16 years = buf->ReadWord();
2385  housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2386  housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2387  break;
2388  }
2389 
2390  case 0x0B: // Population
2391  housespec->population = buf->ReadByte();
2392  break;
2393 
2394  case 0x0C: // Mail generation multiplier
2395  housespec->mail_generation = buf->ReadByte();
2396  break;
2397 
2398  case 0x0D: // Passenger acceptance
2399  case 0x0E: // Mail acceptance
2400  housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2401  break;
2402 
2403  case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2404  int8 goods = buf->ReadByte();
2405 
2406  /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2407  * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2408  CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2409  ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2410 
2411  /* Make sure the cargo type is valid in this climate. */
2412  if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2413 
2414  housespec->accepts_cargo[2] = cid;
2415  housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2416  break;
2417  }
2418 
2419  case 0x10: // Local authority rating decrease on removal
2420  housespec->remove_rating_decrease = buf->ReadWord();
2421  break;
2422 
2423  case 0x11: // Removal cost multiplier
2424  housespec->removal_cost = buf->ReadByte();
2425  break;
2426 
2427  case 0x12: // Building name ID
2428  AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2429  break;
2430 
2431  case 0x13: // Building availability mask
2432  housespec->building_availability = (HouseZones)buf->ReadWord();
2433  break;
2434 
2435  case 0x14: // House callback mask
2436  housespec->callback_mask |= buf->ReadByte();
2437  break;
2438 
2439  case 0x15: { // House override byte
2440  byte override = buf->ReadByte();
2441 
2442  /* The house being overridden must be an original house. */
2443  if (override >= NEW_HOUSE_OFFSET) {
2444  grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2445  continue;
2446  }
2447 
2448  _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2449  break;
2450  }
2451 
2452  case 0x16: // Periodic refresh multiplier
2453  housespec->processing_time = min(buf->ReadByte(), 63);
2454  break;
2455 
2456  case 0x17: // Four random colours to use
2457  for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2458  break;
2459 
2460  case 0x18: // Relative probability of appearing
2461  housespec->probability = buf->ReadByte();
2462  break;
2463 
2464  case 0x19: // Extra flags
2465  housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2466  break;
2467 
2468  case 0x1A: // Animation frames
2469  housespec->animation.frames = buf->ReadByte();
2470  housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2471  SB(housespec->animation.frames, 7, 1, 0);
2472  break;
2473 
2474  case 0x1B: // Animation speed
2475  housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2476  break;
2477 
2478  case 0x1C: // Class of the building type
2479  housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2480  break;
2481 
2482  case 0x1D: // Callback mask part 2
2483  housespec->callback_mask |= (buf->ReadByte() << 8);
2484  break;
2485 
2486  case 0x1E: { // Accepted cargo types
2487  uint32 cargotypes = buf->ReadDWord();
2488 
2489  /* Check if the cargo types should not be changed */
2490  if (cargotypes == 0xFFFFFFFF) break;
2491 
2492  for (uint j = 0; j < 3; j++) {
2493  /* Get the cargo number from the 'list' */
2494  uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2495  CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2496 
2497  if (cargo == CT_INVALID) {
2498  /* Disable acceptance of invalid cargo type */
2499  housespec->cargo_acceptance[j] = 0;
2500  } else {
2501  housespec->accepts_cargo[j] = cargo;
2502  }
2503  }
2504  break;
2505  }
2506 
2507  case 0x1F: // Minimum life span
2508  housespec->minimum_life = buf->ReadByte();
2509  break;
2510 
2511  case 0x20: { // Cargo acceptance watch list
2512  byte count = buf->ReadByte();
2513  for (byte j = 0; j < count; j++) {
2514  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2515  if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2516  }
2517  break;
2518  }
2519 
2520  case 0x21: // long introduction year
2521  housespec->min_year = buf->ReadWord();
2522  break;
2523 
2524  case 0x22: // long maximum year
2525  housespec->max_year = buf->ReadWord();
2526  break;
2527 
2528  default:
2529  ret = CIR_UNKNOWN;
2530  break;
2531  }
2532  }
2533 
2534  return ret;
2535 }
2536 
2543 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2544 {
2545  /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2546  const GRFFile *grffile = GetFileByGRFID(grfid);
2547  return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2548 }
2549 
2559 template <typename T>
2560 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2561 {
2562  if (gvid != 0) {
2563  grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2564  return CIR_INVALID_ID;
2565  }
2566 
2567  translation_table.Clear();
2568  for (int i = 0; i < numinfo; i++) {
2569  uint32 item = buf->ReadDWord();
2570  *translation_table.Append() = BSWAP32(item);
2571  }
2572 
2573  return CIR_SUCCESS;
2574 }
2575 
2584 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2585 {
2586  /* Properties which are handled as a whole */
2587  switch (prop) {
2588  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2589  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2590 
2591  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2592  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2593 
2594  default:
2595  break;
2596  }
2597 
2598  /* Properties which are handled per item */
2600  for (int i = 0; i < numinfo; i++) {
2601  switch (prop) {
2602  case 0x08: { // Cost base factor
2603  int factor = buf->ReadByte();
2604  uint price = gvid + i;
2605 
2606  if (price < PR_END) {
2607  _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2608  } else {
2609  grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2610  }
2611  break;
2612  }
2613 
2614  case 0x0A: { // Currency display names
2615  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2616  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2617 
2618  if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2619  _currency_specs[curidx].name = newone;
2620  }
2621  break;
2622  }
2623 
2624  case 0x0B: { // Currency multipliers
2625  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2626  uint32 rate = buf->ReadDWord();
2627 
2628  if (curidx < CURRENCY_END) {
2629  /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2630  * which OTTD does not. For this reason, divide grf value by 1000,
2631  * to be compatible */
2632  _currency_specs[curidx].rate = rate / 1000;
2633  } else {
2634  grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2635  }
2636  break;
2637  }
2638 
2639  case 0x0C: { // Currency options
2640  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2641  uint16 options = buf->ReadWord();
2642 
2643  if (curidx < CURRENCY_END) {
2644  _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2645  _currency_specs[curidx].separator[1] = '\0';
2646  /* By specifying only one bit, we prevent errors,
2647  * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2648  _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2649  } else {
2650  grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2651  }
2652  break;
2653  }
2654 
2655  case 0x0D: { // Currency prefix symbol
2656  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2657  uint32 tempfix = buf->ReadDWord();
2658 
2659  if (curidx < CURRENCY_END) {
2660  memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2661  _currency_specs[curidx].prefix[4] = 0;
2662  } else {
2663  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2664  }
2665  break;
2666  }
2667 
2668  case 0x0E: { // Currency suffix symbol
2669  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2670  uint32 tempfix = buf->ReadDWord();
2671 
2672  if (curidx < CURRENCY_END) {
2673  memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2674  _currency_specs[curidx].suffix[4] = 0;
2675  } else {
2676  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2677  }
2678  break;
2679  }
2680 
2681  case 0x0F: { // Euro introduction dates
2682  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2683  Year year_euro = buf->ReadWord();
2684 
2685  if (curidx < CURRENCY_END) {
2686  _currency_specs[curidx].to_euro = year_euro;
2687  } else {
2688  grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2689  }
2690  break;
2691  }
2692 
2693  case 0x10: // Snow line height table
2694  if (numinfo > 1 || IsSnowLineSet()) {
2695  grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2696  } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2697  grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2698  } else {
2699  byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2700 
2701  for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2702  for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2703  table[i][j] = buf->ReadByte();
2704  if (_cur.grffile->grf_version >= 8) {
2705  if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2706  } else {
2707  if (table[i][j] >= 128) {
2708  /* no snow */
2709  table[i][j] = 0xFF;
2710  } else {
2711  table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2712  }
2713  }
2714  }
2715  }
2716  SetSnowLine(table);
2717  }
2718  break;
2719 
2720  case 0x11: // GRF match for engine allocation
2721  /* This is loaded during the reservation stage, so just skip it here. */
2722  /* Each entry is 8 bytes. */
2723  buf->Skip(8);
2724  break;
2725 
2726  case 0x13: // Gender translation table
2727  case 0x14: // Case translation table
2728  case 0x15: { // Plural form translation
2729  uint curidx = gvid + i; // The current index, i.e. language.
2730  const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2731  if (lang == NULL) {
2732  grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2733  /* Skip over the data. */
2734  if (prop == 0x15) {
2735  buf->ReadByte();
2736  } else {
2737  while (buf->ReadByte() != 0) {
2738  buf->ReadString();
2739  }
2740  }
2741  break;
2742  }
2743 
2744  if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2745 
2746  if (prop == 0x15) {
2747  uint plural_form = buf->ReadByte();
2748  if (plural_form >= LANGUAGE_MAX_PLURAL) {
2749  grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2750  } else {
2751  _cur.grffile->language_map[curidx].plural_form = plural_form;
2752  }
2753  break;
2754  }
2755 
2756  byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2757  while (newgrf_id != 0) {
2758  const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2759 
2760  /* We'll just ignore the UTF8 identifier character. This is (fairly)
2761  * safe as OpenTTD's strings gender/cases are usually in ASCII which
2762  * is just a subset of UTF8, or they need the bigger UTF8 characters
2763  * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2764  WChar c;
2765  size_t len = Utf8Decode(&c, name);
2766  if (c == NFO_UTF8_IDENTIFIER) name += len;
2767 
2769  map.newgrf_id = newgrf_id;
2770  if (prop == 0x13) {
2771  map.openttd_id = lang->GetGenderIndex(name);
2772  if (map.openttd_id >= MAX_NUM_GENDERS) {
2773  grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2774  } else {
2775  *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2776  }
2777  } else {
2778  map.openttd_id = lang->GetCaseIndex(name);
2779  if (map.openttd_id >= MAX_NUM_CASES) {
2780  grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2781  } else {
2782  *_cur.grffile->language_map[curidx].case_map.Append() = map;
2783  }
2784  }
2785  newgrf_id = buf->ReadByte();
2786  }
2787  break;
2788  }
2789 
2790  default:
2791  ret = CIR_UNKNOWN;
2792  break;
2793  }
2794  }
2795 
2796  return ret;
2797 }
2798 
2799 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2800 {
2801  /* Properties which are handled as a whole */
2802  switch (prop) {
2803  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2804  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2805 
2806  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2807  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2808 
2809  default:
2810  break;
2811  }
2812 
2813  /* Properties which are handled per item */
2815  for (int i = 0; i < numinfo; i++) {
2816  switch (prop) {
2817  case 0x08: // Cost base factor
2818  case 0x15: // Plural form translation
2819  buf->ReadByte();
2820  break;
2821 
2822  case 0x0A: // Currency display names
2823  case 0x0C: // Currency options
2824  case 0x0F: // Euro introduction dates
2825  buf->ReadWord();
2826  break;
2827 
2828  case 0x0B: // Currency multipliers
2829  case 0x0D: // Currency prefix symbol
2830  case 0x0E: // Currency suffix symbol
2831  buf->ReadDWord();
2832  break;
2833 
2834  case 0x10: // Snow line height table
2835  buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2836  break;
2837 
2838  case 0x11: { // GRF match for engine allocation
2839  uint32 s = buf->ReadDWord();
2840  uint32 t = buf->ReadDWord();
2841  SetNewGRFOverride(s, t);
2842  break;
2843  }
2844 
2845  case 0x13: // Gender translation table
2846  case 0x14: // Case translation table
2847  while (buf->ReadByte() != 0) {
2848  buf->ReadString();
2849  }
2850  break;
2851 
2852  default:
2853  ret = CIR_UNKNOWN;
2854  break;
2855  }
2856  }
2857 
2858  return ret;
2859 }
2860 
2861 
2870 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2871 {
2873 
2874  if (cid + numinfo > NUM_CARGO) {
2875  grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2876  return CIR_INVALID_ID;
2877  }
2878 
2879  for (int i = 0; i < numinfo; i++) {
2880  CargoSpec *cs = CargoSpec::Get(cid + i);
2881 
2882  switch (prop) {
2883  case 0x08: // Bit number of cargo
2884  cs->bitnum = buf->ReadByte();
2885  if (cs->IsValid()) {
2886  cs->grffile = _cur.grffile;
2887  SetBit(_cargo_mask, cid + i);
2888  } else {
2889  ClrBit(_cargo_mask, cid + i);
2890  }
2891  break;
2892 
2893  case 0x09: // String ID for cargo type name
2894  AddStringForMapping(buf->ReadWord(), &cs->name);
2895  break;
2896 
2897  case 0x0A: // String for 1 unit of cargo
2898  AddStringForMapping(buf->ReadWord(), &cs->name_single);
2899  break;
2900 
2901  case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2902  case 0x1B: // String for cargo units
2903  /* String for units of cargo. This is different in OpenTTD
2904  * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2905  * Property 1B is used to set OpenTTD's behaviour. */
2906  AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2907  break;
2908 
2909  case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2910  case 0x1C: // String for any amount of cargo
2911  /* Strings for an amount of cargo. This is different in OpenTTD
2912  * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2913  * Property 1C is used to set OpenTTD's behaviour. */
2914  AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2915  break;
2916 
2917  case 0x0D: // String for two letter cargo abbreviation
2918  AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2919  break;
2920 
2921  case 0x0E: // Sprite ID for cargo icon
2922  cs->sprite = buf->ReadWord();
2923  break;
2924 
2925  case 0x0F: // Weight of one unit of cargo
2926  cs->weight = buf->ReadByte();
2927  break;
2928 
2929  case 0x10: // Used for payment calculation
2930  cs->transit_days[0] = buf->ReadByte();
2931  break;
2932 
2933  case 0x11: // Used for payment calculation
2934  cs->transit_days[1] = buf->ReadByte();
2935  break;
2936 
2937  case 0x12: // Base cargo price
2938  cs->initial_payment = buf->ReadDWord();
2939  break;
2940 
2941  case 0x13: // Colour for station rating bars
2942  cs->rating_colour = buf->ReadByte();
2943  break;
2944 
2945  case 0x14: // Colour for cargo graph
2946  cs->legend_colour = buf->ReadByte();
2947  break;
2948 
2949  case 0x15: // Freight status
2950  cs->is_freight = (buf->ReadByte() != 0);
2951  break;
2952 
2953  case 0x16: // Cargo classes
2954  cs->classes = buf->ReadWord();
2955  break;
2956 
2957  case 0x17: // Cargo label
2958  cs->label = buf->ReadDWord();
2959  cs->label = BSWAP32(cs->label);
2960  break;
2961 
2962  case 0x18: { // Town growth substitute type
2963  uint8 substitute_type = buf->ReadByte();
2964 
2965  switch (substitute_type) {
2966  case 0x00: cs->town_effect = TE_PASSENGERS; break;
2967  case 0x02: cs->town_effect = TE_MAIL; break;
2968  case 0x05: cs->town_effect = TE_GOODS; break;
2969  case 0x09: cs->town_effect = TE_WATER; break;
2970  case 0x0B: cs->town_effect = TE_FOOD; break;
2971  default:
2972  grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2973  FALLTHROUGH;
2974  case 0xFF: cs->town_effect = TE_NONE; break;
2975  }
2976  break;
2977  }
2978 
2979  case 0x19: // Town growth coefficient
2980  cs->multipliertowngrowth = buf->ReadWord();
2981  break;
2982 
2983  case 0x1A: // Bitmask of callbacks to use
2984  cs->callback_mask = buf->ReadByte();
2985  break;
2986 
2987  case 0x1D: // Vehicle capacity muliplier
2988  cs->multiplier = max<uint16>(1u, buf->ReadWord());
2989  break;
2990 
2991  default:
2992  ret = CIR_UNKNOWN;
2993  break;
2994  }
2995  }
2996 
2997  return ret;
2998 }
2999 
3000 
3009 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3010 {
3012 
3013  if (_cur.grffile->sound_offset == 0) {
3014  grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3015  return CIR_INVALID_ID;
3016  }
3017 
3018  if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3019  grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3020  return CIR_INVALID_ID;
3021  }
3022 
3023  for (int i = 0; i < numinfo; i++) {
3024  SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3025 
3026  switch (prop) {
3027  case 0x08: // Relative volume
3028  sound->volume = buf->ReadByte();
3029  break;
3030 
3031  case 0x09: // Priority
3032  sound->priority = buf->ReadByte();
3033  break;
3034 
3035  case 0x0A: { // Override old sound
3036  SoundID orig_sound = buf->ReadByte();
3037 
3038  if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3039  grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3040  } else {
3041  SoundEntry *old_sound = GetSound(orig_sound);
3042 
3043  /* Literally copy the data of the new sound over the original */
3044  *old_sound = *sound;
3045  }
3046  break;
3047  }
3048 
3049  default:
3050  ret = CIR_UNKNOWN;
3051  break;
3052  }
3053  }
3054 
3055  return ret;
3056 }
3057 
3065 {
3067 
3068  switch (prop) {
3069  case 0x09:
3070  case 0x0D:
3071  case 0x0E:
3072  case 0x10:
3073  case 0x11:
3074  case 0x12:
3075  buf->ReadByte();
3076  break;
3077 
3078  case 0x0A:
3079  case 0x0B:
3080  case 0x0C:
3081  case 0x0F:
3082  buf->ReadWord();
3083  break;
3084 
3085  default:
3086  ret = CIR_UNKNOWN;
3087  break;
3088  }
3089  return ret;
3090 }
3091 
3100 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3101 {
3103 
3104  if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3105  grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3106  return CIR_INVALID_ID;
3107  }
3108 
3109  /* Allocate industry tile specs if they haven't been allocated already. */
3110  if (_cur.grffile->indtspec == NULL) {
3111  _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3112  }
3113 
3114  for (int i = 0; i < numinfo; i++) {
3115  IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3116 
3117  if (prop != 0x08 && tsp == NULL) {
3119  if (cir > ret) ret = cir;
3120  continue;
3121  }
3122 
3123  switch (prop) {
3124  case 0x08: { // Substitute industry tile type
3125  IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3126  byte subs_id = buf->ReadByte();
3127 
3128  if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3129  /* The substitute id must be one of the original industry tile. */
3130  grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3131  continue;
3132  }
3133 
3134  /* Allocate space for this industry. */
3135  if (*tilespec == NULL) {
3136  *tilespec = CallocT<IndustryTileSpec>(1);
3137  tsp = *tilespec;
3138 
3139  memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3140  tsp->enabled = true;
3141 
3142  /* A copied tile should not have the animation infos copied too.
3143  * The anim_state should be left untouched, though
3144  * It is up to the author to animate them himself */
3145  tsp->anim_production = INDUSTRYTILE_NOANIM;
3146  tsp->anim_next = INDUSTRYTILE_NOANIM;
3147 
3148  tsp->grf_prop.local_id = indtid + i;
3149  tsp->grf_prop.subst_id = subs_id;
3150  tsp->grf_prop.grffile = _cur.grffile;
3151  _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3152  }
3153  break;
3154  }
3155 
3156  case 0x09: { // Industry tile override
3157  byte ovrid = buf->ReadByte();
3158 
3159  /* The industry being overridden must be an original industry. */
3160  if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3161  grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3162  continue;
3163  }
3164 
3165  _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3166  break;
3167  }
3168 
3169  case 0x0A: // Tile acceptance
3170  case 0x0B:
3171  case 0x0C: {
3172  uint16 acctp = buf->ReadWord();
3173  tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3174  tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3175  break;
3176  }
3177 
3178  case 0x0D: // Land shape flags
3179  tsp->slopes_refused = (Slope)buf->ReadByte();
3180  break;
3181 
3182  case 0x0E: // Callback mask
3183  tsp->callback_mask = buf->ReadByte();
3184  break;
3185 
3186  case 0x0F: // Animation information
3187  tsp->animation.frames = buf->ReadByte();
3188  tsp->animation.status = buf->ReadByte();
3189  break;
3190 
3191  case 0x10: // Animation speed
3192  tsp->animation.speed = buf->ReadByte();
3193  break;
3194 
3195  case 0x11: // Triggers for callback 25
3196  tsp->animation.triggers = buf->ReadByte();
3197  break;
3198 
3199  case 0x12: // Special flags
3200  tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3201  break;
3202 
3203  default:
3204  ret = CIR_UNKNOWN;
3205  break;
3206  }
3207  }
3208 
3209  return ret;
3210 }
3211 
3219 {
3221 
3222  switch (prop) {
3223  case 0x09:
3224  case 0x0B:
3225  case 0x0F:
3226  case 0x12:
3227  case 0x13:
3228  case 0x14:
3229  case 0x17:
3230  case 0x18:
3231  case 0x19:
3232  case 0x21:
3233  case 0x22:
3234  buf->ReadByte();
3235  break;
3236 
3237  case 0x0C:
3238  case 0x0D:
3239  case 0x0E:
3240  case 0x10:
3241  case 0x1B:
3242  case 0x1F:
3243  case 0x24:
3244  buf->ReadWord();
3245  break;
3246 
3247  case 0x11:
3248  case 0x1A:
3249  case 0x1C:
3250  case 0x1D:
3251  case 0x1E:
3252  case 0x20:
3253  case 0x23:
3254  buf->ReadDWord();
3255  break;
3256 
3257  case 0x0A: {
3258  byte num_table = buf->ReadByte();
3259  for (byte j = 0; j < num_table; j++) {
3260  for (uint k = 0;; k++) {
3261  byte x = buf->ReadByte();
3262  if (x == 0xFE && k == 0) {
3263  buf->ReadByte();
3264  buf->ReadByte();
3265  break;
3266  }
3267 
3268  byte y = buf->ReadByte();
3269  if (x == 0 && y == 0x80) break;
3270 
3271  byte gfx = buf->ReadByte();
3272  if (gfx == 0xFE) buf->ReadWord();
3273  }
3274  }
3275  break;
3276  }
3277 
3278  case 0x16:
3279  for (byte j = 0; j < 3; j++) buf->ReadByte();
3280  break;
3281 
3282  case 0x15: {
3283  byte number_of_sounds = buf->ReadByte();
3284  for (uint8 j = 0; j < number_of_sounds; j++) {
3285  buf->ReadByte();
3286  }
3287  break;
3288  }
3289 
3290  default:
3291  ret = CIR_UNKNOWN;
3292  break;
3293  }
3294  return ret;
3295 }
3296 
3303 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3304 {
3305  for (int i = 0; i < size - 1; i++) {
3306  for (int j = i + 1; j < size; j++) {
3307  if (layout[i].ti.x == layout[j].ti.x &&
3308  layout[i].ti.y == layout[j].ti.y) {
3309  return false;
3310  }
3311  }
3312  }
3313  return true;
3314 }
3315 
3318 {
3319  if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3320  for (int j = 0; j < ind->num_table; j++) {
3321  /* remove the individual layouts */
3322  free(ind->table[j]);
3323  }
3324  /* remove the layouts pointers */
3325  free(ind->table);
3326  ind->table = NULL;
3327  }
3328 }
3329 
3338 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3339 {
3341 
3342  if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3343  grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3344  return CIR_INVALID_ID;
3345  }
3346 
3347  /* Allocate industry specs if they haven't been allocated already. */
3348  if (_cur.grffile->industryspec == NULL) {
3349  _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3350  }
3351 
3352  for (int i = 0; i < numinfo; i++) {
3353  IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3354 
3355  if (prop != 0x08 && indsp == NULL) {
3356  ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3357  if (cir > ret) ret = cir;
3358  continue;
3359  }
3360 
3361  switch (prop) {
3362  case 0x08: { // Substitute industry type
3363  IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3364  byte subs_id = buf->ReadByte();
3365 
3366  if (subs_id == 0xFF) {
3367  /* Instead of defining a new industry, a substitute industry id
3368  * of 0xFF disables the old industry with the current id. */
3369  _industry_specs[indid + i].enabled = false;
3370  continue;
3371  } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3372  /* The substitute id must be one of the original industry. */
3373  grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3374  continue;
3375  }
3376 
3377  /* Allocate space for this industry.
3378  * Only need to do it once. If ever it is called again, it should not
3379  * do anything */
3380  if (*indspec == NULL) {
3381  *indspec = CallocT<IndustrySpec>(1);
3382  indsp = *indspec;
3383 
3384  memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3385  indsp->enabled = true;
3386  indsp->grf_prop.local_id = indid + i;
3387  indsp->grf_prop.subst_id = subs_id;
3388  indsp->grf_prop.grffile = _cur.grffile;
3389  /* If the grf industry needs to check its surounding upon creation, it should
3390  * rely on callbacks, not on the original placement functions */
3391  indsp->check_proc = CHECK_NOTHING;
3392  }
3393  break;
3394  }
3395 
3396  case 0x09: { // Industry type override
3397  byte ovrid = buf->ReadByte();
3398 
3399  /* The industry being overridden must be an original industry. */
3400  if (ovrid >= NEW_INDUSTRYOFFSET) {
3401  grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3402  continue;
3403  }
3404  indsp->grf_prop.override = ovrid;
3405  _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3406  break;
3407  }
3408 
3409  case 0x0A: { // Set industry layout(s)
3410  byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3411  /* We read the total size in bytes, but we can't rely on the
3412  * newgrf to provide a sane value. First assume the value is
3413  * sane but later on we make sure we enlarge the array if the
3414  * newgrf contains more data. Each tile uses either 3 or 5
3415  * bytes, so to play it safe we assume 3. */
3416  uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3417  IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3418  IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3419  uint size;
3420  const IndustryTileTable *copy_from;
3421 
3422  try {
3423  for (byte j = 0; j < new_num_layouts; j++) {
3424  for (uint k = 0;; k++) {
3425  if (k >= def_num_tiles) {
3426  grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3427  /* Size reported by newgrf was not big enough so enlarge the array. */
3428  def_num_tiles *= 2;
3429  itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3430  }
3431 
3432  itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3433 
3434  if (itt[k].ti.x == 0xFE && k == 0) {
3435  /* This means we have to borrow the layout from an old industry */
3436  IndustryType type = buf->ReadByte(); // industry holding required layout
3437  byte laynbr = buf->ReadByte(); // layout number to borrow
3438 
3439  copy_from = _origin_industry_specs[type].table[laynbr];
3440  for (size = 1;; size++) {
3441  if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3442  }
3443  break;
3444  }
3445 
3446  itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3447 
3448  if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3449  /* Not the same terminator. The one we are using is rather
3450  x = -80, y = x . So, adjust it. */
3451  itt[k].ti.x = -0x80;
3452  itt[k].ti.y = 0;
3453  itt[k].gfx = 0;
3454 
3455  size = k + 1;
3456  copy_from = itt;
3457  break;
3458  }
3459 
3460  itt[k].gfx = buf->ReadByte();
3461 
3462  if (itt[k].gfx == 0xFE) {
3463  /* Use a new tile from this GRF */
3464  int local_tile_id = buf->ReadWord();
3465 
3466  /* Read the ID from the _industile_mngr. */
3467  int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3468 
3469  if (tempid == INVALID_INDUSTRYTILE) {
3470  grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3471  } else {
3472  /* Declared as been valid, can be used */
3473  itt[k].gfx = tempid;
3474  size = k + 1;
3475  copy_from = itt;
3476  }
3477  } else if (itt[k].gfx == 0xFF) {
3478  itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3479  itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3480 
3481  /* When there were only 256x256 maps, TileIndex was a uint16 and
3482  * itt[k].ti was just a TileIndexDiff that was added to it.
3483  * As such negative "x" values were shifted into the "y" position.
3484  * x = -1, y = 1 -> x = 255, y = 0
3485  * Since GRF version 8 the position is interpreted as pair of independent int8.
3486  * For GRF version < 8 we need to emulate the old shifting behaviour.
3487  */
3488  if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3489  }
3490  }
3491 
3492  if (!ValidateIndustryLayout(copy_from, size)) {
3493  /* The industry layout was not valid, so skip this one. */
3494  grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3495  new_num_layouts--;
3496  j--;
3497  } else {
3498  tile_table[j] = CallocT<IndustryTileTable>(size);
3499  memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3500  }
3501  }
3502  } catch (...) {
3503  for (int i = 0; i < new_num_layouts; i++) {
3504  free(tile_table[i]);
3505  }
3506  free(tile_table);
3507  free(itt);
3508  throw;
3509  }
3510 
3511  /* Clean the tile table if it was already set by a previous prop A. */
3512  CleanIndustryTileTable(indsp);
3513  /* Install final layout construction in the industry spec */
3514  indsp->num_table = new_num_layouts;
3515  indsp->table = tile_table;
3517  free(itt);
3518  break;
3519  }
3520 
3521  case 0x0B: // Industry production flags
3522  indsp->life_type = (IndustryLifeType)buf->ReadByte();
3523  break;
3524 
3525  case 0x0C: // Industry closure message
3526  AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3527  break;
3528 
3529  case 0x0D: // Production increase message
3530  AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3531  break;
3532 
3533  case 0x0E: // Production decrease message
3534  AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3535  break;
3536 
3537  case 0x0F: // Fund cost multiplier
3538  indsp->cost_multiplier = buf->ReadByte();
3539  break;
3540 
3541  case 0x10: // Production cargo types
3542  for (byte j = 0; j < 2; j++) {
3543  indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3544  }
3545  break;
3546 
3547  case 0x11: // Acceptance cargo types
3548  for (byte j = 0; j < 3; j++) {
3549  indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3550  }
3551  buf->ReadByte(); // Unnused, eat it up
3552  break;
3553 
3554  case 0x12: // Production multipliers
3555  case 0x13:
3556  indsp->production_rate[prop - 0x12] = buf->ReadByte();
3557  break;
3558 
3559  case 0x14: // Minimal amount of cargo distributed
3560  indsp->minimal_cargo = buf->ReadByte();
3561  break;
3562 
3563  case 0x15: { // Random sound effects
3564  indsp->number_of_sounds = buf->ReadByte();
3565  uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3566 
3567  try {
3568  for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3569  sounds[j] = buf->ReadByte();
3570  }
3571  } catch (...) {
3572  free(sounds);
3573  throw;
3574  }
3575 
3576  if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3577  free(indsp->random_sounds);
3578  }
3579  indsp->random_sounds = sounds;
3581  break;
3582  }
3583 
3584  case 0x16: // Conflicting industry types
3585  for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3586  break;
3587 
3588  case 0x17: // Probability in random game
3589  indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3590  break;
3591 
3592  case 0x18: // Probability during gameplay
3593  indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3594  break;
3595 
3596  case 0x19: // Map colour
3597  indsp->map_colour = buf->ReadByte();
3598  break;
3599 
3600  case 0x1A: // Special industry flags to define special behavior
3601  indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3602  break;
3603 
3604  case 0x1B: // New industry text ID
3605  AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3606  break;
3607 
3608  case 0x1C: // Input cargo multipliers for the three input cargo types
3609  case 0x1D:
3610  case 0x1E: {
3611  uint32 multiples = buf->ReadDWord();
3612  indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3613  indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3614  break;
3615  }
3616 
3617  case 0x1F: // Industry name
3618  AddStringForMapping(buf->ReadWord(), &indsp->name);
3619  break;
3620 
3621  case 0x20: // Prospecting success chance
3622  indsp->prospecting_chance = buf->ReadDWord();
3623  break;
3624 
3625  case 0x21: // Callback mask
3626  case 0x22: { // Callback additional mask
3627  byte aflag = buf->ReadByte();
3628  SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3629  break;
3630  }
3631 
3632  case 0x23: // removal cost multiplier
3633  indsp->removal_cost_multiplier = buf->ReadDWord();
3634  break;
3635 
3636  case 0x24: { // name for nearby station
3637  uint16 str = buf->ReadWord();
3638  if (str == 0) {
3639  indsp->station_name = STR_NULL;
3640  } else {
3641  AddStringForMapping(str, &indsp->station_name);
3642  }
3643  break;
3644  }
3645 
3646  default:
3647  ret = CIR_UNKNOWN;
3648  break;
3649  }
3650  }
3651 
3652  return ret;
3653 }
3654 
3661 {
3662  AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3663  for (int i = 0; i < as->num_table; i++) {
3664  uint num_tiles = 1;
3665  const AirportTileTable *it = as->table[0];
3666  do {
3667  num_tiles++;
3668  } while ((++it)->ti.x != -0x80);
3669  table_list[i] = MallocT<AirportTileTable>(num_tiles);
3670  MemCpyT(table_list[i], as->table[i], num_tiles);
3671  }
3672  as->table = table_list;
3673  HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3674  MemCpyT(depot_table, as->depot_table, as->nof_depots);
3675  as->depot_table = depot_table;
3676  Direction *rotation = MallocT<Direction>(as->num_table);
3677  MemCpyT(rotation, as->rotation, as->num_table);
3678  as->rotation = rotation;
3679 }
3680 
3689 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3690 {
3692 
3693  if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3694  grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3695  return CIR_INVALID_ID;
3696  }
3697 
3698  /* Allocate industry specs if they haven't been allocated already. */
3699  if (_cur.grffile->airportspec == NULL) {
3700  _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3701  }
3702 
3703  for (int i = 0; i < numinfo; i++) {
3704  AirportSpec *as = _cur.grffile->airportspec[airport + i];
3705 
3706  if (as == NULL && prop != 0x08 && prop != 0x09) {
3707  grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3708  return CIR_INVALID_ID;
3709  }
3710 
3711  switch (prop) {
3712  case 0x08: { // Modify original airport
3713  byte subs_id = buf->ReadByte();
3714 
3715  if (subs_id == 0xFF) {
3716  /* Instead of defining a new airport, an airport id
3717  * of 0xFF disables the old airport with the current id. */
3718  AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3719  continue;
3720  } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3721  /* The substitute id must be one of the original airports. */
3722  grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3723  continue;
3724  }
3725 
3726  AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3727  /* Allocate space for this airport.
3728  * Only need to do it once. If ever it is called again, it should not
3729  * do anything */
3730  if (*spec == NULL) {
3731  *spec = MallocT<AirportSpec>(1);
3732  as = *spec;
3733 
3734  memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3735  as->enabled = true;
3736  as->grf_prop.local_id = airport + i;
3737  as->grf_prop.subst_id = subs_id;
3738  as->grf_prop.grffile = _cur.grffile;
3739  /* override the default airport */
3740  _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3741  /* Create a copy of the original tiletable so it can be freed later. */
3742  DuplicateTileTable(as);
3743  }
3744  break;
3745  }
3746 
3747  case 0x0A: { // Set airport layout
3748  free(as->rotation);
3749  as->num_table = buf->ReadByte(); // Number of layaouts
3750  as->rotation = MallocT<Direction>(as->num_table);
3751  uint32 defsize = buf->ReadDWord(); // Total size of the definition
3752  AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3753  AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3754  int size;
3755  const AirportTileTable *copy_from;
3756  try {
3757  for (byte j = 0; j < as->num_table; j++) {
3758  const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3759  for (int k = 0;; k++) {
3760  att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3761  att[k].ti.y = buf->ReadByte();
3762 
3763  if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3764  /* Not the same terminator. The one we are using is rather
3765  * x = -80, y = 0 . So, adjust it. */
3766  att[k].ti.x = -0x80;
3767  att[k].ti.y = 0;
3768  att[k].gfx = 0;
3769 
3770  size = k + 1;
3771  copy_from = att;
3772  break;
3773  }
3774 
3775  att[k].gfx = buf->ReadByte();
3776 
3777  if (att[k].gfx == 0xFE) {
3778  /* Use a new tile from this GRF */
3779  int local_tile_id = buf->ReadWord();
3780 
3781  /* Read the ID from the _airporttile_mngr. */
3782  uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3783 
3784  if (tempid == INVALID_AIRPORTTILE) {
3785  grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3786  } else {
3787  /* Declared as been valid, can be used */
3788  att[k].gfx = tempid;
3789  size = k + 1;
3790  copy_from = att;
3791  }
3792  } else if (att[k].gfx == 0xFF) {
3793  att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3794  att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3795  }
3796 
3797  if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3798  as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3799  as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3800  } else {
3801  as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3802  as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3803  }
3804  }
3805  tile_table[j] = CallocT<AirportTileTable>(size);
3806  memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3807  }
3808  /* Install final layout construction in the airport spec */
3809  as->table = tile_table;
3810  free(att);
3811  } catch (...) {
3812  for (int i = 0; i < as->num_table; i++) {
3813  free(tile_table[i]);
3814  }
3815  free(tile_table);
3816  free(att);
3817  throw;
3818  }
3819  break;
3820  }
3821 
3822  case 0x0C:
3823  as->min_year = buf->ReadWord();
3824  as->max_year = buf->ReadWord();
3825  if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3826  break;
3827 
3828  case 0x0D:
3829  as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3830  break;
3831 
3832  case 0x0E:
3833  as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3834  break;
3835 
3836  case 0x0F:
3837  as->noise_level = buf->ReadByte();
3838  break;
3839 
3840  case 0x10:
3841  AddStringForMapping(buf->ReadWord(), &as->name);
3842  break;
3843 
3844  case 0x11: // Maintenance cost factor
3845  as->maintenance_cost = buf->ReadWord();
3846  break;
3847 
3848  default:
3849  ret = CIR_UNKNOWN;
3850  break;
3851  }
3852  }
3853 
3854  return ret;
3855 }
3856 
3864 {
3866 
3867  switch (prop) {
3868  case 0x0B:
3869  case 0x0C:
3870  case 0x0D:
3871  case 0x12:
3872  case 0x14:
3873  case 0x16:
3874  case 0x17:
3875  buf->ReadByte();
3876  break;
3877 
3878  case 0x09:
3879  case 0x0A:
3880  case 0x10:
3881  case 0x11:
3882  case 0x13:
3883  case 0x15:
3884  buf->ReadWord();
3885  break;
3886 
3887  case 0x08:
3888  case 0x0E:
3889  case 0x0F:
3890  buf->ReadDWord();
3891  break;
3892 
3893  default:
3894  ret = CIR_UNKNOWN;
3895  break;
3896  }
3897 
3898  return ret;
3899 }
3900 
3909 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3910 {
3912 
3913  if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3914  grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3915  return CIR_INVALID_ID;
3916  }
3917 
3918  /* Allocate object specs if they haven't been allocated already. */
3919  if (_cur.grffile->objectspec == NULL) {
3920  _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3921  }
3922 
3923  for (int i = 0; i < numinfo; i++) {
3924  ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3925 
3926  if (prop != 0x08 && spec == NULL) {
3927  /* If the object property 08 is not yet set, ignore this property */
3928  ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3929  if (cir > ret) ret = cir;
3930  continue;
3931  }
3932 
3933  switch (prop) {
3934  case 0x08: { // Class ID
3935  ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3936 
3937  /* Allocate space for this object. */
3938  if (*ospec == NULL) {
3939  *ospec = CallocT<ObjectSpec>(1);
3940  (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3941  }
3942 
3943  /* Swap classid because we read it in BE. */
3944  uint32 classid = buf->ReadDWord();
3945  (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3946  (*ospec)->enabled = true;
3947  break;
3948  }
3949 
3950  case 0x09: { // Class name
3951  ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3952  AddStringForMapping(buf->ReadWord(), &objclass->name);
3953  break;
3954  }
3955 
3956  case 0x0A: // Object name
3957  AddStringForMapping(buf->ReadWord(), &spec->name);
3958  break;
3959 
3960  case 0x0B: // Climate mask
3961  spec->climate = buf->ReadByte();
3962  break;
3963 
3964  case 0x0C: // Size
3965  spec->size = buf->ReadByte();
3966  break;
3967 
3968  case 0x0D: // Build cost multipler
3969  spec->build_cost_multiplier = buf->ReadByte();
3971  break;
3972 
3973  case 0x0E: // Introduction date
3974  spec->introduction_date = buf->ReadDWord();
3975  break;
3976 
3977  case 0x0F: // End of life
3978  spec->end_of_life_date = buf->ReadDWord();
3979  break;
3980 
3981  case 0x10: // Flags
3982  spec->flags = (ObjectFlags)buf->ReadWord();
3983  _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3984  break;
3985 
3986  case 0x11: // Animation info
3987  spec->animation.frames = buf->ReadByte();
3988  spec->animation.status = buf->ReadByte();
3989  break;
3990 
3991  case 0x12: // Animation speed
3992  spec->animation.speed = buf->ReadByte();
3993  break;
3994 
3995  case 0x13: // Animation triggers
3996  spec->animation.triggers = buf->ReadWord();
3997  break;
3998 
3999  case 0x14: // Removal cost multiplier
4000  spec->clear_cost_multiplier = buf->ReadByte();
4001  break;
4002 
4003  case 0x15: // Callback mask
4004  spec->callback_mask = buf->ReadWord();
4005  break;
4006 
4007  case 0x16: // Building height
4008  spec->height = buf->ReadByte();
4009  break;
4010 
4011  case 0x17: // Views
4012  spec->views = buf->ReadByte();
4013  if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4014  grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4015  spec->views = 1;
4016  }
4017  break;
4018 
4019  case 0x18: // Amount placed on 256^2 map on map creation
4020  spec->generate_amount = buf->ReadByte();
4021  break;
4022 
4023  default:
4024  ret = CIR_UNKNOWN;
4025  break;
4026  }
4027  }
4028 
4029  return ret;
4030 }
4031 
4040 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4041 {
4043 
4044  extern RailtypeInfo _railtypes[RAILTYPE_END];
4045 
4046  if (id + numinfo > RAILTYPE_END) {
4047  grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4048  return CIR_INVALID_ID;
4049  }
4050 
4051  for (int i = 0; i < numinfo; i++) {
4052  RailType rt = _cur.grffile->railtype_map[id + i];
4053  if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4054 
4055  RailtypeInfo *rti = &_railtypes[rt];
4056 
4057  switch (prop) {
4058  case 0x08: // Label of rail type
4059  /* Skipped here as this is loaded during reservation stage. */
4060  buf->ReadDWord();
4061  break;
4062 
4063  case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4064  uint16 str = buf->ReadWord();
4066  if (_cur.grffile->grf_version < 8) {
4067  AddStringForMapping(str, &rti->strings.name);
4068  }
4069  break;
4070  }
4071 
4072  case 0x0A: // Menu text of railtype
4073  AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4074  break;
4075 
4076  case 0x0B: // Build window caption
4077  AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4078  break;
4079 
4080  case 0x0C: // Autoreplace text
4081  AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4082  break;
4083 
4084  case 0x0D: // New locomotive text
4085  AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4086  break;
4087 
4088  case 0x0E: // Compatible railtype list
4089  case 0x0F: // Powered railtype list
4090  case 0x18: // Railtype list required for date introduction
4091  case 0x19: // Introduced railtype list
4092  {
4093  /* Rail type compatibility bits are added to the existing bits
4094  * to allow multiple GRFs to modify compatibility with the
4095  * default rail types. */
4096  int n = buf->ReadByte();
4097  for (int j = 0; j != n; j++) {
4098  RailTypeLabel label = buf->ReadDWord();
4099  RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4100  if (rt != INVALID_RAILTYPE) {
4101  switch (prop) {
4102  case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4103  case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4104  case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4105  case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4106  }
4107  }
4108  }
4109  break;
4110  }
4111 
4112  case 0x10: // Rail Type flags
4113  rti->flags = (RailTypeFlags)buf->ReadByte();
4114  break;
4115 
4116  case 0x11: // Curve speed advantage
4117  rti->curve_speed = buf->ReadByte();
4118  break;
4119 
4120  case 0x12: // Station graphic
4121  rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4122  break;
4123 
4124  case 0x13: // Construction cost factor
4125  rti->cost_multiplier = buf->ReadWord();
4126  break;
4127 
4128  case 0x14: // Speed limit
4129  rti->max_speed = buf->ReadWord();
4130  break;
4131 
4132  case 0x15: // Acceleration model
4133  rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4134  break;
4135 
4136  case 0x16: // Map colour
4137  rti->map_colour = buf->ReadByte();
4138  break;
4139 
4140  case 0x17: // Introduction date
4141  rti->introduction_date = buf->ReadDWord();
4142  break;
4143 
4144  case 0x1A: // Sort order
4145  rti->sorting_order = buf->ReadByte();
4146  break;
4147 
4148  case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4149  AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4150  break;
4151 
4152  case 0x1C: // Maintenance cost factor
4153  rti->maintenance_multiplier = buf->ReadWord();
4154  break;
4155 
4156  case 0x1D: // Alternate rail type label list
4157  /* Skipped here as this is loaded during reservation stage. */
4158  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4159  break;
4160 
4161  default:
4162  ret = CIR_UNKNOWN;
4163  break;
4164  }
4165  }
4166 
4167  return ret;
4168 }
4169 
4170 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4171 {
4173 
4174  extern RailtypeInfo _railtypes[RAILTYPE_END];
4175 
4176  if (id + numinfo > RAILTYPE_END) {
4177  grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4178  return CIR_INVALID_ID;
4179  }
4180 
4181  for (int i = 0; i < numinfo; i++) {
4182  switch (prop) {
4183  case 0x08: // Label of rail type
4184  {
4185  RailTypeLabel rtl = buf->ReadDWord();
4186  rtl = BSWAP32(rtl);
4187 
4188  RailType rt = GetRailTypeByLabel(rtl, false);
4189  if (rt == INVALID_RAILTYPE) {
4190  /* Set up new rail type */
4191  rt = AllocateRailType(rtl);
4192  }
4193 
4194  _cur.grffile->railtype_map[id + i] = rt;
4195  break;
4196  }
4197 
4198  case 0x09: // Toolbar caption of railtype
4199  case 0x0A: // Menu text
4200  case 0x0B: // Build window caption
4201  case 0x0C: // Autoreplace text
4202  case 0x0D: // New loco
4203  case 0x13: // Construction cost
4204  case 0x14: // Speed limit
4205  case 0x1B: // Name of railtype
4206  case 0x1C: // Maintenance cost factor
4207  buf->ReadWord();
4208  break;
4209 
4210  case 0x1D: // Alternate rail type label list
4211  if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4212  int n = buf->ReadByte();
4213  for (int j = 0; j != n; j++) {
4214  *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4215  }
4216  break;
4217  }
4218  grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4219  FALLTHROUGH;
4220 
4221  case 0x0E: // Compatible railtype list
4222  case 0x0F: // Powered railtype list
4223  case 0x18: // Railtype list required for date introduction
4224  case 0x19: // Introduced railtype list
4225  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4226  break;
4227 
4228  case 0x10: // Rail Type flags
4229  case 0x11: // Curve speed advantage
4230  case 0x12: // Station graphic
4231  case 0x15: // Acceleration model
4232  case 0x16: // Map colour
4233  case 0x1A: // Sort order
4234  buf->ReadByte();
4235  break;
4236 
4237  case 0x17: // Introduction date
4238  buf->ReadDWord();
4239  break;
4240 
4241  default:
4242  ret = CIR_UNKNOWN;
4243  break;
4244  }
4245  }
4246 
4247  return ret;
4248 }
4249 
4250 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4251 {
4253 
4254  if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4255  grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4256  return CIR_INVALID_ID;
4257  }
4258 
4259  /* Allocate airport tile specs if they haven't been allocated already. */
4260  if (_cur.grffile->airtspec == NULL) {
4261  _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4262  }
4263 
4264  for (int i = 0; i < numinfo; i++) {
4265  AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4266 
4267  if (prop != 0x08 && tsp == NULL) {
4268  grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4269  return CIR_INVALID_ID;
4270  }
4271 
4272  switch (prop) {
4273  case 0x08: { // Substitute airport tile type
4274  AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4275  byte subs_id = buf->ReadByte();
4276 
4277  if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4278  /* The substitute id must be one of the original airport tiles. */
4279  grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4280  continue;
4281  }
4282 
4283  /* Allocate space for this airport tile. */
4284  if (*tilespec == NULL) {
4285  *tilespec = CallocT<AirportTileSpec>(1);
4286  tsp = *tilespec;
4287 
4288  memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4289  tsp->enabled = true;
4290 
4291  tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4292 
4293  tsp->grf_prop.local_id = airtid + i;
4294  tsp->grf_prop.subst_id = subs_id;
4295  tsp->grf_prop.grffile = _cur.grffile;
4296  _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4297  }
4298  break;
4299  }
4300 
4301  case 0x09: { // Airport tile override
4302  byte override = buf->ReadByte();
4303 
4304  /* The airport tile being overridden must be an original airport tile. */
4305  if (override >= NEW_AIRPORTTILE_OFFSET) {
4306  grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4307  continue;
4308  }
4309 
4310  _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4311  break;
4312  }
4313 
4314  case 0x0E: // Callback mask
4315  tsp->callback_mask = buf->ReadByte();
4316  break;
4317 
4318  case 0x0F: // Animation information
4319  tsp->animation.frames = buf->ReadByte();
4320  tsp->animation.status = buf->ReadByte();
4321  break;
4322 
4323  case 0x10: // Animation speed
4324  tsp->animation.speed = buf->ReadByte();
4325  break;
4326 
4327  case 0x11: // Animation triggers
4328  tsp->animation.triggers = buf->ReadByte();
4329  break;
4330 
4331  default:
4332  ret = CIR_UNKNOWN;
4333  break;
4334  }
4335  }
4336 
4337  return ret;
4338 }
4339 
4340 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4341 {
4342  switch (cir) {
4343  default: NOT_REACHED();
4344 
4345  case CIR_DISABLED:
4346  /* Error has already been printed; just stop parsing */
4347  return true;
4348 
4349  case CIR_SUCCESS:
4350  return false;
4351 
4352  case CIR_UNHANDLED:
4353  grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4354  return false;
4355 
4356  case CIR_UNKNOWN:
4357  grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4358  FALLTHROUGH;
4359 
4360  case CIR_INVALID_ID: {
4361  /* No debug message for an invalid ID, as it has already been output */
4362  GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4363  if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4364  return true;
4365  }
4366  }
4367 }
4368 
4369 /* Action 0x00 */
4370 static void FeatureChangeInfo(ByteReader *buf)
4371 {
4372  /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4373  *
4374  * B feature
4375  * B num-props how many properties to change per vehicle/station
4376  * B num-info how many vehicles/stations to change
4377  * E id ID of first vehicle/station to change, if num-info is
4378  * greater than one, this one and the following
4379  * vehicles/stations will be changed
4380  * B property what property to change, depends on the feature
4381  * V new-info new bytes of info (variable size; depends on properties) */
4382 
4383  static const VCI_Handler handler[] = {
4384  /* GSF_TRAINS */ RailVehicleChangeInfo,
4385  /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4386  /* GSF_SHIPS */ ShipVehicleChangeInfo,
4387  /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4388  /* GSF_STATIONS */ StationChangeInfo,
4389  /* GSF_CANALS */ CanalChangeInfo,
4390  /* GSF_BRIDGES */ BridgeChangeInfo,
4391  /* GSF_HOUSES */ TownHouseChangeInfo,
4392  /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4393  /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4394  /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4395  /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4396  /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4397  /* GSF_AIRPORTS */ AirportChangeInfo,
4398  /* GSF_SIGNALS */ NULL,
4399  /* GSF_OBJECTS */ ObjectChangeInfo,
4400  /* GSF_RAILTYPES */ RailTypeChangeInfo,
4401  /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4402  };
4403 
4404  uint8 feature = buf->ReadByte();
4405  uint8 numprops = buf->ReadByte();
4406  uint numinfo = buf->ReadByte();
4407  uint engine = buf->ReadExtendedByte();
4408 
4409  grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410  feature, numprops, engine, numinfo);
4411 
4412  if (feature >= lengthof(handler) || handler[feature] == NULL) {
4413  if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4414  return;
4415  }
4416 
4417  /* Mark the feature as used by the grf */
4418  SetBit(_cur.grffile->grf_features, feature);
4419 
4420  while (numprops-- && buf->HasData()) {
4421  uint8 prop = buf->ReadByte();
4422 
4423  ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4424  if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4425  }
4426 }
4427 
4428 /* Action 0x00 (GLS_SAFETYSCAN) */
4429 static void SafeChangeInfo(ByteReader *buf)
4430 {
4431  uint8 feature = buf->ReadByte();
4432  uint8 numprops = buf->ReadByte();
4433  uint numinfo = buf->ReadByte();
4434  buf->ReadExtendedByte(); // id
4435 
4436  if (feature == GSF_BRIDGES && numprops == 1) {
4437  uint8 prop = buf->ReadByte();
4438  /* Bridge property 0x0D is redefinition of sprite layout tables, which
4439  * is considered safe. */
4440  if (prop == 0x0D) return;
4441  } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4442  uint8 prop = buf->ReadByte();
4443  /* Engine ID Mappings are safe, if the source is static */
4444  if (prop == 0x11) {
4445  bool is_safe = true;
4446  for (uint i = 0; i < numinfo; i++) {
4447  uint32 s = buf->ReadDWord();
4448  buf->ReadDWord(); // dest
4449  const GRFConfig *grfconfig = GetGRFConfig(s);
4450  if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4451  is_safe = false;
4452  break;
4453  }
4454  }
4455  if (is_safe) return;
4456  }
4457  }
4458 
4459  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4460 
4461  /* Skip remainder of GRF */
4462  _cur.skip_sprites = -1;
4463 }
4464 
4465 /* Action 0x00 (GLS_RESERVE) */
4466 static void ReserveChangeInfo(ByteReader *buf)
4467 {
4468  uint8 feature = buf->ReadByte();
4469 
4470  if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4471 
4472  uint8 numprops = buf->ReadByte();
4473  uint8 numinfo = buf->ReadByte();
4474  uint8 index = buf->ReadExtendedByte();
4475 
4476  while (numprops-- && buf->HasData()) {
4477  uint8 prop = buf->ReadByte();
4479 
4480  switch (feature) {
4481  default: NOT_REACHED();
4482  case GSF_CARGOES:
4483  cir = CargoChangeInfo(index, numinfo, prop, buf);
4484  break;
4485 
4486  case GSF_GLOBALVAR:
4487  cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4488  break;
4489 
4490  case GSF_RAILTYPES:
4491  cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4492  break;
4493  }
4494 
4495  if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4496  }
4497 }
4498 
4499 /* Action 0x01 */
4500 static void NewSpriteSet(ByteReader *buf)
4501 {
4502  /* Basic format: <01> <feature> <num-sets> <num-ent>
4503  * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4504  *
4505  * B feature feature to define sprites for
4506  * 0, 1, 2, 3: veh-type, 4: train stations
4507  * E first-set first sprite set to define
4508  * B num-sets number of sprite sets (extended byte in extended format)
4509  * E num-ent how many entries per sprite set
4510  * For vehicles, this is the number of different
4511  * vehicle directions in each sprite set
4512  * Set num-dirs=8, unless your sprites are symmetric.
4513  * In that case, use num-dirs=4.
4514  */
4515 
4516  uint8 feature = buf->ReadByte();
4517  uint16 num_sets = buf->ReadByte();
4518  uint16 first_set = 0;
4519 
4520  if (num_sets == 0 && buf->HasData(3)) {
4521  /* Extended Action1 format.
4522  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4523  first_set = buf->ReadExtendedByte();
4524  num_sets = buf->ReadExtendedByte();
4525  }
4526  uint16 num_ents = buf->ReadExtendedByte();
4527 
4528  _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4529 
4530  grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531  _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4532  );
4533 
4534  for (int i = 0; i < num_sets * num_ents; i++) {
4535  _cur.nfo_line++;
4536  LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4537  }
4538 }
4539 
4540 /* Action 0x01 (SKIP) */
4541 static void SkipAct1(ByteReader *buf)
4542 {
4543  buf->ReadByte();
4544  uint16 num_sets = buf->ReadByte();
4545 
4546  if (num_sets == 0 && buf->HasData(3)) {
4547  /* Extended Action1 format.
4548  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4549  buf->ReadExtendedByte(); // first_set
4550  num_sets = buf->ReadExtendedByte();
4551  }
4552  uint16 num_ents = buf->ReadExtendedByte();
4553 
4554  _cur.skip_sprites = num_sets * num_ents;
4555 
4556  grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4557 }
4558 
4559 /* Helper function to either create a callback or link to a previously
4560  * defined spritegroup. */
4561 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4562 {
4563  if (HasBit(groupid, 15)) {
4565  return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4566  }
4567 
4568  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4569  grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4570  return NULL;
4571  }
4572 
4573  return _cur.spritegroups[groupid];
4574 }
4575 
4584 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4585 {
4586  if (HasBit(spriteid, 15)) {
4588  return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4589  }
4590 
4591  if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4592  grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4593  return NULL;
4594  }
4595 
4596  SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4597  uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4598 
4599  /* Ensure that the sprites are loeded */
4600  assert(spriteset_start + num_sprites <= _cur.spriteid);
4601 
4603  return new ResultSpriteGroup(spriteset_start, num_sprites);
4604 }
4605 
4606 /* Action 0x02 */
4607 static void NewSpriteGroup(ByteReader *buf)
4608 {
4609  /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4610  *
4611  * B feature see action 1
4612  * B set-id ID of this particular definition
4613  * B type/num-entries
4614  * if 80 or greater, this is a randomized or variational
4615  * list definition, see below
4616  * otherwise it specifies a number of entries, the exact
4617  * meaning depends on the feature
4618  * V feature-specific-data (huge mess, don't even look it up --pasky) */
4619  SpriteGroup *act_group = NULL;
4620 
4621  uint8 feature = buf->ReadByte();
4622  uint8 setid = buf->ReadByte();
4623  uint8 type = buf->ReadByte();
4624 
4625  /* Sprite Groups are created here but they are allocated from a pool, so
4626  * we do not need to delete anything if there is an exception from the
4627  * ByteReader. */
4628 
4629  switch (type) {
4630  /* Deterministic Sprite Group */
4631  case 0x81: // Self scope, byte
4632  case 0x82: // Parent scope, byte
4633  case 0x85: // Self scope, word
4634  case 0x86: // Parent scope, word
4635  case 0x89: // Self scope, dword
4636  case 0x8A: // Parent scope, dword
4637  {
4638  byte varadjust;
4639  byte varsize;
4640 
4643  act_group = group;
4644  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4645 
4646  switch (GB(type, 2, 2)) {
4647  default: NOT_REACHED();
4648  case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4649  case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4650  case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4651  }
4652 
4654  adjusts.Clear();
4655 
4656  /* Loop through the var adjusts. Unfortunately we don't know how many we have
4657  * from the outset, so we shall have to keep reallocing. */
4658  do {
4659  DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4660 
4661  /* The first var adjust doesn't have an operation specified, so we set it to add. */
4662  adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4663  adjust->variable = buf->ReadByte();
4664  if (adjust->variable == 0x7E) {
4665  /* Link subroutine group */
4666  adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4667  } else {
4668  adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4669  }
4670 
4671  varadjust = buf->ReadByte();
4672  adjust->shift_num = GB(varadjust, 0, 5);
4673  adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4674  adjust->and_mask = buf->ReadVarSize(varsize);
4675 
4676  if (adjust->type != DSGA_TYPE_NONE) {
4677  adjust->add_val = buf->ReadVarSize(varsize);
4678  adjust->divmod_val = buf->ReadVarSize(varsize);
4679  } else {
4680  adjust->add_val = 0;
4681  adjust->divmod_val = 0;
4682  }
4683 
4684  /* Continue reading var adjusts while bit 5 is set. */
4685  } while (HasBit(varadjust, 5));
4686 
4687  group->num_adjusts = adjusts.Length();
4688  group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4689  MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4690 
4691  std::vector<DeterministicSpriteGroupRange> ranges;
4692  ranges.resize(buf->ReadByte());
4693  for (uint i = 0; i < ranges.size(); i++) {
4694  ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4695  ranges[i].low = buf->ReadVarSize(varsize);
4696  ranges[i].high = buf->ReadVarSize(varsize);
4697  }
4698 
4699  group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4700  group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
4701  /* nvar == 0 is a special case -- we turn our value into a callback result */
4702  group->calculated_result = ranges.size() == 0;
4703 
4704  /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4705  std::vector<uint32> bounds;
4706  for (uint i = 0; i < ranges.size(); i++) {
4707  bounds.push_back(ranges[i].low);
4708  if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4709  }
4710  std::sort(bounds.begin(), bounds.end());
4711  bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4712 
4713  std::vector<const SpriteGroup *> target;
4714  for (uint j = 0; j < bounds.size(); ++j) {
4715  uint32 v = bounds[j];
4716  const SpriteGroup *t = group->default_group;
4717  for (uint i = 0; i < ranges.size(); i++) {
4718  if (ranges[i].low <= v && v <= ranges[i].high) {
4719  t = ranges[i].group;
4720  break;
4721  }
4722  }
4723  target.push_back(t);
4724  }
4725  assert(target.size() == bounds.size());
4726 
4727  std::vector<DeterministicSpriteGroupRange> optimised;
4728  for (uint j = 0; j < bounds.size(); ) {
4729  if (target[j] != group->default_group) {
4731  r.group = target[j];
4732  r.low = bounds[j];
4733  while (j < bounds.size() && target[j] == r.group) {
4734  j++;
4735  }
4736  r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
4737  optimised.push_back(r);
4738  } else {
4739  j++;
4740  }
4741  }
4742 
4743  group->num_ranges = optimised.size();
4744  if (group->num_ranges > 0) {
4745  group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4746  MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
4747  }
4748  break;
4749  }
4750 
4751  /* Randomized Sprite Group */
4752  case 0x80: // Self scope
4753  case 0x83: // Parent scope
4754  case 0x84: // Relative scope
4755  {
4758  act_group = group;
4759  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4760 
4761  if (HasBit(type, 2)) {
4762  if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4763  group->count = buf->ReadByte();
4764  }
4765 
4766  uint8 triggers = buf->ReadByte();
4767  group->triggers = GB(triggers, 0, 7);
4768  group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4769  group->lowest_randbit = buf->ReadByte();
4770  group->num_groups = buf->ReadByte();
4771  group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4772 
4773  for (uint i = 0; i < group->num_groups; i++) {
4774  group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4775  }
4776 
4777  break;
4778  }
4779 
4780  /* Neither a variable or randomized sprite group... must be a real group */
4781  default:
4782  {
4783  switch (feature) {
4784  case GSF_TRAINS:
4785  case GSF_ROADVEHICLES:
4786  case GSF_SHIPS:
4787  case GSF_AIRCRAFT:
4788  case GSF_STATIONS:
4789  case GSF_CANALS:
4790  case GSF_CARGOES:
4791  case GSF_AIRPORTS:
4792  case GSF_RAILTYPES:
4793  {
4794  byte num_loaded = type;
4795  byte num_loading = buf->ReadByte();
4796 
4797  if (!_cur.HasValidSpriteSets(feature)) {
4798  grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4799  return;
4800  }
4801 
4803  RealSpriteGroup *group = new RealSpriteGroup();
4804  act_group = group;
4805 
4806  group->num_loaded = num_loaded;
4807  group->num_loading = num_loading;
4808  if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4809  if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4810 
4811  grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4812  setid, num_loaded, num_loading);
4813 
4814  for (uint i = 0; i < num_loaded; i++) {
4815  uint16 spriteid = buf->ReadWord();
4816  group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4817  grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4818  }
4819 
4820  for (uint i = 0; i < num_loading; i++) {
4821  uint16 spriteid = buf->ReadWord();
4822  group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4823  grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4824  }
4825 
4826  break;
4827  }
4828 
4829  case GSF_HOUSES:
4830  case GSF_AIRPORTTILES:
4831  case GSF_OBJECTS:
4832  case GSF_INDUSTRYTILES: {
4833  byte num_building_sprites = max((uint8)1, type);
4834 
4837  act_group = group;
4838 
4839  /* On error, bail out immediately. Temporary GRF data was already freed */
4840  if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4841  break;
4842  }
4843 
4844  case GSF_INDUSTRIES: {
4845  if (type > 1) {
4846  grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4847  break;
4848  }
4849 
4852  act_group = group;
4853  group->version = type;
4854  if (type == 0) {
4855  for (uint i = 0; i < 3; i++) {
4856  group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4857  }
4858  for (uint i = 0; i < 2; i++) {
4859  group->add_output[i] = buf->ReadWord(); // unsigned
4860  }
4861  group->again = buf->ReadByte();
4862  } else {
4863  for (uint i = 0; i < 3; i++) {
4864  group->subtract_input[i] = buf->ReadByte();
4865  }
4866  for (uint i = 0; i < 2; i++) {
4867  group->add_output[i] = buf->ReadByte();
4868  }
4869  group->again = buf->ReadByte();
4870  }
4871  break;
4872  }
4873 
4874  /* Loading of Tile Layout and Production Callback groups would happen here */
4875  default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4876  }
4877  }
4878  }
4879 
4880  _cur.spritegroups[setid] = act_group;
4881 }
4882 
4883 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4884 {
4885  if (feature == GSF_OBJECTS) {
4886  switch (ctype) {
4887  case 0: return 0;
4888  case 0xFF: return CT_PURCHASE_OBJECT;
4889  default:
4890  grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4891  return CT_INVALID;
4892  }
4893  }
4894  /* Special cargo types for purchase list and stations */
4895  if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4896  if (ctype == 0xFF) return CT_PURCHASE;
4897 
4898  if (_cur.grffile->cargo_list.Length() == 0) {
4899  /* No cargo table, so use bitnum values */
4900  if (ctype >= 32) {
4901  grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4902  return CT_INVALID;
4903  }
4904 
4905  const CargoSpec *cs;
4906  FOR_ALL_CARGOSPECS(cs) {
4907  if (cs->bitnum == ctype) {
4908  grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4909  return cs->Index();
4910  }
4911  }
4912 
4913  grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4914  return CT_INVALID;
4915  }
4916 
4917  /* Check if the cargo type is out of bounds of the cargo translation table */
4918  if (ctype >= _cur.grffile->cargo_list.Length()) {
4919  grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4920  return CT_INVALID;
4921  }
4922 
4923  /* Look up the cargo label from the translation table */
4924  CargoLabel cl = _cur.grffile->cargo_list[ctype];
4925  if (cl == 0) {
4926  grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4927  return CT_INVALID;
4928  }
4929 
4930  ctype = GetCargoIDByLabel(cl);
4931  if (ctype == CT_INVALID) {
4932  grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
4933  return CT_INVALID;
4934  }
4935 
4936  grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
4937  return ctype;
4938 }
4939 
4940 
4941 static bool IsValidGroupID(uint16 groupid, const char *function)
4942 {
4943  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4944  grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4945  return false;
4946  }
4947 
4948  return true;
4949 }
4950 
4951 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4952 {
4953  static EngineID *last_engines;
4954  static uint last_engines_count;
4955  bool wagover = false;
4956 
4957  /* Test for 'wagon override' flag */
4958  if (HasBit(idcount, 7)) {
4959  wagover = true;
4960  /* Strip off the flag */
4961  idcount = GB(idcount, 0, 7);
4962 
4963  if (last_engines_count == 0) {
4964  grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4965  return;
4966  }
4967 
4968  grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4969  last_engines_count, idcount);
4970  } else {
4971  if (last_engines_count != idcount) {
4972  last_engines = ReallocT(last_engines, idcount);
4973  last_engines_count = idcount;
4974  }
4975  }
4976 
4977  EngineID *engines = AllocaM(EngineID, idcount);
4978  for (uint i = 0; i < idcount; i++) {
4979  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4980  if (e == NULL) {
4981  /* No engine could be allocated?!? Deal with it. Okay,
4982  * this might look bad. Also make sure this NewGRF
4983  * gets disabled, as a half loaded one is bad. */
4984  HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4985  return;
4986  }
4987 
4988  engines[i] = e->index;
4989  if (!wagover) last_engines[i] = engines[i];
4990  }
4991 
4992  uint8 cidcount = buf->ReadByte();
4993  for (uint c = 0; c < cidcount; c++) {
4994  uint8 ctype = buf->ReadByte();
4995  uint16 groupid = buf->ReadWord();
4996  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4997 
4998  grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4999 
5000  ctype = TranslateCargo(feature, ctype);
5001  if (ctype == CT_INVALID) continue;
5002 
5003  for (uint i = 0; i < idcount; i++) {
5004  EngineID engine = engines[i];
5005 
5006  grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5007 
5008  if (wagover) {
5009  SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5010  } else {
5011  SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5012  }
5013  }
5014  }
5015 
5016  uint16 groupid = buf->ReadWord();
5017  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5018 
5019  grfmsg(8, "-- Default group id 0x%04X", groupid);
5020 
5021  for (uint i = 0; i < idcount; i++) {
5022  EngineID engine = engines[i];
5023 
5024  if (wagover) {
5025  SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5026  } else {
5027  SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5028  SetEngineGRF(engine, _cur.grffile);
5029  }
5030  }
5031 }
5032 
5033 
5034 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5035 {
5036  CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5037  for (uint i = 0; i < idcount; i++) {
5038  cfs[i] = (CanalFeature)buf->ReadByte();
5039  }
5040 
5041  uint8 cidcount = buf->ReadByte();
5042  buf->Skip(cidcount * 3);
5043 
5044  uint16 groupid = buf->ReadWord();
5045  if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5046 
5047  for (uint i = 0; i < idcount; i++) {
5048  CanalFeature cf = cfs[i];
5049 
5050  if (cf >= CF_END) {
5051  grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5052  continue;
5053  }
5054 
5055  _water_feature[cf].grffile = _cur.grffile;
5056  _water_feature[cf].group = _cur.spritegroups[groupid];
5057  }
5058 }
5059 
5060 
5061 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5062 {
5063  uint8 *stations = AllocaM(uint8, idcount);
5064  for (uint i = 0; i < idcount; i++) {
5065  stations[i] = buf->ReadByte();
5066  }
5067 
5068  uint8 cidcount = buf->ReadByte();
5069  for (uint c = 0; c < cidcount; c++) {
5070  uint8 ctype = buf->ReadByte();
5071  uint16 groupid = buf->ReadWord();
5072  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5073 
5074  ctype = TranslateCargo(GSF_STATIONS, ctype);
5075  if (ctype == CT_INVALID) continue;
5076 
5077  for (uint i = 0; i < idcount; i++) {
5078  StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5079 
5080  if (statspec == NULL) {
5081  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5082  continue;
5083  }
5084 
5085  statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5086  }
5087  }
5088 
5089  uint16 groupid = buf->ReadWord();
5090  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5091 
5092  for (uint i = 0; i < idcount; i++) {
5093  StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5094 
5095  if (statspec == NULL) {
5096  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5097  continue;
5098  }
5099 
5100  if (statspec->grf_prop.grffile != NULL) {
5101  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5102  continue;
5103  }
5104 
5105  statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5106  statspec->grf_prop.grffile = _cur.grffile;
5107  statspec->grf_prop.local_id = stations[i];
5108  StationClass::Assign(statspec);
5109  }
5110 }
5111 
5112 
5113 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5114 {
5115  uint8 *houses = AllocaM(uint8, idcount);
5116  for (uint i = 0; i < idcount; i++) {
5117  houses[i] = buf->ReadByte();
5118  }
5119 
5120  /* Skip the cargo type section, we only care about the default group */
5121  uint8 cidcount = buf->ReadByte();
5122  buf->Skip(cidcount * 3);
5123 
5124  uint16 groupid = buf->ReadWord();
5125  if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5126 
5127  if (_cur.grffile->housespec == NULL) {
5128  grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5129  return;
5130  }
5131 
5132  for (uint i = 0; i < idcount; i++) {
5133  HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5134 
5135  if (hs == NULL) {
5136  grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5137  continue;
5138  }
5139 
5140  hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5141  }
5142 }
5143 
5144 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5145 {
5146  uint8 *industries = AllocaM(uint8, idcount);
5147  for (uint i = 0; i < idcount; i++) {
5148  industries[i] = buf->ReadByte();
5149  }
5150 
5151  /* Skip the cargo type section, we only care about the default group */
5152  uint8 cidcount = buf->ReadByte();
5153  buf->Skip(cidcount * 3);
5154 
5155  uint16 groupid = buf->ReadWord();
5156  if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5157 
5158  if (_cur.grffile->industryspec == NULL) {
5159  grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5160  return;
5161  }
5162 
5163  for (uint i = 0; i < idcount; i++) {
5164  IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5165 
5166  if (indsp == NULL) {
5167  grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5168  continue;
5169  }
5170 
5171  indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5172  }
5173 }
5174 
5175 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5176 {
5177  uint8 *indtiles = AllocaM(uint8, idcount);
5178  for (uint i = 0; i < idcount; i++) {
5179  indtiles[i] = buf->ReadByte();
5180  }
5181 
5182  /* Skip the cargo type section, we only care about the default group */
5183  uint8 cidcount = buf->ReadByte();
5184  buf->Skip(cidcount * 3);
5185 
5186  uint16 groupid = buf->ReadWord();
5187  if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5188 
5189  if (_cur.grffile->indtspec == NULL) {
5190  grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5191  return;
5192  }
5193 
5194  for (uint i = 0; i < idcount; i++) {
5195  IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5196 
5197  if (indtsp == NULL) {
5198  grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5199  continue;
5200  }
5201 
5202  indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5203  }
5204 }
5205 
5206 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5207 {
5208  CargoID *cargoes = AllocaM(CargoID, idcount);
5209  for (uint i = 0; i < idcount; i++) {
5210  cargoes[i] = buf->ReadByte();
5211  }
5212 
5213  /* Skip the cargo type section, we only care about the default group */
5214  uint8 cidcount = buf->ReadByte();
5215  buf->Skip(cidcount * 3);
5216 
5217  uint16 groupid = buf->ReadWord();
5218  if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5219 
5220  for (uint i = 0; i < idcount; i++) {
5221  CargoID cid = cargoes[i];
5222 
5223  if (cid >= NUM_CARGO) {
5224  grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5225  continue;
5226  }
5227 
5228  CargoSpec *cs = CargoSpec::Get(cid);
5229  cs->grffile = _cur.grffile;
5230  cs->group = _cur.spritegroups[groupid];
5231  }
5232 }
5233 
5234 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5235 {
5236  if (_cur.grffile->objectspec == NULL) {
5237  grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5238  return;
5239  }
5240 
5241  uint8 *objects = AllocaM(uint8, idcount);
5242  for (uint i = 0; i < idcount; i++) {
5243  objects[i] = buf->ReadByte();
5244  }
5245 
5246  uint8 cidcount = buf->ReadByte();
5247  for (uint c = 0; c < cidcount; c++) {
5248  uint8 ctype = buf->ReadByte();
5249  uint16 groupid = buf->ReadWord();
5250  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5251 
5252  ctype = TranslateCargo(GSF_OBJECTS, ctype);
5253  if (ctype == CT_INVALID) continue;
5254 
5255  for (uint i = 0; i < idcount; i++) {
5256  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5257 
5258  if (spec == NULL) {
5259  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5260  continue;
5261  }
5262 
5263  spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5264  }
5265  }
5266 
5267  uint16 groupid = buf->ReadWord();
5268  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5269 
5270  for (uint i = 0; i < idcount; i++) {
5271  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5272 
5273  if (spec == NULL) {
5274  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5275  continue;
5276  }
5277 
5278  if (spec->grf_prop.grffile != NULL) {
5279  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5280  continue;
5281  }
5282 
5283  spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5284  spec->grf_prop.grffile = _cur.grffile;
5285  spec->grf_prop.local_id = objects[i];
5286  }
5287 }
5288 
5289 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5290 {
5291  uint8 *railtypes = AllocaM(uint8, idcount);
5292  for (uint i = 0; i < idcount; i++) {
5293  railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5294  }
5295 
5296  uint8 cidcount = buf->ReadByte();
5297  for (uint c = 0; c < cidcount; c++) {
5298  uint8 ctype = buf->ReadByte();
5299  uint16 groupid = buf->ReadWord();
5300  if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5301 
5302  if (ctype >= RTSG_END) continue;
5303 
5304  extern RailtypeInfo _railtypes[RAILTYPE_END];
5305  for (uint i = 0; i < idcount; i++) {
5306  if (railtypes[i] != INVALID_RAILTYPE) {
5307  RailtypeInfo *rti = &_railtypes[railtypes[i]];
5308 
5309  rti->grffile[ctype] = _cur.grffile;
5310  rti->group[ctype] = _cur.spritegroups[groupid];
5311  }
5312  }
5313  }
5314 
5315  /* Railtypes do not use the default group. */
5316  buf->ReadWord();
5317 }
5318 
5319 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5320 {
5321  uint8 *airports = AllocaM(uint8, idcount);
5322  for (uint i = 0; i < idcount; i++) {
5323  airports[i] = buf->ReadByte();
5324  }
5325 
5326  /* Skip the cargo type section, we only care about the default group */
5327  uint8 cidcount = buf->ReadByte();
5328  buf->Skip(cidcount * 3);
5329 
5330  uint16 groupid = buf->ReadWord();
5331  if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5332 
5333  if (_cur.grffile->airportspec == NULL) {
5334  grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5335  return;
5336  }
5337 
5338  for (uint i = 0; i < idcount; i++) {
5339  AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5340 
5341  if (as == NULL) {
5342  grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5343  continue;
5344  }
5345 
5346  as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5347  }
5348 }
5349 
5350 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5351 {
5352  uint8 *airptiles = AllocaM(uint8, idcount);
5353  for (uint i = 0; i < idcount; i++) {
5354  airptiles[i] = buf->ReadByte();
5355  }
5356 
5357  /* Skip the cargo type section, we only care about the default group */
5358  uint8 cidcount = buf->ReadByte();
5359  buf->Skip(cidcount * 3);
5360 
5361  uint16 groupid = buf->ReadWord();
5362  if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5363 
5364  if (_cur.grffile->airtspec == NULL) {
5365  grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5366  return;
5367  }
5368 
5369  for (uint i = 0; i < idcount; i++) {
5370  AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5371 
5372  if (airtsp == NULL) {
5373  grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5374  continue;
5375  }
5376 
5377  airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5378  }
5379 }
5380 
5381 
5382 /* Action 0x03 */
5383 static void FeatureMapSpriteGroup(ByteReader *buf)
5384 {
5385  /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5386  * id-list := [<id>] [id-list]
5387  * cargo-list := <cargo-type> <cid> [cargo-list]
5388  *
5389  * B feature see action 0
5390  * B n-id bits 0-6: how many IDs this definition applies to
5391  * bit 7: if set, this is a wagon override definition (see below)
5392  * B ids the IDs for which this definition applies
5393  * B num-cid number of cargo IDs (sprite group IDs) in this definition
5394  * can be zero, in that case the def-cid is used always
5395  * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5396  * W cid cargo ID (sprite group ID) for this type of cargo
5397  * W def-cid default cargo ID (sprite group ID) */
5398 
5399  uint8 feature = buf->ReadByte();
5400  uint8 idcount = buf->ReadByte();
5401 
5402  /* If idcount is zero, this is a feature callback */
5403  if (idcount == 0) {
5404  /* Skip number of cargo ids? */
5405  buf->ReadByte();
5406  uint16 groupid = buf->ReadWord();
5407  if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5408 
5409  grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5410 
5411  AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5412  return;
5413  }
5414 
5415  /* Mark the feature as used by the grf (generic callbacks do not count) */
5416  SetBit(_cur.grffile->grf_features, feature);
5417 
5418  grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5419 
5420  switch (feature) {
5421  case GSF_TRAINS:
5422  case GSF_ROADVEHICLES:
5423  case GSF_SHIPS:
5424  case GSF_AIRCRAFT:
5425  VehicleMapSpriteGroup(buf, feature, idcount);
5426  return;
5427 
5428  case GSF_CANALS:
5429  CanalMapSpriteGroup(buf, idcount);
5430  return;
5431 
5432  case GSF_STATIONS:
5433  StationMapSpriteGroup(buf, idcount);
5434  return;
5435 
5436  case GSF_HOUSES:
5437  TownHouseMapSpriteGroup(buf, idcount);
5438  return;
5439 
5440  case GSF_INDUSTRIES:
5441  IndustryMapSpriteGroup(buf, idcount);
5442  return;
5443 
5444  case GSF_INDUSTRYTILES:
5445  IndustrytileMapSpriteGroup(buf, idcount);
5446  return;
5447 
5448  case GSF_CARGOES:
5449  CargoMapSpriteGroup(buf, idcount);
5450  return;
5451 
5452  case GSF_AIRPORTS:
5453  AirportMapSpriteGroup(buf, idcount);
5454  return;
5455 
5456  case GSF_OBJECTS:
5457  ObjectMapSpriteGroup(buf, idcount);
5458  break;
5459 
5460  case GSF_RAILTYPES:
5461  RailTypeMapSpriteGroup(buf, idcount);
5462  break;
5463 
5464  case GSF_AIRPORTTILES:
5465  AirportTileMapSpriteGroup(buf, idcount);
5466  return;
5467 
5468  default:
5469  grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5470  return;
5471  }
5472 }
5473 
5474 /* Action 0x04 */
5475 static void FeatureNewName(ByteReader *buf)
5476 {
5477  /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5478  *
5479  * B veh-type see action 0 (as 00..07, + 0A
5480  * But IF veh-type = 48, then generic text
5481  * B language-id If bit 6 is set, This is the extended language scheme,
5482  * with up to 64 language.
5483  * Otherwise, it is a mapping where set bits have meaning
5484  * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5485  * Bit 7 set means this is a generic text, not a vehicle one (or else)
5486  * B num-veh number of vehicles which are getting a new name
5487  * B/W offset number of the first vehicle that gets a new name
5488  * Byte : ID of vehicle to change
5489  * Word : ID of string to change/add
5490  * S data new texts, each of them zero-terminated, after
5491  * which the next name begins. */
5492 
5493  bool new_scheme = _cur.grffile->grf_version >= 7;
5494 
5495  uint8 feature = buf->ReadByte();
5496  uint8 lang = buf->ReadByte();
5497  uint8 num = buf->ReadByte();
5498  bool generic = HasBit(lang, 7);
5499  uint16 id;
5500  if (generic) {
5501  id = buf->ReadWord();
5502  } else if (feature <= GSF_AIRCRAFT) {
5503  id = buf->ReadExtendedByte();
5504  } else {
5505  id = buf->ReadByte();
5506  }
5507 
5508  ClrBit(lang, 7);
5509 
5510  uint16 endid = id + num;
5511 
5512  grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5513  id, endid, feature, lang);
5514 
5515  for (; id < endid && buf->HasData(); id++) {
5516  const char *name = buf->ReadString();
5517  grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5518 
5519  switch (feature) {
5520  case GSF_TRAINS:
5521  case GSF_ROADVEHICLES:
5522  case GSF_SHIPS:
5523  case GSF_AIRCRAFT:
5524  if (!generic) {
5525  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5526  if (e == NULL) break;
5527  StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5528  e->info.string_id = string;
5529  } else {
5530  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5531  }
5532  break;
5533 
5534  default:
5535  if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5536  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5537  break;
5538  }
5539 
5540  switch (GB(id, 8, 8)) {
5541  case 0xC4: // Station class name
5542  if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5543  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5544  } else {
5545  StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5546  StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5547  }
5548  break;
5549 
5550  case 0xC5: // Station name
5551  if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5552  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5553  } else {
5554  _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5555  }
5556  break;
5557 
5558  case 0xC7: // Airporttile name
5559  if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5560  grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5561  } else {
5562  _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5563  }
5564  break;
5565 
5566  case 0xC9: // House name
5567  if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5568  grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5569  } else {
5570  _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5571  }
5572  break;
5573 
5574  default:
5575  grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5576  break;
5577  }
5578  break;
5579  }
5580  }
5581 }
5582 
5591 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5592 {
5593 
5594  if (offset >= max_sprites) {
5595  grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5596  uint orig_num = num;
5597  num = 0;
5598  return orig_num;
5599  }
5600 
5601  if (offset + num > max_sprites) {
5602  grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5603  uint orig_num = num;
5604  num = max(max_sprites - offset, 0);
5605  return orig_num - num;
5606  }
5607 
5608  return 0;
5609 }
5610 
5611 
5617 };
5619 struct Action5Type {
5622  uint16 min_sprites;
5623  uint16 max_sprites;
5624  const char *name;
5625 };
5626 
5628 static const Action5Type _action5_types[] = {
5629  /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5630  /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5631  /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5632  /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5633  /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5634  /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5635  /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5636  /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5637  /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5638  /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5639  /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5640  /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5641  /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5642  /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5643  /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5644  /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5645  /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5646  /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5647  /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5648  /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5649  /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5650  /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5651  /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5652  /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5653  /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5654  /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5655 };
5656 
5657 /* Action 0x05 */
5658 static void GraphicsNew(ByteReader *buf)
5659 {
5660  /* <05> <graphics-type> <num-sprites> <other data...>
5661  *
5662  * B graphics-type What set of graphics the sprites define.
5663  * E num-sprites How many sprites are in this set?
5664  * V other data Graphics type specific data. Currently unused. */
5665  /* TODO */
5666 
5667  uint8 type = buf->ReadByte();
5668  uint16 num = buf->ReadExtendedByte();
5669  uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5670  ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5671 
5672  if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5673  /* Special not-TTDP-compatible case used in openttd.grf
5674  * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5675  grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5676  LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5677  LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5678  LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5679  LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5680  LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5681  LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5682  LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5683  LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5684  LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5685  LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5686  if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5687  return;
5688  }
5689 
5690  /* Supported type? */
5691  if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5692  grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5693  _cur.skip_sprites = num;
5694  return;
5695  }
5696 
5697  const Action5Type *action5_type = &_action5_types[type];
5698 
5699  /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5700  * except for the long version of the shore type:
5701  * Ignore offset if not allowed */
5702  if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5703  grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5704  offset = 0;
5705  }
5706 
5707  /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5708  * This does not make sense, if <offset> is allowed */
5709  if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5710  grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
5711  _cur.skip_sprites = num;
5712  return;
5713  }
5714 
5715  /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5716  uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5717  SpriteID replace = action5_type->sprite_base + offset;
5718 
5719  /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5720  grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
5721 
5722  for (; num > 0; num--) {
5723  _cur.nfo_line++;
5724  LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5725  }
5726 
5727  if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5728 
5729  _cur.skip_sprites = skip_num;
5730 }
5731 
5732 /* Action 0x05 (SKIP) */
5733 static void SkipAct5(ByteReader *buf)
5734 {
5735  /* Ignore type byte */
5736  buf->ReadByte();
5737 
5738  /* Skip the sprites of this action */
5739  _cur.skip_sprites = buf->ReadExtendedByte();
5740 
5741  grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5742 }
5743 
5755 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5756 {
5757  switch (param) {
5758  case 0x00: // current date
5759  *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5760  return true;
5761 
5762  case 0x01: // current year
5764  return true;
5765 
5766  case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
5767  YearMonthDay ymd;
5768  ConvertDateToYMD(_date, &ymd);
5769  Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5770  *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5771  return true;
5772  }
5773 
5774  case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5776  return true;
5777 
5778  case 0x06: // road traffic side, bit 4 clear=left, set=right
5779  *value = _settings_game.vehicle.road_side << 4;
5780  return true;
5781 
5782  case 0x09: // date fraction
5783  *value = _date_fract * 885;
5784  return true;
5785 
5786  case 0x0A: // animation counter
5787  *value = _tick_counter;
5788  return true;
5789 
5790  case 0x0B: { // TTDPatch version
5791  uint major = 2;
5792  uint minor = 6;
5793  uint revision = 1; // special case: 2.0.1 is 2.0.10
5794  uint build = 1382;
5795  *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5796  return true;
5797  }
5798 
5799  case 0x0D: // TTD Version, 00=DOS, 01=Windows
5800  *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5801  return true;
5802 
5803  case 0x0E: // Y-offset for train sprites
5804  *value = _cur.grffile->traininfo_vehicle_pitch;
5805  return true;
5806 
5807  case 0x0F: // Rail track type cost factors
5808  *value = 0;
5809  SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5811  /* skip elrail multiplier - disabled */
5812  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5813  } else {
5814  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5815  /* Skip monorail multiplier - no space in result */
5816  }
5817  SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5818  return true;
5819 
5820  case 0x11: // current rail tool type
5821  *value = 0; // constant fake value to avoid desync
5822  return true;
5823 
5824  case 0x12: // Game mode
5825  *value = _game_mode;
5826  return true;
5827 
5828  /* case 0x13: // Tile refresh offset to left not implemented */
5829  /* case 0x14: // Tile refresh offset to right not implemented */
5830  /* case 0x15: // Tile refresh offset upwards not implemented */
5831  /* case 0x16: // Tile refresh offset downwards not implemented */
5832  /* case 0x17: // temperate snow line not implemented */
5833 
5834  case 0x1A: // Always -1
5835  *value = UINT_MAX;
5836  return true;
5837 
5838  case 0x1B: // Display options
5839  *value = 0x3F; // constant fake value to avoid desync
5840  return true;
5841 
5842  case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5843  *value = 1;
5844  return true;
5845 
5846  case 0x1E: // Miscellaneous GRF features
5847  *value = _misc_grf_features;
5848 
5849  /* Add the local flags */
5850  assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5851  if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5852  return true;
5853 
5854  /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5855 
5856  case 0x20: { // snow line height
5857  byte snowline = GetSnowLine();
5859  *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5860  } else {
5861  /* No snow */
5862  *value = 0xFF;
5863  }
5864  return true;
5865  }
5866 
5867  case 0x21: // OpenTTD version
5868  *value = _openttd_newgrf_version;
5869  return true;
5870 
5871  case 0x22: // difficulty level
5872  *value = SP_CUSTOM;
5873  return true;
5874 
5875  case 0x23: // long format date
5876  *value = _date;
5877  return true;
5878 
5879  case 0x24: // long format year
5880  *value = _cur_year;
5881  return true;
5882 
5883  default: return false;
5884  }
5885 }
5886 
5887 static uint32 GetParamVal(byte param, uint32 *cond_val)
5888 {
5889  /* First handle variable common with VarAction2 */
5890  uint32 value;
5891  if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5892 
5893  /* Non-common variable */
5894  switch (param) {
5895  case 0x84: { // GRF loading stage
5896  uint32 res = 0;
5897 
5898  if (_cur.stage > GLS_INIT) SetBit(res, 0);
5899  if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5900  if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5901  return res;
5902  }
5903 
5904  case 0x85: // TTDPatch flags, only for bit tests
5905  if (cond_val == NULL) {
5906  /* Supported in Action 0x07 and 0x09, not 0x0D */
5907  return 0;
5908  } else {
5909  uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5910  *cond_val %= 0x20;
5911  return param_val;
5912  }
5913 
5914  case 0x88: // GRF ID check
5915  return 0;
5916 
5917  /* case 0x99: Global ID offset not implemented */
5918 
5919  default:
5920  /* GRF Parameter */
5921  if (param < 0x80) return _cur.grffile->GetParam(param);
5922 
5923  /* In-game variable. */
5924  grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5925  return UINT_MAX;
5926  }
5927 }
5928 
5929 /* Action 0x06 */
5930 static void CfgApply(ByteReader *buf)
5931 {
5932  /* <06> <param-num> <param-size> <offset> ... <FF>
5933  *
5934  * B param-num Number of parameter to substitute (First = "zero")
5935  * Ignored if that parameter was not specified in newgrf.cfg
5936  * B param-size How many bytes to replace. If larger than 4, the
5937  * bytes of the following parameter are used. In that
5938  * case, nothing is applied unless *all* parameters
5939  * were specified.
5940  * B offset Offset into data from beginning of next sprite
5941  * to place where parameter is to be stored. */
5942 
5943  /* Preload the next sprite */
5944  size_t pos = FioGetPos();
5945  uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5946  uint8 type = FioReadByte();
5947  byte *preload_sprite = NULL;
5948 
5949  /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5950  if (type == 0xFF) {
5951  preload_sprite = MallocT<byte>(num);
5952  FioReadBlock(preload_sprite, num);
5953  }
5954 
5955  /* Reset the file position to the start of the next sprite */
5956  FioSeekTo(pos, SEEK_SET);
5957 
5958  if (type != 0xFF) {
5959  grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5960  free(preload_sprite);
5961  return;
5962  }
5963 
5964  GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5965  GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5966  if (it != _grf_line_to_action6_sprite_override.end()) {
5967  free(preload_sprite);
5968  preload_sprite = _grf_line_to_action6_sprite_override[location];
5969  } else {
5970  _grf_line_to_action6_sprite_override[location] = preload_sprite;
5971  }
5972 
5973  /* Now perform the Action 0x06 on our data. */
5974 
5975  for (;;) {
5976  uint i;
5977  uint param_num;
5978  uint param_size;
5979  uint offset;
5980  bool add_value;
5981 
5982  /* Read the parameter to apply. 0xFF indicates no more data to change. */
5983  param_num = buf->ReadByte();
5984  if (param_num == 0xFF) break;
5985 
5986  /* Get the size of the parameter to use. If the size covers multiple
5987  * double words, sequential parameter values are used. */
5988  param_size = buf->ReadByte();
5989 
5990  /* Bit 7 of param_size indicates we should add to the original value
5991  * instead of replacing it. */
5992  add_value = HasBit(param_size, 7);
5993  param_size = GB(param_size, 0, 7);
5994 
5995  /* Where to apply the data to within the pseudo sprite data. */
5996  offset = buf->ReadExtendedByte();
5997 
5998  /* If the parameter is a GRF parameter (not an internal variable) check
5999  * if it (and all further sequential parameters) has been defined. */
6000  if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6001  grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6002  break;
6003  }
6004 
6005  grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6006 
6007  bool carry = false;
6008  for (i = 0; i < param_size && offset + i < num; i++) {
6009  uint32 value = GetParamVal(param_num + i / 4, NULL);
6010  /* Reset carry flag for each iteration of the variable (only really
6011  * matters if param_size is greater than 4) */
6012  if (i % 4 == 0) carry = false;
6013 
6014  if (add_value) {
6015  uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6016  preload_sprite[offset + i] = GB(new_value, 0, 8);
6017  /* Check if the addition overflowed */
6018  carry = new_value >= 256;
6019  } else {
6020  preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6021  }
6022  }
6023  }
6024 }
6025 
6036 {
6037  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6038  error->data = stredup(_cur.grfconfig->GetName());
6039 }
6040 
6041 /* Action 0x07
6042  * Action 0x09 */
6043 static void SkipIf(ByteReader *buf)
6044 {
6045  /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6046  *
6047  * B param-num
6048  * B param-size
6049  * B condition-type
6050  * V value
6051  * B num-sprites */
6052  /* TODO: More params. More condition types. */
6053  uint32 cond_val = 0;
6054  uint32 mask = 0;
6055  bool result;
6056 
6057  uint8 param = buf->ReadByte();
6058  uint8 paramsize = buf->ReadByte();
6059  uint8 condtype = buf->ReadByte();
6060 
6061  if (condtype < 2) {
6062  /* Always 1 for bit tests, the given value should be ignored. */
6063  paramsize = 1;
6064  }
6065 
6066  switch (paramsize) {
6067  case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6068  case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6069  case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6070  case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6071  default: break;
6072  }
6073 
6074  if (param < 0x80 && _cur.grffile->param_end <= param) {
6075  grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6076  return;
6077  }
6078 
6079  uint32 param_val = GetParamVal(param, &cond_val);
6080 
6081  grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6082 
6083  /*
6084  * Parameter (variable in specs) 0x88 can only have GRF ID checking
6085  * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6086  * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6087  * So, when the condition type is one of those, the specific variable
6088  * 0x88 code is skipped, so the "general" code for the cargo
6089  * availability conditions kicks in.
6090  */
6091  if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6092  /* GRF ID checks */
6093 
6094  GRFConfig *c = GetGRFConfig(cond_val, mask);
6095 
6096  if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6098  c = NULL;
6099  }
6100 
6101  if (condtype != 10 && c == NULL) {
6102  grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6103  return;
6104  }
6105 
6106  switch (condtype) {
6107  /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6108  case 0x06: // Is GRFID active?
6109  result = c->status == GCS_ACTIVATED;
6110  break;
6111 
6112  case 0x07: // Is GRFID non-active?
6113  result = c->status != GCS_ACTIVATED;
6114  break;
6115 
6116  case 0x08: // GRFID is not but will be active?
6117  result = c->status == GCS_INITIALISED;
6118  break;
6119 
6120  case 0x09: // GRFID is or will be active?
6121  result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6122  break;
6123 
6124  case 0x0A: // GRFID is not nor will be active
6125  /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6126  result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6127  break;
6128 
6129  default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6130  }
6131  } else {
6132  /* Parameter or variable tests */
6133  switch (condtype) {
6134  case 0x00: result = !!(param_val & (1 << cond_val));
6135  break;
6136  case 0x01: result = !(param_val & (1 << cond_val));
6137  break;
6138  case 0x02: result = (param_val & mask) == cond_val;
6139  break;
6140  case 0x03: result = (param_val & mask) != cond_val;
6141  break;
6142  case 0x04: result = (param_val & mask) < cond_val;
6143  break;
6144  case 0x05: result = (param_val & mask) > cond_val;
6145  break;
6146  case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6147  break;
6148  case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6149  break;
6150  case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6151  break;
6152  case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6153  break;
6154 
6155  default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6156  }
6157  }
6158 
6159  if (!result) {
6160  grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6161  return;
6162  }
6163 
6164  uint8 numsprites = buf->ReadByte();
6165 
6166  /* numsprites can be a GOTO label if it has been defined in the GRF
6167  * file. The jump will always be the first matching label that follows
6168  * the current nfo_line. If no matching label is found, the first matching
6169  * label in the file is used. */
6170  GRFLabel *choice = NULL;
6171  for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6172  if (label->label != numsprites) continue;
6173 
6174  /* Remember a goto before the current line */
6175  if (choice == NULL) choice = label;
6176  /* If we find a label here, this is definitely good */
6177  if (label->nfo_line > _cur.nfo_line) {
6178  choice = label;
6179  break;
6180  }
6181  }
6182 
6183  if (choice != NULL) {
6184  grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6185  FioSeekTo(choice->pos, SEEK_SET);
6186  _cur.nfo_line = choice->nfo_line;
6187  return;
6188  }
6189 
6190  grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6191  _cur.skip_sprites = numsprites;
6192  if (_cur.skip_sprites == 0) {
6193  /* Zero means there are no sprites to skip, so
6194  * we use -1 to indicate that all further
6195  * sprites should be skipped. */
6196  _cur.skip_sprites = -1;
6197 
6198  /* If an action 8 hasn't been encountered yet, disable the grf. */
6199  if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6200  DisableGrf();
6201  }
6202  }
6203 }
6204 
6205 
6206 /* Action 0x08 (GLS_FILESCAN) */
6207 static void ScanInfo(ByteReader *buf)
6208 {
6209  uint8 grf_version = buf->ReadByte();
6210  uint32 grfid = buf->ReadDWord();
6211  const char *name = buf->ReadString();
6212 
6213  _cur.grfconfig->ident.grfid = grfid;
6214 
6215  if (grf_version < 2 || grf_version > 8) {
6217  DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
6218  }
6219 
6220  /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6221  if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6222 
6223  AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6224 
6225  if (buf->HasData()) {
6226  const char *info = buf->ReadString();
6227  AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6228  }
6229 
6230  /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6231  _cur.skip_sprites = -1;
6232 }
6233 
6234 /* Action 0x08 */
6235 static void GRFInfo(ByteReader *buf)
6236 {
6237  /* <08> <version> <grf-id> <name> <info>
6238  *
6239  * B version newgrf version, currently 06
6240  * 4*B grf-id globally unique ID of this .grf file
6241  * S name name of this .grf set
6242  * S info string describing the set, and e.g. author and copyright */
6243 
6244  uint8 version = buf->ReadByte();
6245  uint32 grfid = buf->ReadDWord();
6246  const char *name = buf->ReadString();
6247 
6248  if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6249  DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6250  return;
6251  }
6252 
6253  if (_cur.grffile->grfid != grfid) {
6254  DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
6255  _cur.grffile->grfid = grfid;
6256  }
6257 
6258  _cur.grffile->grf_version = version;
6259  _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6260 
6261  /* Do swap the GRFID for displaying purposes since people expect that */
6262  DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
6263 }
6264 
6265 /* Action 0x0A */
6266 static void SpriteReplace(ByteReader *buf)
6267 {
6268  /* <0A> <num-sets> <set1> [<set2> ...]
6269  * <set>: <num-sprites> <first-sprite>
6270  *
6271  * B num-sets How many sets of sprites to replace.
6272  * Each set:
6273  * B num-sprites How many sprites are in this set
6274  * W first-sprite First sprite number to replace */
6275 
6276  uint8 num_sets = buf->ReadByte();
6277 
6278  for (uint i = 0; i < num_sets; i++) {
6279  uint8 num_sprites = buf->ReadByte();
6280  uint16 first_sprite = buf->ReadWord();
6281 
<