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