Rework return statement in FlowsDown
[openttd/fttd.git] / src / newgrf.cpp
blob6cd72653694f8208e62599a83bbf0f4f4ba48826
1 /* $Id$ */
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 */
10 /** @file newgrf.cpp Base of all NewGRF support. */
12 #include "stdafx.h"
14 #include <stdarg.h>
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 #include "rail.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 /* TTDPatch extended GRF format codec
57 * (c) Petr Baudis 2004 (GPL'd)
58 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
60 * Contains portions of documentation by TTDPatch team.
61 * Thanks especially to Josef Drexler for the documentation as well as a lot
62 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
63 * served as subject to the initial testing of this codec. */
65 /** List of all loaded GRF files */
66 static SmallVector<GRFFile *, 16> _grf_files;
68 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
69 byte _misc_grf_features = 0;
71 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
72 static uint32 _ttdpatch_flags[8];
74 /** Indicates which are the newgrf features currently loaded ingame */
75 GRFLoadedFeatures _loaded_newgrf_features;
77 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
79 /** Temporary data during loading of GRFs */
80 struct GrfProcessingState {
81 private:
82 /** Definition of a single Action1 spriteset */
83 struct SpriteSet {
84 SpriteID sprite; ///< SpriteID of the first sprite of the set.
85 uint num_sprites; ///< Number of sprites in the set.
88 /** Currently referenceable spritesets */
89 std::map<uint, SpriteSet> spritesets[GSF_END];
91 public:
92 /* Global state */
93 GrfLoadingStage stage; ///< Current loading stage
94 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
96 /* Local state in the file */
97 uint file_index; ///< File index of currently processed GRF file.
98 GRFFile *grffile; ///< Currently processed GRF file.
99 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
100 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
101 byte grf_container_ver; ///< Container format of the current GRF file.
103 /* Kind of return values when processing certain actions */
104 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
106 /* Currently referenceable spritegroups */
107 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
109 /** Clear temporary data before processing the next file in the current loading stage */
110 void ClearDataForNextFile()
112 this->nfo_line = 0;
113 this->skip_sprites = 0;
115 for (uint i = 0; i < GSF_END; i++) {
116 this->spritesets[i].clear();
119 memset(this->spritegroups, 0, sizeof(this->spritegroups));
123 * Records new spritesets.
124 * @param feature GrfSpecFeature the set is defined for.
125 * @param first_sprite SpriteID of the first sprite in the set.
126 * @param first_set First spriteset to define.
127 * @param numsets Number of sets to define.
128 * @param numents Number of sprites per set to define.
130 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
132 assert(feature < GSF_END);
133 for (uint i = 0; i < numsets; i++) {
134 SpriteSet &set = this->spritesets[feature][first_set + i];
135 set.sprite = first_sprite + i * numents;
136 set.num_sprites = numents;
141 * Check whether there are any valid spritesets for a feature.
142 * @param feature GrfSpecFeature to check.
143 * @return true if there are any valid sets.
144 * @note Spritesets with zero sprites are valid to allow callback-failures.
146 bool HasValidSpriteSets(byte feature) const
148 assert(feature < GSF_END);
149 return !this->spritesets[feature].empty();
153 * Check whether a specific set is defined.
154 * @param feature GrfSpecFeature to check.
155 * @param set Set to check.
156 * @return true if the set is valid.
157 * @note Spritesets with zero sprites are valid to allow callback-failures.
159 bool IsValidSpriteSet(byte feature, uint set) const
161 assert(feature < GSF_END);
162 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
166 * Returns the first sprite of a spriteset.
167 * @param feature GrfSpecFeature to query.
168 * @param set Set to query.
169 * @return First sprite of the set.
171 SpriteID GetSprite(byte feature, uint set) const
173 assert(IsValidSpriteSet(feature, set));
174 return this->spritesets[feature].find(set)->second.sprite;
178 * Returns the number of sprites in a spriteset
179 * @param feature GrfSpecFeature to query.
180 * @param set Set to query.
181 * @return Number of sprites in the set.
183 uint GetNumEnts(byte feature, uint set) const
185 assert(IsValidSpriteSet(feature, set));
186 return this->spritesets[feature].find(set)->second.num_sprites;
190 static GrfProcessingState _cur;
194 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
195 * @param <T> The type of vehicle.
196 * @param image_index The image index to check.
197 * @return True iff the image index is valid, or 0xFD (use new graphics).
199 template <VehicleType T>
200 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
202 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
205 class OTTDByteReaderSignal { };
207 /** Class to read from a NewGRF file */
208 class ByteReader {
209 protected:
210 byte *data;
211 byte *end;
213 public:
214 ByteReader(byte *data, byte *end) : data(data), end(end) { }
216 inline byte ReadByte()
218 if (data < end) return *(data)++;
219 throw OTTDByteReaderSignal();
222 uint16 ReadWord()
224 uint16 val = ReadByte();
225 return val | (ReadByte() << 8);
228 uint16 ReadExtendedByte()
230 uint16 val = ReadByte();
231 return val == 0xFF ? ReadWord() : val;
234 uint32 ReadDWord()
236 uint32 val = ReadWord();
237 return val | (ReadWord() << 16);
240 uint32 ReadVarSize(byte size)
242 switch (size) {
243 case 1: return ReadByte();
244 case 2: return ReadWord();
245 case 4: return ReadDWord();
246 default:
247 NOT_REACHED();
248 return 0;
252 const char *ReadString()
254 char *string = reinterpret_cast<char *>(data);
255 size_t string_length = ttd_strnlen(string, Remaining());
257 if (string_length == Remaining()) {
258 /* String was not NUL terminated, so make sure it is now. */
259 string[string_length - 1] = '\0';
260 grfmsg(7, "String was not terminated with a zero byte.");
261 } else {
262 /* Increase the string length to include the NUL byte. */
263 string_length++;
265 Skip(string_length);
267 return string;
270 inline size_t Remaining() const
272 return end - data;
275 inline bool HasData(size_t count = 1) const
277 return data + count <= end;
280 inline byte *Data()
282 return data;
285 inline void Skip(size_t len)
287 data += len;
288 /* It is valid to move the buffer to exactly the end of the data,
289 * as there may not be any more data read. */
290 if (data > end) throw OTTDByteReaderSignal();
294 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
296 static const uint NUM_STATIONS_PER_GRF = 255; ///< Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on.
298 /** Temporary engine data used when loading only */
299 struct GRFTempEngineData {
300 /** Summary state of refittability properties */
301 enum Refittability {
302 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
303 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
304 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
307 uint16 cargo_allowed;
308 uint16 cargo_disallowed;
309 RailTypeLabel railtypelabel;
310 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
311 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
312 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
313 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
314 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
315 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
318 * Update the summary refittability on setting a refittability property.
319 * @param non_empty true if the GRF sets the vehicle to be refittable.
321 void UpdateRefittability(bool non_empty)
323 if (non_empty) {
324 this->refittability = NONEMPTY;
325 } else if (this->refittability == UNSET) {
326 this->refittability = EMPTY;
331 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
334 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
335 * GRM for vehicles is only used if dynamic engine allocation is disabled,
336 * so 256 is the number of original engines. */
337 static uint32 _grm_engines[256];
339 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
340 static uint32 _grm_cargoes[NUM_CARGO * 2];
342 struct GRFLocation {
343 uint32 grfid;
344 uint32 nfoline;
346 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
348 bool operator<(const GRFLocation &other) const
350 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
353 bool operator == (const GRFLocation &other) const
355 return this->grfid == other.grfid && this->nfoline == other.nfoline;
359 static std::map<GRFLocation, SpriteID> _grm_sprites;
360 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
361 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
364 * DEBUG() function dedicated to newGRF debugging messages
365 * Function is essentially the same as DEBUG(grf, severity, ...) with the
366 * addition of file:line information when parsing grf files.
367 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
368 * loading/parsing grf files, not for runtime debug messages as there
369 * is no file information available during that time.
370 * @param severity debugging severity level, see debug.h
371 * @param str message in printf() format
373 void CDECL grfmsg(int severity, const char *str, ...)
375 char buf[1024];
376 va_list va;
378 va_start(va, str);
379 vsnprintf(buf, sizeof(buf), str, va);
380 va_end(va);
382 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
386 * Obtain a NewGRF file by its grfID
387 * @param grfid The grfID to obtain the file for
388 * @return The file.
390 static GRFFile *GetFileByGRFID(uint32 grfid)
392 const GRFFile * const *end = _grf_files.End();
393 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
394 if ((*file)->grfid == grfid) return *file;
396 return NULL;
400 * Obtain a NewGRF file by its filename
401 * @param filename The filename to obtain the file for.
402 * @return The file.
404 static GRFFile *GetFileByFilename(const char *filename)
406 const GRFFile * const *end = _grf_files.End();
407 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
408 if (strcmp((*file)->filename, filename) == 0) return *file;
410 return NULL;
413 /** Reset all NewGRFData that was used only while processing data */
414 static void ClearTemporaryNewGRFData(GRFFile *gf)
416 /* Clear the GOTO labels used for GRF processing */
417 for (GRFLabel *l = gf->label; l != NULL;) {
418 GRFLabel *l2 = l->next;
419 free(l);
420 l = l2;
422 gf->label = NULL;
426 * Disable a GRF
427 * @param message Error message or STR_NULL.
428 * @param config GRFConfig to disable, NULL for current.
429 * @return Error message of the GRF for further customisation.
431 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
433 GRFFile *file;
434 if (config != NULL) {
435 file = GetFileByGRFID(config->ident.grfid);
436 } else {
437 config = _cur.grfconfig;
438 file = _cur.grffile;
441 config->status = GCS_DISABLED;
442 if (file != NULL) ClearTemporaryNewGRFData(file);
443 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
445 if (message != STR_NULL) {
446 delete config->error;
447 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
448 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
451 return config->error;
455 typedef std::map<StringID *, uint32> StringIDToGRFIDMapping;
456 static StringIDToGRFIDMapping _string_to_grf_mapping;
459 * Used when setting an object's property to map to the GRF's strings
460 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
461 * @param grfid Id of the grf file.
462 * @param str StringID that we want to have the equivalent in OoenTTD.
463 * @return The properly adjusted StringID.
465 StringID MapGRFStringID(uint32 grfid, StringID str)
467 /* 0xD0 and 0xDC stand for all the TextIDs in the range
468 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
469 * These strings are unique to each grf file, and thus require to be used with the
470 * grfid in which they are declared */
471 switch (GB(str, 8, 8)) {
472 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
473 case 0xDC:
474 return GetGRFStringID(grfid, str);
476 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
477 /* Strings embedded via 0x81 have 0x400 added to them (no real
478 * explanation why...) */
479 return GetGRFStringID(grfid, str - 0x400);
481 default: break;
484 return TTDPStringIDToOTTDStringIDMapping(str);
487 static std::map<uint32, uint32> _grf_id_overrides;
490 * Set the override for a NewGRF
491 * @param source_grfid The grfID which wants to override another NewGRF.
492 * @param target_grfid The grfID which is being overridden.
494 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
496 _grf_id_overrides[source_grfid] = target_grfid;
497 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
501 * Returns the engine associated to a certain internal_id, resp. allocates it.
502 * @param file NewGRF that wants to change the engine.
503 * @param type Vehicle type.
504 * @param internal_id Engine ID inside the NewGRF.
505 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
506 * @return The requested engine.
508 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
510 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
511 * them use the same engine slots. */
512 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
513 if (_settings_game.vehicle.dynamic_engines) {
514 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
515 scope_grfid = file->grfid;
516 uint32 override = _grf_id_overrides[file->grfid];
517 if (override != 0) {
518 scope_grfid = override;
519 const GRFFile *grf_match = GetFileByGRFID(override);
520 if (grf_match == NULL) {
521 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
522 } else {
523 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
527 /* Check if the engine is registered in the override manager */
528 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
529 if (engine != INVALID_ENGINE) {
530 Engine *e = Engine::Get(engine);
531 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
532 return e;
536 /* Check if there is an unreserved slot */
537 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
538 if (engine != INVALID_ENGINE) {
539 Engine *e = Engine::Get(engine);
541 if (e->grf_prop.grffile == NULL) {
542 e->grf_prop.grffile = file;
543 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
546 /* Reserve the engine slot */
547 if (!static_access) {
548 EngineIDMapping *eid = _engine_mngr.Get(engine);
549 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
552 return e;
555 if (static_access) return NULL;
557 if (!Engine::CanAllocateItem()) {
558 grfmsg(0, "Can't allocate any more engines");
559 return NULL;
562 size_t engine_pool_size = Engine::GetPoolSize();
564 /* ... it's not, so create a new one based off an existing engine */
565 Engine *e = new Engine(type, internal_id);
566 e->grf_prop.grffile = file;
568 /* Reserve the engine slot */
569 assert(_engine_mngr.Length() == e->index);
570 EngineIDMapping *eid = _engine_mngr.Append();
571 eid->type = type;
572 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
573 eid->internal_id = internal_id;
574 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
576 if (engine_pool_size != Engine::GetPoolSize()) {
577 /* Resize temporary engine data ... */
578 _gted = ReallocT(_gted, Engine::GetPoolSize());
580 /* and blank the new block. */
581 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
582 memset(_gted + engine_pool_size, 0, len);
584 if (type == VEH_TRAIN) {
585 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
588 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
590 return e;
594 * Return the ID of a new engine
595 * @param file The NewGRF file providing the engine.
596 * @param type The Vehicle type.
597 * @param internal_id NewGRF-internal ID of the engine.
598 * @return The new EngineID.
599 * @note depending on the dynamic_engine setting and a possible override
600 * property the grfID may be unique or overwriting or partially re-defining
601 * properties of an existing engine.
603 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
605 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
606 if (_settings_game.vehicle.dynamic_engines) {
607 scope_grfid = file->grfid;
608 uint32 override = _grf_id_overrides[file->grfid];
609 if (override != 0) scope_grfid = override;
612 return _engine_mngr.GetID(type, internal_id, scope_grfid);
616 * Map the colour modifiers of TTDPatch to those that Open is using.
617 * @param grf_sprite Pointer to the structure been modified.
619 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
621 if (HasBit(grf_sprite->pal, 14)) {
622 ClrBit(grf_sprite->pal, 14);
623 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
626 if (HasBit(grf_sprite->sprite, 14)) {
627 ClrBit(grf_sprite->sprite, 14);
628 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
631 if (HasBit(grf_sprite->sprite, 15)) {
632 ClrBit(grf_sprite->sprite, 15);
633 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
638 * Read a sprite and a palette from the GRF and convert them into a format
639 * suitable to OpenTTD.
640 * @param buf Input stream.
641 * @param read_flags Whether to read TileLayoutFlags.
642 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
643 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
644 * @param feature GrfSpecFeature to use spritesets from.
645 * @param [out] grf_sprite Read sprite and palette.
646 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
647 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
648 * @return Read TileLayoutFlags.
650 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)
652 grf_sprite->sprite = buf->ReadWord();
653 grf_sprite->pal = buf->ReadWord();
654 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
656 MapSpriteMappingRecolour(grf_sprite);
658 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
659 ClrBit(grf_sprite->pal, 15);
660 if (custom_sprite) {
661 /* Use sprite from Action 1 */
662 uint index = GB(grf_sprite->sprite, 0, 14);
663 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
664 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
665 grf_sprite->sprite = SPR_IMG_QUERY;
666 grf_sprite->pal = PAL_NONE;
667 } else {
668 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
669 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
670 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
671 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
673 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
674 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
675 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
676 return flags;
679 if (flags & TLF_CUSTOM_PALETTE) {
680 /* Use palette from Action 1 */
681 uint index = GB(grf_sprite->pal, 0, 14);
682 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
683 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
684 grf_sprite->pal = PAL_NONE;
685 } else {
686 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
687 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
688 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
689 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
691 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
692 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
693 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
694 return flags;
697 return flags;
701 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
702 * @param buf Input stream.
703 * @param flags TileLayoutFlags to process.
704 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
705 * @param dts Sprite layout to insert data into.
706 * @param index Sprite index to process; 0 for ground sprite.
708 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
710 if (!(flags & TLF_DRAWING_FLAGS)) return;
712 if (dts->registers == NULL) dts->AllocateRegisters();
713 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
714 regs.flags = flags & TLF_DRAWING_FLAGS;
716 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
717 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
718 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
720 if (is_parent) {
721 if (flags & TLF_BB_XY_OFFSET) {
722 regs.delta.parent[0] = buf->ReadByte();
723 regs.delta.parent[1] = buf->ReadByte();
725 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
726 } else {
727 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
728 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
731 if (flags & TLF_SPRITE_VAR10) {
732 regs.sprite_var10 = buf->ReadByte();
733 if (regs.sprite_var10 > TLR_MAX_VAR10) {
734 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
735 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
736 return;
740 if (flags & TLF_PALETTE_VAR10) {
741 regs.palette_var10 = buf->ReadByte();
742 if (regs.palette_var10 > TLR_MAX_VAR10) {
743 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
744 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
745 return;
751 * Read a spritelayout from the GRF.
752 * @param buf Input
753 * @param num_building_sprites Number of building sprites to read
754 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
755 * @param feature GrfSpecFeature to use spritesets from.
756 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
757 * @param no_z_position Whether bounding boxes have no Z offset
758 * @param dts Layout container to output into
759 * @return True on error (GRF was disabled).
761 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
763 bool has_flags = HasBit(num_building_sprites, 6);
764 ClrBit(num_building_sprites, 6);
765 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
766 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
767 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
769 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
770 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
771 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
772 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
774 /* Groundsprite */
775 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
776 if (_cur.skip_sprites < 0) return true;
778 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
779 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
780 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
781 return true;
784 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
785 if (_cur.skip_sprites < 0) return true;
787 for (uint i = 0; i < num_building_sprites; i++) {
788 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
790 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
791 if (_cur.skip_sprites < 0) return true;
793 if (flags & ~valid_flags) {
794 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
795 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
796 return true;
799 seq->delta_x = buf->ReadByte();
800 seq->delta_y = buf->ReadByte();
802 if (!no_z_position) seq->delta_z = buf->ReadByte();
804 if (seq->IsParentSprite()) {
805 seq->size_x = buf->ReadByte();
806 seq->size_y = buf->ReadByte();
807 seq->size_z = buf->ReadByte();
810 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
811 if (_cur.skip_sprites < 0) return true;
814 /* Check if the number of sprites per spriteset is consistent */
815 bool is_consistent = true;
816 dts->consistent_max_offset = 0;
817 for (uint i = 0; i < num_building_sprites + 1; i++) {
818 if (max_sprite_offset[i] > 0) {
819 if (dts->consistent_max_offset == 0) {
820 dts->consistent_max_offset = max_sprite_offset[i];
821 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
822 is_consistent = false;
823 break;
826 if (max_palette_offset[i] > 0) {
827 if (dts->consistent_max_offset == 0) {
828 dts->consistent_max_offset = max_palette_offset[i];
829 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
830 is_consistent = false;
831 break;
836 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
837 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
839 if (!is_consistent || dts->registers != NULL) {
840 dts->consistent_max_offset = 0;
841 if (dts->registers == NULL) dts->AllocateRegisters();
843 for (uint i = 0; i < num_building_sprites + 1; i++) {
844 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
845 regs.max_sprite_offset = max_sprite_offset[i];
846 regs.max_palette_offset = max_palette_offset[i];
850 return false;
854 * Translate the refit mask.
856 static uint32 TranslateRefitMask(uint32 refit_mask)
858 uint32 result = 0;
859 uint8 bit;
860 FOR_EACH_SET_BIT(bit, refit_mask) {
861 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
862 if (cargo != CT_INVALID) SetBit(result, cargo);
864 return result;
868 * Converts TTD(P) Base Price pointers into the enum used by OTTD
869 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
870 * @param base_pointer TTD(P) Base Price Pointer
871 * @param error_location Function name for grf error messages
872 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
874 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
876 /* Special value for 'none' */
877 if (base_pointer == 0) {
878 *index = INVALID_PRICE;
879 return;
882 static const uint32 start = 0x4B34; ///< Position of first base price
883 static const uint32 size = 6; ///< Size of each base price record
885 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
886 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
887 return;
890 *index = (Price)((base_pointer - start) / size);
893 /** Possible return values for the FeatureChangeInfo functions */
894 enum ChangeInfoResult {
895 CIR_SUCCESS, ///< Variable was parsed and read
896 CIR_DISABLED, ///< GRF was disabled due to error
897 CIR_UNHANDLED, ///< Variable was parsed but unread
898 CIR_UNKNOWN, ///< Variable is unknown
899 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
902 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
905 * Define properties common to all vehicles
906 * @param ei Engine info.
907 * @param prop The property to change.
908 * @param buf The property value.
909 * @return ChangeInfoResult.
911 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
913 switch (prop) {
914 case 0x00: // Introduction date
915 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
916 break;
918 case 0x02: // Decay speed
919 ei->decay_speed = buf->ReadByte();
920 break;
922 case 0x03: // Vehicle life
923 ei->lifelength = buf->ReadByte();
924 break;
926 case 0x04: // Model life
927 ei->base_life = buf->ReadByte();
928 break;
930 case 0x06: // Climates available
931 ei->climates = buf->ReadByte();
932 break;
934 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
935 /* Amount of cargo loaded during a vehicle's "loading tick" */
936 ei->load_amount = buf->ReadByte();
937 break;
939 default:
940 return CIR_UNKNOWN;
943 return CIR_SUCCESS;
947 * Define properties for rail vehicles
948 * @param engine :ocal ID of the first vehicle.
949 * @param numinfo Number of subsequent IDs to change the property for.
950 * @param prop The property to change.
951 * @param buf The property value.
952 * @return ChangeInfoResult.
954 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
956 ChangeInfoResult ret = CIR_SUCCESS;
958 for (int i = 0; i < numinfo; i++) {
959 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
960 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
962 EngineInfo *ei = &e->info;
963 RailVehicleInfo *rvi = &e->u.rail;
965 switch (prop) {
966 case 0x05: { // Track type
967 uint8 tracktype = buf->ReadByte();
969 if (tracktype < _cur.grffile->railtype_list.Length()) {
970 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
971 break;
974 switch (tracktype) {
975 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
976 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
977 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
978 default:
979 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
980 break;
982 break;
985 case 0x08: // AI passenger service
986 /* Tells the AI that this engine is designed for
987 * passenger services and shouldn't be used for freight. */
988 rvi->ai_passenger_only = buf->ReadByte();
989 break;
991 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
992 uint16 speed = buf->ReadWord();
993 if (speed == 0xFFFF) speed = 0;
995 rvi->max_speed = speed;
996 break;
999 case PROP_TRAIN_POWER: // 0x0B Power
1000 rvi->power = buf->ReadWord();
1002 /* Set engine / wagon state based on power */
1003 if (rvi->power != 0) {
1004 if (rvi->railveh_type == RAILVEH_WAGON) {
1005 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1007 } else {
1008 rvi->railveh_type = RAILVEH_WAGON;
1010 break;
1012 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1013 rvi->running_cost = buf->ReadByte();
1014 break;
1016 case 0x0E: // Running cost base
1017 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1018 break;
1020 case 0x12: { // Sprite ID
1021 uint8 spriteid = buf->ReadByte();
1022 uint8 orig_spriteid = spriteid;
1024 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1025 * as an array index, so we need it to be half the original value. */
1026 if (spriteid < 0xFD) spriteid >>= 1;
1028 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1029 rvi->image_index = spriteid;
1030 } else {
1031 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1032 rvi->image_index = 0;
1034 break;
1037 case 0x13: { // Dual-headed
1038 uint8 dual = buf->ReadByte();
1040 if (dual != 0) {
1041 rvi->railveh_type = RAILVEH_MULTIHEAD;
1042 } else {
1043 rvi->railveh_type = rvi->power == 0 ?
1044 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1046 break;
1049 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1050 rvi->capacity = buf->ReadByte();
1051 break;
1053 case 0x15: { // Cargo type
1054 _gted[e->index].defaultcargo_grf = _cur.grffile;
1055 uint8 ctype = buf->ReadByte();
1057 if (ctype == 0xFF) {
1058 /* 0xFF is specified as 'use first refittable' */
1059 ei->cargo_type = CT_INVALID;
1060 } else if (_cur.grffile->grf_version >= 8) {
1061 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1062 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1063 } else if (ctype < NUM_CARGO) {
1064 /* Use untranslated cargo. */
1065 ei->cargo_type = ctype;
1066 } else {
1067 ei->cargo_type = CT_INVALID;
1068 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1070 break;
1073 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1074 SB(rvi->weight, 0, 8, buf->ReadByte());
1075 break;
1077 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1078 rvi->cost_factor = buf->ReadByte();
1079 break;
1081 case 0x18: // AI rank
1082 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1083 buf->ReadByte();
1084 break;
1086 case 0x19: { // Engine traction type
1087 /* What do the individual numbers mean?
1088 * 0x00 .. 0x07: Steam
1089 * 0x08 .. 0x27: Diesel
1090 * 0x28 .. 0x31: Electric
1091 * 0x32 .. 0x37: Monorail
1092 * 0x38 .. 0x41: Maglev
1094 uint8 traction = buf->ReadByte();
1095 EngineClass engclass;
1097 if (traction <= 0x07) {
1098 engclass = EC_STEAM;
1099 } else if (traction <= 0x27) {
1100 engclass = EC_DIESEL;
1101 } else if (traction <= 0x31) {
1102 engclass = EC_ELECTRIC;
1103 } else if (traction <= 0x37) {
1104 engclass = EC_MONORAIL;
1105 } else if (traction <= 0x41) {
1106 engclass = EC_MAGLEV;
1107 } else {
1108 break;
1111 if (_cur.grffile->railtype_list.Length() == 0) {
1112 /* Use traction type to select between normal and electrified
1113 * rail only when no translation list is in place. */
1114 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1115 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1118 rvi->engclass = engclass;
1119 break;
1122 case 0x1A: // Alter purchase list sort order
1123 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1124 break;
1126 case 0x1B: // Powered wagons power bonus
1127 rvi->pow_wag_power = buf->ReadWord();
1128 break;
1130 case 0x1C: // Refit cost
1131 ei->refit_cost = buf->ReadByte();
1132 break;
1134 case 0x1D: { // Refit cargo
1135 uint32 mask = buf->ReadDWord();
1136 _gted[e->index].UpdateRefittability(mask != 0);
1137 ei->refit_mask = TranslateRefitMask(mask);
1138 _gted[e->index].defaultcargo_grf = _cur.grffile;
1139 break;
1142 case 0x1E: // Callback
1143 ei->callback_mask = buf->ReadByte();
1144 break;
1146 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1147 rvi->tractive_effort = buf->ReadByte();
1148 break;
1150 case 0x20: // Air drag
1151 rvi->air_drag = buf->ReadByte();
1152 break;
1154 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1155 rvi->shorten_factor = buf->ReadByte();
1156 break;
1158 case 0x22: // Visual effect
1159 rvi->visual_effect = buf->ReadByte();
1160 /* Avoid accidentally setting visual_effect to the default value
1161 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1162 if (rvi->visual_effect == VE_DEFAULT) {
1163 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1164 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1166 break;
1168 case 0x23: // Powered wagons weight bonus
1169 rvi->pow_wag_weight = buf->ReadByte();
1170 break;
1172 case 0x24: { // High byte of vehicle weight
1173 byte weight = buf->ReadByte();
1175 if (weight > 4) {
1176 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1177 } else {
1178 SB(rvi->weight, 8, 8, weight);
1180 break;
1183 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1184 rvi->user_def_data = buf->ReadByte();
1185 break;
1187 case 0x26: // Retire vehicle early
1188 ei->retire_early = buf->ReadByte();
1189 break;
1191 case 0x27: // Miscellaneous flags
1192 ei->misc_flags = buf->ReadByte();
1193 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1194 _gted[e->index].prop27_set = true;
1195 break;
1197 case 0x28: // Cargo classes allowed
1198 _gted[e->index].cargo_allowed = buf->ReadWord();
1199 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1200 _gted[e->index].defaultcargo_grf = _cur.grffile;
1201 break;
1203 case 0x29: // Cargo classes disallowed
1204 _gted[e->index].cargo_disallowed = buf->ReadWord();
1205 _gted[e->index].UpdateRefittability(false);
1206 break;
1208 case 0x2A: // Long format introduction date (days since year 0)
1209 ei->base_intro = buf->ReadDWord();
1210 break;
1212 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1213 ei->cargo_age_period = buf->ReadWord();
1214 break;
1216 case 0x2C: // CTT refit include list
1217 case 0x2D: { // CTT refit exclude list
1218 uint8 count = buf->ReadByte();
1219 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1220 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1221 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1222 ctt = 0;
1223 while (count--) {
1224 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1225 if (ctype == CT_INVALID) continue;
1226 SetBit(ctt, ctype);
1228 break;
1231 default:
1232 ret = CommonVehicleChangeInfo(ei, prop, buf);
1233 break;
1237 return ret;
1241 * Define properties for road vehicles
1242 * @param engine Local ID of the first vehicle.
1243 * @param numinfo Number of subsequent IDs to change the property for.
1244 * @param prop The property to change.
1245 * @param buf The property value.
1246 * @return ChangeInfoResult.
1248 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1250 ChangeInfoResult ret = CIR_SUCCESS;
1252 for (int i = 0; i < numinfo; i++) {
1253 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1254 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1256 EngineInfo *ei = &e->info;
1257 RoadVehicleInfo *rvi = &e->u.road;
1259 switch (prop) {
1260 case 0x08: // Speed (1 unit is 0.5 kmh)
1261 rvi->max_speed = buf->ReadByte();
1262 break;
1264 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1265 rvi->running_cost = buf->ReadByte();
1266 break;
1268 case 0x0A: // Running cost base
1269 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1270 break;
1272 case 0x0E: { // Sprite ID
1273 uint8 spriteid = buf->ReadByte();
1274 uint8 orig_spriteid = spriteid;
1276 /* cars have different custom id in the GRF file */
1277 if (spriteid == 0xFF) spriteid = 0xFD;
1279 if (spriteid < 0xFD) spriteid >>= 1;
1281 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1282 rvi->image_index = spriteid;
1283 } else {
1284 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1285 rvi->image_index = 0;
1287 break;
1290 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1291 rvi->capacity = buf->ReadByte();
1292 break;
1294 case 0x10: { // Cargo type
1295 _gted[e->index].defaultcargo_grf = _cur.grffile;
1296 uint8 ctype = buf->ReadByte();
1298 if (ctype == 0xFF) {
1299 /* 0xFF is specified as 'use first refittable' */
1300 ei->cargo_type = CT_INVALID;
1301 } else if (_cur.grffile->grf_version >= 8) {
1302 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1303 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1304 } else if (ctype < NUM_CARGO) {
1305 /* Use untranslated cargo. */
1306 ei->cargo_type = ctype;
1307 } else {
1308 ei->cargo_type = CT_INVALID;
1309 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1311 break;
1314 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1315 rvi->cost_factor = buf->ReadByte();
1316 break;
1318 case 0x12: // SFX
1319 rvi->sfx = buf->ReadByte();
1320 break;
1322 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1323 rvi->power = buf->ReadByte();
1324 break;
1326 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1327 rvi->weight = buf->ReadByte();
1328 break;
1330 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1331 _gted[e->index].rv_max_speed = buf->ReadByte();
1332 break;
1334 case 0x16: { // Cargoes available for refitting
1335 uint32 mask = buf->ReadDWord();
1336 _gted[e->index].UpdateRefittability(mask != 0);
1337 ei->refit_mask = TranslateRefitMask(mask);
1338 _gted[e->index].defaultcargo_grf = _cur.grffile;
1339 break;
1342 case 0x17: // Callback mask
1343 ei->callback_mask = buf->ReadByte();
1344 break;
1346 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1347 rvi->tractive_effort = buf->ReadByte();
1348 break;
1350 case 0x19: // Air drag
1351 rvi->air_drag = buf->ReadByte();
1352 break;
1354 case 0x1A: // Refit cost
1355 ei->refit_cost = buf->ReadByte();
1356 break;
1358 case 0x1B: // Retire vehicle early
1359 ei->retire_early = buf->ReadByte();
1360 break;
1362 case 0x1C: // Miscellaneous flags
1363 ei->misc_flags = buf->ReadByte();
1364 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1365 break;
1367 case 0x1D: // Cargo classes allowed
1368 _gted[e->index].cargo_allowed = buf->ReadWord();
1369 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1370 _gted[e->index].defaultcargo_grf = _cur.grffile;
1371 break;
1373 case 0x1E: // Cargo classes disallowed
1374 _gted[e->index].cargo_disallowed = buf->ReadWord();
1375 _gted[e->index].UpdateRefittability(false);
1376 break;
1378 case 0x1F: // Long format introduction date (days since year 0)
1379 ei->base_intro = buf->ReadDWord();
1380 break;
1382 case 0x20: // Alter purchase list sort order
1383 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1384 break;
1386 case 0x21: // Visual effect
1387 rvi->visual_effect = buf->ReadByte();
1388 /* Avoid accidentally setting visual_effect to the default value
1389 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1390 if (rvi->visual_effect == VE_DEFAULT) {
1391 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1392 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1394 break;
1396 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1397 ei->cargo_age_period = buf->ReadWord();
1398 break;
1400 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1401 rvi->shorten_factor = buf->ReadByte();
1402 break;
1404 case 0x24: // CTT refit include list
1405 case 0x25: { // CTT refit exclude list
1406 uint8 count = buf->ReadByte();
1407 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1408 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1409 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1410 ctt = 0;
1411 while (count--) {
1412 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1413 if (ctype == CT_INVALID) continue;
1414 SetBit(ctt, ctype);
1416 break;
1419 default:
1420 ret = CommonVehicleChangeInfo(ei, prop, buf);
1421 break;
1425 return ret;
1429 * Define properties for ships
1430 * @param engine Local ID of the first vehicle.
1431 * @param numinfo Number of subsequent IDs to change the property for.
1432 * @param prop The property to change.
1433 * @param buf The property value.
1434 * @return ChangeInfoResult.
1436 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1438 ChangeInfoResult ret = CIR_SUCCESS;
1440 for (int i = 0; i < numinfo; i++) {
1441 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1442 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1444 EngineInfo *ei = &e->info;
1445 ShipVehicleInfo *svi = &e->u.ship;
1447 switch (prop) {
1448 case 0x08: { // Sprite ID
1449 uint8 spriteid = buf->ReadByte();
1450 uint8 orig_spriteid = spriteid;
1452 /* ships have different custom id in the GRF file */
1453 if (spriteid == 0xFF) spriteid = 0xFD;
1455 if (spriteid < 0xFD) spriteid >>= 1;
1457 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1458 svi->image_index = spriteid;
1459 } else {
1460 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1461 svi->image_index = 0;
1463 break;
1466 case 0x09: // Refittable
1467 svi->old_refittable = (buf->ReadByte() != 0);
1468 break;
1470 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1471 svi->cost_factor = buf->ReadByte();
1472 break;
1474 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1475 svi->max_speed = buf->ReadByte();
1476 break;
1478 case 0x0C: { // Cargo type
1479 _gted[e->index].defaultcargo_grf = _cur.grffile;
1480 uint8 ctype = buf->ReadByte();
1482 if (ctype == 0xFF) {
1483 /* 0xFF is specified as 'use first refittable' */
1484 ei->cargo_type = CT_INVALID;
1485 } else if (_cur.grffile->grf_version >= 8) {
1486 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1487 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1488 } else if (ctype < NUM_CARGO) {
1489 /* Use untranslated cargo. */
1490 ei->cargo_type = ctype;
1491 } else {
1492 ei->cargo_type = CT_INVALID;
1493 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1495 break;
1498 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1499 svi->capacity = buf->ReadWord();
1500 break;
1502 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1503 svi->running_cost = buf->ReadByte();
1504 break;
1506 case 0x10: // SFX
1507 svi->sfx = buf->ReadByte();
1508 break;
1510 case 0x11: { // Cargoes available for refitting
1511 uint32 mask = buf->ReadDWord();
1512 _gted[e->index].UpdateRefittability(mask != 0);
1513 ei->refit_mask = TranslateRefitMask(mask);
1514 _gted[e->index].defaultcargo_grf = _cur.grffile;
1515 break;
1518 case 0x12: // Callback mask
1519 ei->callback_mask = buf->ReadByte();
1520 break;
1522 case 0x13: // Refit cost
1523 ei->refit_cost = buf->ReadByte();
1524 break;
1526 case 0x14: // Ocean speed fraction
1527 svi->ocean_speed_frac = buf->ReadByte();
1528 break;
1530 case 0x15: // Canal speed fraction
1531 svi->canal_speed_frac = buf->ReadByte();
1532 break;
1534 case 0x16: // Retire vehicle early
1535 ei->retire_early = buf->ReadByte();
1536 break;
1538 case 0x17: // Miscellaneous flags
1539 ei->misc_flags = buf->ReadByte();
1540 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1541 break;
1543 case 0x18: // Cargo classes allowed
1544 _gted[e->index].cargo_allowed = buf->ReadWord();
1545 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1546 _gted[e->index].defaultcargo_grf = _cur.grffile;
1547 break;
1549 case 0x19: // Cargo classes disallowed
1550 _gted[e->index].cargo_disallowed = buf->ReadWord();
1551 _gted[e->index].UpdateRefittability(false);
1552 break;
1554 case 0x1A: // Long format introduction date (days since year 0)
1555 ei->base_intro = buf->ReadDWord();
1556 break;
1558 case 0x1B: // Alter purchase list sort order
1559 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1560 break;
1562 case 0x1C: // Visual effect
1563 svi->visual_effect = buf->ReadByte();
1564 /* Avoid accidentally setting visual_effect to the default value
1565 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1566 if (svi->visual_effect == VE_DEFAULT) {
1567 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1568 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1570 break;
1572 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1573 ei->cargo_age_period = buf->ReadWord();
1574 break;
1576 case 0x1E: // CTT refit include list
1577 case 0x1F: { // CTT refit exclude list
1578 uint8 count = buf->ReadByte();
1579 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1580 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1581 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1582 ctt = 0;
1583 while (count--) {
1584 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1585 if (ctype == CT_INVALID) continue;
1586 SetBit(ctt, ctype);
1588 break;
1591 default:
1592 ret = CommonVehicleChangeInfo(ei, prop, buf);
1593 break;
1597 return ret;
1601 * Define properties for aircraft
1602 * @param engine Local ID of the aircraft.
1603 * @param numinfo Number of subsequent IDs to change the property for.
1604 * @param prop The property to change.
1605 * @param buf The property value.
1606 * @return ChangeInfoResult.
1608 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1610 ChangeInfoResult ret = CIR_SUCCESS;
1612 for (int i = 0; i < numinfo; i++) {
1613 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1614 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1616 EngineInfo *ei = &e->info;
1617 AircraftVehicleInfo *avi = &e->u.air;
1619 switch (prop) {
1620 case 0x08: { // Sprite ID
1621 uint8 spriteid = buf->ReadByte();
1622 uint8 orig_spriteid = spriteid;
1624 /* aircraft have different custom id in the GRF file */
1625 if (spriteid == 0xFF) spriteid = 0xFD;
1627 if (spriteid < 0xFD) spriteid >>= 1;
1629 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1630 avi->image_index = spriteid;
1631 } else {
1632 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1633 avi->image_index = 0;
1635 break;
1638 case 0x09: // Helicopter
1639 if (buf->ReadByte() == 0) {
1640 avi->subtype = AIR_HELI;
1641 } else {
1642 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1644 break;
1646 case 0x0A: // Large
1647 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1648 break;
1650 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1651 avi->cost_factor = buf->ReadByte();
1652 break;
1654 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1655 avi->max_speed = (buf->ReadByte() * 128) / 10;
1656 break;
1658 case 0x0D: // Acceleration
1659 avi->acceleration = buf->ReadByte();
1660 break;
1662 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1663 avi->running_cost = buf->ReadByte();
1664 break;
1666 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1667 avi->passenger_capacity = buf->ReadWord();
1668 break;
1670 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1671 avi->mail_capacity = buf->ReadByte();
1672 break;
1674 case 0x12: // SFX
1675 avi->sfx = buf->ReadByte();
1676 break;
1678 case 0x13: { // Cargoes available for refitting
1679 uint32 mask = buf->ReadDWord();
1680 _gted[e->index].UpdateRefittability(mask != 0);
1681 ei->refit_mask = TranslateRefitMask(mask);
1682 _gted[e->index].defaultcargo_grf = _cur.grffile;
1683 break;
1686 case 0x14: // Callback mask
1687 ei->callback_mask = buf->ReadByte();
1688 break;
1690 case 0x15: // Refit cost
1691 ei->refit_cost = buf->ReadByte();
1692 break;
1694 case 0x16: // Retire vehicle early
1695 ei->retire_early = buf->ReadByte();
1696 break;
1698 case 0x17: // Miscellaneous flags
1699 ei->misc_flags = buf->ReadByte();
1700 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1701 break;
1703 case 0x18: // Cargo classes allowed
1704 _gted[e->index].cargo_allowed = buf->ReadWord();
1705 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1706 _gted[e->index].defaultcargo_grf = _cur.grffile;
1707 break;
1709 case 0x19: // Cargo classes disallowed
1710 _gted[e->index].cargo_disallowed = buf->ReadWord();
1711 _gted[e->index].UpdateRefittability(false);
1712 break;
1714 case 0x1A: // Long format introduction date (days since year 0)
1715 ei->base_intro = buf->ReadDWord();
1716 break;
1718 case 0x1B: // Alter purchase list sort order
1719 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1720 break;
1722 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1723 ei->cargo_age_period = buf->ReadWord();
1724 break;
1726 case 0x1D: // CTT refit include list
1727 case 0x1E: { // CTT refit exclude list
1728 uint8 count = buf->ReadByte();
1729 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1730 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1731 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1732 ctt = 0;
1733 while (count--) {
1734 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1735 if (ctype == CT_INVALID) continue;
1736 SetBit(ctt, ctype);
1738 break;
1741 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1742 avi->max_range = buf->ReadWord();
1743 break;
1745 default:
1746 ret = CommonVehicleChangeInfo(ei, prop, buf);
1747 break;
1751 return ret;
1755 * Define properties for stations
1756 * @param stdid StationID of the first station tile.
1757 * @param numinfo Number of subsequent station tiles to change the property for.
1758 * @param prop The property to change.
1759 * @param buf The property value.
1760 * @return ChangeInfoResult.
1762 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1764 ChangeInfoResult ret = CIR_SUCCESS;
1766 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1767 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1768 return CIR_INVALID_ID;
1771 /* Allocate station specs if necessary */
1772 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1774 for (int i = 0; i < numinfo; i++) {
1775 StationSpec *statspec = _cur.grffile->stations[stid + i];
1777 /* Check that the station we are modifying is defined. */
1778 if (statspec == NULL && prop != 0x08) {
1779 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1780 return CIR_INVALID_ID;
1783 switch (prop) {
1784 case 0x08: { // Class ID
1785 StationSpec **spec = &_cur.grffile->stations[stid + i];
1787 /* Property 0x08 is special; it is where the station is allocated */
1788 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1790 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1791 uint32 classid = buf->ReadDWord();
1792 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1793 break;
1796 case 0x09: // Define sprite layout
1797 statspec->tiles = buf->ReadExtendedByte();
1798 delete[] statspec->renderdata; // delete earlier loaded stuff
1799 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1801 for (uint t = 0; t < statspec->tiles; t++) {
1802 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1803 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1805 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1806 buf->Skip(4);
1807 extern const DrawTileSprites _station_display_datas_rail[8];
1808 dts->Clone(&_station_display_datas_rail[t % 8]);
1809 continue;
1812 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1813 /* On error, bail out immediately. Temporary GRF data was already freed */
1814 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1816 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1817 tmp_layout.Clear();
1818 for (;;) {
1819 /* no relative bounding box support */
1820 DrawTileSeqStruct *dtss = tmp_layout.Append();
1821 MemSetT(dtss, 0);
1823 dtss->delta_x = buf->ReadByte();
1824 if (dtss->IsTerminator()) break;
1825 dtss->delta_y = buf->ReadByte();
1826 dtss->delta_z = buf->ReadByte();
1827 dtss->size_x = buf->ReadByte();
1828 dtss->size_y = buf->ReadByte();
1829 dtss->size_z = buf->ReadByte();
1831 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1832 /* On error, bail out immediately. Temporary GRF data was already freed */
1833 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1835 dts->Clone(tmp_layout.Begin());
1837 break;
1839 case 0x0A: { // Copy sprite layout
1840 byte srcid = buf->ReadByte();
1841 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1843 if (srcstatspec == NULL) {
1844 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1845 continue;
1848 delete[] statspec->renderdata; // delete earlier loaded stuff
1850 statspec->tiles = srcstatspec->tiles;
1851 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1852 for (uint t = 0; t < statspec->tiles; t++) {
1853 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1855 break;
1858 case 0x0B: // Callback mask
1859 statspec->callback_mask = buf->ReadByte();
1860 break;
1862 case 0x0C: // Disallowed number of platforms
1863 statspec->disallowed_platforms = buf->ReadByte();
1864 break;
1866 case 0x0D: // Disallowed platform lengths
1867 statspec->disallowed_lengths = buf->ReadByte();
1868 break;
1870 case 0x0E: // Define custom layout
1871 statspec->copied_layouts = false;
1873 while (buf->HasData()) {
1874 byte length = buf->ReadByte();
1875 byte number = buf->ReadByte();
1876 StationLayout layout;
1877 uint l, p;
1879 if (length == 0 || number == 0) break;
1881 if (length > statspec->lengths) {
1882 statspec->platforms = ReallocT(statspec->platforms, length);
1883 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1885 statspec->layouts = ReallocT(statspec->layouts, length);
1886 memset(statspec->layouts + statspec->lengths, 0,
1887 (length - statspec->lengths) * sizeof(*statspec->layouts));
1889 statspec->lengths = length;
1891 l = length - 1; // index is zero-based
1893 if (number > statspec->platforms[l]) {
1894 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1895 /* We expect NULL being 0 here, but C99 guarantees that. */
1896 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1897 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1899 statspec->platforms[l] = number;
1902 p = 0;
1903 layout = MallocT<byte>(length * number);
1904 try {
1905 for (l = 0; l < length; l++) {
1906 for (p = 0; p < number; p++) {
1907 layout[l * number + p] = buf->ReadByte();
1910 } catch (...) {
1911 free(layout);
1912 throw;
1915 l--;
1916 p--;
1917 free(statspec->layouts[l][p]);
1918 statspec->layouts[l][p] = layout;
1920 break;
1922 case 0x0F: { // Copy custom layout
1923 byte srcid = buf->ReadByte();
1924 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1926 if (srcstatspec == NULL) {
1927 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
1928 continue;
1931 statspec->lengths = srcstatspec->lengths;
1932 statspec->platforms = srcstatspec->platforms;
1933 statspec->layouts = srcstatspec->layouts;
1934 statspec->copied_layouts = true;
1935 break;
1938 case 0x10: // Little/lots cargo threshold
1939 statspec->cargo_threshold = buf->ReadWord();
1940 break;
1942 case 0x11: // Pylon placement
1943 statspec->pylons = buf->ReadByte();
1944 break;
1946 case 0x12: // Cargo types for random triggers
1947 statspec->cargo_triggers = buf->ReadDWord();
1948 if (_cur.grffile->grf_version >= 7) {
1949 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
1951 break;
1953 case 0x13: // General flags
1954 statspec->flags = buf->ReadByte();
1955 break;
1957 case 0x14: // Overhead wire placement
1958 statspec->wires = buf->ReadByte();
1959 break;
1961 case 0x15: // Blocked tiles
1962 statspec->blocked = buf->ReadByte();
1963 break;
1965 case 0x16: // Animation info
1966 statspec->animation.frames = buf->ReadByte();
1967 statspec->animation.status = buf->ReadByte();
1968 break;
1970 case 0x17: // Animation speed
1971 statspec->animation.speed = buf->ReadByte();
1972 break;
1974 case 0x18: // Animation triggers
1975 statspec->animation.triggers = buf->ReadWord();
1976 break;
1978 case 0x1A: // Advanced sprite layout
1979 statspec->tiles = buf->ReadExtendedByte();
1980 delete[] statspec->renderdata; // delete earlier loaded stuff
1981 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1983 for (uint t = 0; t < statspec->tiles; t++) {
1984 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1985 uint num_building_sprites = buf->ReadByte();
1986 /* On error, bail out immediately. Temporary GRF data was already freed */
1987 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
1989 break;
1991 default:
1992 ret = CIR_UNKNOWN;
1993 break;
1997 return ret;
2001 * Define properties for water features
2002 * @param id Type of the first water feature.
2003 * @param numinfo Number of subsequent water feature ids to change the property for.
2004 * @param prop The property to change.
2005 * @param buf The property value.
2006 * @return ChangeInfoResult.
2008 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2010 ChangeInfoResult ret = CIR_SUCCESS;
2012 if (id + numinfo > CF_END) {
2013 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2014 return CIR_INVALID_ID;
2017 for (int i = 0; i < numinfo; i++) {
2018 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2020 switch (prop) {
2021 case 0x08:
2022 cp->callback_mask = buf->ReadByte();
2023 break;
2025 case 0x09:
2026 cp->flags = buf->ReadByte();
2027 break;
2029 default:
2030 ret = CIR_UNKNOWN;
2031 break;
2035 return ret;
2039 * Define properties for bridges
2040 * @param brid BridgeID of the bridge.
2041 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2042 * @param prop The property to change.
2043 * @param buf The property value.
2044 * @return ChangeInfoResult.
2046 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2048 ChangeInfoResult ret = CIR_SUCCESS;
2050 if (brid + numinfo > MAX_BRIDGES) {
2051 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2052 return CIR_INVALID_ID;
2055 for (int i = 0; i < numinfo; i++) {
2056 BridgeSpec *bridge = &_bridge[brid + i];
2058 switch (prop) {
2059 case 0x08: { // Year of availability
2060 /* We treat '0' as always available */
2061 byte year = buf->ReadByte();
2062 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2063 break;
2066 case 0x09: // Minimum length
2067 bridge->min_length = buf->ReadByte();
2068 break;
2070 case 0x0A: // Maximum length
2071 bridge->max_length = buf->ReadByte();
2072 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2073 break;
2075 case 0x0B: // Cost factor
2076 bridge->price = buf->ReadByte();
2077 break;
2079 case 0x0C: // Maximum speed
2080 bridge->speed = buf->ReadWord();
2081 break;
2083 case 0x0D: { // Bridge sprite tables
2084 byte tableid = buf->ReadByte();
2085 byte numtables = buf->ReadByte();
2087 if (bridge->sprite_table == NULL) {
2088 /* Allocate memory for sprite table pointers and zero out */
2089 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2092 for (; numtables-- != 0; tableid++) {
2093 if (tableid >= 7) { // skip invalid data
2094 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2095 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2096 continue;
2099 if (bridge->sprite_table[tableid] == NULL) {
2100 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2103 for (byte sprite = 0; sprite < 32; sprite++) {
2104 SpriteID image = buf->ReadWord();
2105 PaletteID pal = buf->ReadWord();
2107 bridge->sprite_table[tableid][sprite].sprite = image;
2108 bridge->sprite_table[tableid][sprite].pal = pal;
2110 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2113 break;
2116 case 0x0E: // Flags; bit 0 - disable far pillars
2117 bridge->flags = buf->ReadByte();
2118 break;
2120 case 0x0F: // Long format year of availability (year since year 0)
2121 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2122 break;
2124 case 0x10: { // purchase string
2125 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2126 if (newone != STR_UNDEFINED) bridge->material = newone;
2127 break;
2130 case 0x11: // description of bridge with rails or roads
2131 case 0x12: {
2132 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2133 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2134 break;
2137 case 0x13: // 16 bits cost multiplier
2138 bridge->price = buf->ReadWord();
2139 break;
2141 default:
2142 ret = CIR_UNKNOWN;
2143 break;
2147 return ret;
2151 * Ignore a house property
2152 * @param prop Property to read.
2153 * @param buf Property value.
2154 * @return ChangeInfoResult.
2156 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2158 ChangeInfoResult ret = CIR_SUCCESS;
2160 switch (prop) {
2161 case 0x09:
2162 case 0x0B:
2163 case 0x0C:
2164 case 0x0D:
2165 case 0x0E:
2166 case 0x0F:
2167 case 0x11:
2168 case 0x14:
2169 case 0x15:
2170 case 0x16:
2171 case 0x18:
2172 case 0x19:
2173 case 0x1A:
2174 case 0x1B:
2175 case 0x1C:
2176 case 0x1D:
2177 case 0x1F:
2178 buf->ReadByte();
2179 break;
2181 case 0x0A:
2182 case 0x10:
2183 case 0x12:
2184 case 0x13:
2185 case 0x21:
2186 case 0x22:
2187 buf->ReadWord();
2188 break;
2190 case 0x1E:
2191 buf->ReadDWord();
2192 break;
2194 case 0x17:
2195 for (uint j = 0; j < 4; j++) buf->ReadByte();
2196 break;
2198 case 0x20: {
2199 byte count = buf->ReadByte();
2200 for (byte j = 0; j < count; j++) buf->ReadByte();
2201 break;
2204 default:
2205 ret = CIR_UNKNOWN;
2206 break;
2208 return ret;
2212 * Define properties for houses
2213 * @param hid HouseID of the house.
2214 * @param numinfo Number of subsequent houseIDs to change the property for.
2215 * @param prop The property to change.
2216 * @param buf The property value.
2217 * @return ChangeInfoResult.
2219 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2221 ChangeInfoResult ret = CIR_SUCCESS;
2223 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2224 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2225 return CIR_INVALID_ID;
2228 /* Allocate house specs if they haven't been allocated already. */
2229 if (_cur.grffile->housespec == NULL) {
2230 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2233 for (int i = 0; i < numinfo; i++) {
2234 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2236 if (prop != 0x08 && housespec == NULL) {
2237 /* If the house property 08 is not yet set, ignore this property */
2238 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2239 if (cir > ret) ret = cir;
2240 continue;
2243 switch (prop) {
2244 case 0x08: { // Substitute building type, and definition of a new house
2245 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2246 byte subs_id = buf->ReadByte();
2248 if (subs_id == 0xFF) {
2249 /* Instead of defining a new house, a substitute house id
2250 * of 0xFF disables the old house with the current id. */
2251 HouseSpec::Get(hid + i)->enabled = false;
2252 continue;
2253 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2254 /* The substitute id must be one of the original houses. */
2255 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2256 continue;
2259 /* Allocate space for this house. */
2260 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2262 housespec = *house;
2264 MemCpyT(housespec, HouseSpec::Get(subs_id));
2266 housespec->enabled = true;
2267 housespec->grf_prop.local_id = hid + i;
2268 housespec->grf_prop.subst_id = subs_id;
2269 housespec->grf_prop.grffile = _cur.grffile;
2270 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2271 housespec->random_colour[1] = 0x08; // for all new houses
2272 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2273 housespec->random_colour[3] = 0x06;
2275 /* Make sure that the third cargo type is valid in this
2276 * climate. This can cause problems when copying the properties
2277 * of a house that accepts food, where the new house is valid
2278 * in the temperate climate. */
2279 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2280 housespec->cargo_acceptance[2] = 0;
2283 _loaded_newgrf_features.has_newhouses = true;
2284 break;
2287 case 0x09: // Building flags
2288 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2289 break;
2291 case 0x0A: { // Availability years
2292 uint16 years = buf->ReadWord();
2293 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2294 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2295 break;
2298 case 0x0B: // Population
2299 housespec->population = buf->ReadByte();
2300 break;
2302 case 0x0C: // Mail generation multiplier
2303 housespec->mail_generation = buf->ReadByte();
2304 break;
2306 case 0x0D: // Passenger acceptance
2307 case 0x0E: // Mail acceptance
2308 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2309 break;
2311 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2312 int8 goods = buf->ReadByte();
2314 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2315 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2316 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2317 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2319 /* Make sure the cargo type is valid in this climate. */
2320 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2322 housespec->accepts_cargo[2] = cid;
2323 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2324 break;
2327 case 0x10: // Local authority rating decrease on removal
2328 housespec->remove_rating_decrease = buf->ReadWord();
2329 break;
2331 case 0x11: // Removal cost multiplier
2332 housespec->removal_cost = buf->ReadByte();
2333 break;
2335 case 0x12: // Building name ID
2336 housespec->building_name = buf->ReadWord();
2337 _string_to_grf_mapping[&housespec->building_name] = _cur.grffile->grfid;
2338 break;
2340 case 0x13: // Building availability mask
2341 housespec->building_availability = (HouseZones)buf->ReadWord();
2342 break;
2344 case 0x14: // House callback mask
2345 housespec->callback_mask |= buf->ReadByte();
2346 break;
2348 case 0x15: { // House override byte
2349 byte override = buf->ReadByte();
2351 /* The house being overridden must be an original house. */
2352 if (override >= NEW_HOUSE_OFFSET) {
2353 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2354 continue;
2357 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2358 break;
2361 case 0x16: // Periodic refresh multiplier
2362 housespec->processing_time = min(buf->ReadByte(), 63);
2363 break;
2365 case 0x17: // Four random colours to use
2366 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2367 break;
2369 case 0x18: // Relative probability of appearing
2370 housespec->probability = buf->ReadByte();
2371 break;
2373 case 0x19: // Extra flags
2374 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2375 break;
2377 case 0x1A: // Animation frames
2378 housespec->animation.frames = buf->ReadByte();
2379 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2380 SB(housespec->animation.frames, 7, 1, 0);
2381 break;
2383 case 0x1B: // Animation speed
2384 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2385 break;
2387 case 0x1C: // Class of the building type
2388 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2389 break;
2391 case 0x1D: // Callback mask part 2
2392 housespec->callback_mask |= (buf->ReadByte() << 8);
2393 break;
2395 case 0x1E: { // Accepted cargo types
2396 uint32 cargotypes = buf->ReadDWord();
2398 /* Check if the cargo types should not be changed */
2399 if (cargotypes == 0xFFFFFFFF) break;
2401 for (uint j = 0; j < 3; j++) {
2402 /* Get the cargo number from the 'list' */
2403 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2404 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2406 if (cargo == CT_INVALID) {
2407 /* Disable acceptance of invalid cargo type */
2408 housespec->cargo_acceptance[j] = 0;
2409 } else {
2410 housespec->accepts_cargo[j] = cargo;
2413 break;
2416 case 0x1F: // Minimum life span
2417 housespec->minimum_life = buf->ReadByte();
2418 break;
2420 case 0x20: { // Cargo acceptance watch list
2421 byte count = buf->ReadByte();
2422 for (byte j = 0; j < count; j++) {
2423 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2424 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2426 break;
2429 case 0x21: // long introduction year
2430 housespec->min_year = buf->ReadWord();
2431 break;
2433 case 0x22: // long maximum year
2434 housespec->max_year = buf->ReadWord();
2435 break;
2437 default:
2438 ret = CIR_UNKNOWN;
2439 break;
2443 return ret;
2447 * Get the language map associated with a given NewGRF and language.
2448 * @param grfid The NewGRF to get the map for.
2449 * @param language_id The (NewGRF) language ID to get the map for.
2450 * @return The LanguageMap, or NULL if it couldn't be found.
2452 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2454 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2455 const GRFFile *grffile = GetFileByGRFID(grfid);
2456 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2460 * Load a cargo- or railtype-translation table.
2461 * @param gvid ID of the global variable. This is basically only checked for zerones.
2462 * @param numinfo Number of subsequent IDs to change the property for.
2463 * @param buf The property value.
2464 * @param [in,out] translation_table Storage location for the translation table.
2465 * @param name Name of the table for debug output.
2466 * @return ChangeInfoResult.
2468 template <typename T>
2469 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2471 if (gvid != 0) {
2472 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2473 return CIR_INVALID_ID;
2476 translation_table.Clear();
2477 for (int i = 0; i < numinfo; i++) {
2478 uint32 item = buf->ReadDWord();
2479 *translation_table.Append() = BSWAP32(item);
2482 return CIR_SUCCESS;
2486 * Define properties for global variables
2487 * @param gvid ID of the global variable.
2488 * @param numinfo Number of subsequent IDs to change the property for.
2489 * @param prop The property to change.
2490 * @param buf The property value.
2491 * @return ChangeInfoResult.
2493 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2495 /* Properties which are handled as a whole */
2496 switch (prop) {
2497 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2498 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2500 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2501 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2503 default:
2504 break;
2507 /* Properties which are handled per item */
2508 ChangeInfoResult ret = CIR_SUCCESS;
2509 for (int i = 0; i < numinfo; i++) {
2510 switch (prop) {
2511 case 0x08: { // Cost base factor
2512 int factor = buf->ReadByte();
2513 uint price = gvid + i;
2515 if (price < PR_END) {
2516 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2517 } else {
2518 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2520 break;
2523 case 0x0A: { // Currency display names
2524 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2525 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2527 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2528 _currency_specs[curidx].name = newone;
2530 break;
2533 case 0x0B: { // Currency multipliers
2534 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2535 uint32 rate = buf->ReadDWord();
2537 if (curidx < CURRENCY_END) {
2538 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2539 * which OTTD does not. For this reason, divide grf value by 1000,
2540 * to be compatible */
2541 _currency_specs[curidx].rate = rate / 1000;
2542 } else {
2543 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2545 break;
2548 case 0x0C: { // Currency options
2549 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2550 uint16 options = buf->ReadWord();
2552 if (curidx < CURRENCY_END) {
2553 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2554 _currency_specs[curidx].separator[1] = '\0';
2555 /* By specifying only one bit, we prevent errors,
2556 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2557 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2558 } else {
2559 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2561 break;
2564 case 0x0D: { // Currency prefix symbol
2565 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2566 uint32 tempfix = buf->ReadDWord();
2568 if (curidx < CURRENCY_END) {
2569 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2570 _currency_specs[curidx].prefix[4] = 0;
2571 } else {
2572 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2574 break;
2577 case 0x0E: { // Currency suffix symbol
2578 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2579 uint32 tempfix = buf->ReadDWord();
2581 if (curidx < CURRENCY_END) {
2582 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2583 _currency_specs[curidx].suffix[4] = 0;
2584 } else {
2585 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2587 break;
2590 case 0x0F: { // Euro introduction dates
2591 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2592 Year year_euro = buf->ReadWord();
2594 if (curidx < CURRENCY_END) {
2595 _currency_specs[curidx].to_euro = year_euro;
2596 } else {
2597 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2599 break;
2602 case 0x10: // Snow line height table
2603 if (numinfo > 1 || IsSnowLineSet()) {
2604 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2605 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2606 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2607 } else {
2608 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2610 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2611 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2612 table[i][j] = buf->ReadByte();
2613 if (_cur.grffile->grf_version >= 8) {
2614 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 256;
2615 } else {
2616 if (table[i][j] >= 128) {
2617 /* no snow */
2618 table[i][j] = 0xFF;
2619 } else {
2620 table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 128;
2625 SetSnowLine(table);
2627 break;
2629 case 0x11: // GRF match for engine allocation
2630 /* This is loaded during the reservation stage, so just skip it here. */
2631 /* Each entry is 8 bytes. */
2632 buf->Skip(8);
2633 break;
2635 case 0x13: // Gender translation table
2636 case 0x14: // Case translation table
2637 case 0x15: { // Plural form translation
2638 uint curidx = gvid + i; // The current index, i.e. language.
2639 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2640 if (lang == NULL) {
2641 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2642 /* Skip over the data. */
2643 if (prop == 0x15) {
2644 buf->ReadByte();
2645 } else {
2646 while (buf->ReadByte() != 0) {
2647 buf->ReadString();
2650 break;
2653 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2655 if (prop == 0x15) {
2656 uint plural_form = buf->ReadByte();
2657 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2658 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2659 } else {
2660 _cur.grffile->language_map[curidx].plural_form = plural_form;
2662 break;
2665 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2666 while (newgrf_id != 0) {
2667 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2669 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2670 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2671 * is just a subset of UTF8, or they need the bigger UTF8 characters
2672 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2673 WChar c;
2674 size_t len = Utf8Decode(&c, name);
2675 if (c == NFO_UTF8_IDENTIFIER) name += len;
2677 LanguageMap::Mapping map;
2678 map.newgrf_id = newgrf_id;
2679 if (prop == 0x13) {
2680 map.openttd_id = lang->GetGenderIndex(name);
2681 if (map.openttd_id >= MAX_NUM_GENDERS) {
2682 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2683 } else {
2684 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2686 } else {
2687 map.openttd_id = lang->GetCaseIndex(name);
2688 if (map.openttd_id >= MAX_NUM_CASES) {
2689 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2690 } else {
2691 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2694 newgrf_id = buf->ReadByte();
2696 break;
2699 default:
2700 ret = CIR_UNKNOWN;
2701 break;
2705 return ret;
2708 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2710 /* Properties which are handled as a whole */
2711 switch (prop) {
2712 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2713 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2715 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2716 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2718 default:
2719 break;
2722 /* Properties which are handled per item */
2723 ChangeInfoResult ret = CIR_SUCCESS;
2724 for (int i = 0; i < numinfo; i++) {
2725 switch (prop) {
2726 case 0x08: // Cost base factor
2727 case 0x15: // Plural form translation
2728 buf->ReadByte();
2729 break;
2731 case 0x0A: // Currency display names
2732 case 0x0C: // Currency options
2733 case 0x0F: // Euro introduction dates
2734 buf->ReadWord();
2735 break;
2737 case 0x0B: // Currency multipliers
2738 case 0x0D: // Currency prefix symbol
2739 case 0x0E: // Currency suffix symbol
2740 buf->ReadDWord();
2741 break;
2743 case 0x10: // Snow line height table
2744 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2745 break;
2747 case 0x11: { // GRF match for engine allocation
2748 uint32 s = buf->ReadDWord();
2749 uint32 t = buf->ReadDWord();
2750 SetNewGRFOverride(s, t);
2751 break;
2754 case 0x13: // Gender translation table
2755 case 0x14: // Case translation table
2756 while (buf->ReadByte() != 0) {
2757 buf->ReadString();
2759 break;
2761 default:
2762 ret = CIR_UNKNOWN;
2763 break;
2767 return ret;
2772 * Define properties for cargoes
2773 * @param cid Local ID of the cargo.
2774 * @param numinfo Number of subsequent IDs to change the property for.
2775 * @param prop The property to change.
2776 * @param buf The property value.
2777 * @return ChangeInfoResult.
2779 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2781 ChangeInfoResult ret = CIR_SUCCESS;
2783 if (cid + numinfo > NUM_CARGO) {
2784 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2785 return CIR_INVALID_ID;
2788 for (int i = 0; i < numinfo; i++) {
2789 CargoSpec *cs = CargoSpec::Get(cid + i);
2791 switch (prop) {
2792 case 0x08: // Bit number of cargo
2793 cs->bitnum = buf->ReadByte();
2794 if (cs->IsValid()) {
2795 cs->grffile = _cur.grffile;
2796 SetBit(_cargo_mask, cid + i);
2797 } else {
2798 ClrBit(_cargo_mask, cid + i);
2800 break;
2802 case 0x09: // String ID for cargo type name
2803 cs->name = buf->ReadWord();
2804 _string_to_grf_mapping[&cs->name] = _cur.grffile->grfid;
2805 break;
2807 case 0x0A: // String for 1 unit of cargo
2808 cs->name_single = buf->ReadWord();
2809 _string_to_grf_mapping[&cs->name_single] = _cur.grffile->grfid;
2810 break;
2812 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2813 case 0x1B: // String for cargo units
2814 /* String for units of cargo. This is different in OpenTTD
2815 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2816 * Property 1B is used to set OpenTTD's behaviour. */
2817 cs->units_volume = buf->ReadWord();
2818 _string_to_grf_mapping[&cs->units_volume] = _cur.grffile->grfid;
2819 break;
2821 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2822 case 0x1C: // String for any amount of cargo
2823 /* Strings for an amount of cargo. This is different in OpenTTD
2824 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2825 * Property 1C is used to set OpenTTD's behaviour. */
2826 cs->quantifier = buf->ReadWord();
2827 _string_to_grf_mapping[&cs->quantifier] = _cur.grffile->grfid;
2828 break;
2830 case 0x0D: // String for two letter cargo abbreviation
2831 cs->abbrev = buf->ReadWord();
2832 _string_to_grf_mapping[&cs->abbrev] = _cur.grffile->grfid;
2833 break;
2835 case 0x0E: // Sprite ID for cargo icon
2836 cs->sprite = buf->ReadWord();
2837 break;
2839 case 0x0F: // Weight of one unit of cargo
2840 cs->weight = buf->ReadByte();
2841 break;
2843 case 0x10: // Used for payment calculation
2844 cs->transit_days[0] = buf->ReadByte();
2845 break;
2847 case 0x11: // Used for payment calculation
2848 cs->transit_days[1] = buf->ReadByte();
2849 break;
2851 case 0x12: // Base cargo price
2852 cs->initial_payment = buf->ReadDWord();
2853 break;
2855 case 0x13: // Colour for station rating bars
2856 cs->rating_colour = buf->ReadByte();
2857 break;
2859 case 0x14: // Colour for cargo graph
2860 cs->legend_colour = buf->ReadByte();
2861 break;
2863 case 0x15: // Freight status
2864 cs->is_freight = (buf->ReadByte() != 0);
2865 break;
2867 case 0x16: // Cargo classes
2868 cs->classes = buf->ReadWord();
2869 break;
2871 case 0x17: // Cargo label
2872 cs->label = buf->ReadDWord();
2873 cs->label = BSWAP32(cs->label);
2874 break;
2876 case 0x18: { // Town growth substitute type
2877 uint8 substitute_type = buf->ReadByte();
2879 switch (substitute_type) {
2880 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2881 case 0x02: cs->town_effect = TE_MAIL; break;
2882 case 0x05: cs->town_effect = TE_GOODS; break;
2883 case 0x09: cs->town_effect = TE_WATER; break;
2884 case 0x0B: cs->town_effect = TE_FOOD; break;
2885 default:
2886 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2887 /* FALL THROUGH */
2888 case 0xFF: cs->town_effect = TE_NONE; break;
2890 break;
2893 case 0x19: // Town growth coefficient
2894 cs->multipliertowngrowth = buf->ReadWord();
2895 break;
2897 case 0x1A: // Bitmask of callbacks to use
2898 cs->callback_mask = buf->ReadByte();
2899 break;
2901 case 0x1D: // Vehicle capacity muliplier
2902 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2903 break;
2905 default:
2906 ret = CIR_UNKNOWN;
2907 break;
2911 return ret;
2916 * Define properties for sound effects
2917 * @param sid Local ID of the sound.
2918 * @param numinfo Number of subsequent IDs to change the property for.
2919 * @param prop The property to change.
2920 * @param buf The property value.
2921 * @return ChangeInfoResult.
2923 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
2925 ChangeInfoResult ret = CIR_SUCCESS;
2927 if (_cur.grffile->sound_offset == 0) {
2928 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
2929 return CIR_INVALID_ID;
2932 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
2933 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
2934 return CIR_INVALID_ID;
2937 for (int i = 0; i < numinfo; i++) {
2938 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
2940 switch (prop) {
2941 case 0x08: // Relative volume
2942 sound->volume = buf->ReadByte();
2943 break;
2945 case 0x09: // Priority
2946 sound->priority = buf->ReadByte();
2947 break;
2949 case 0x0A: { // Override old sound
2950 SoundID orig_sound = buf->ReadByte();
2952 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
2953 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
2954 } else {
2955 SoundEntry *old_sound = GetSound(orig_sound);
2957 /* Literally copy the data of the new sound over the original */
2958 *old_sound = *sound;
2960 break;
2963 default:
2964 ret = CIR_UNKNOWN;
2965 break;
2969 return ret;
2973 * Ignore an industry tile property
2974 * @param prop The property to ignore.
2975 * @param buf The property value.
2976 * @return ChangeInfoResult.
2978 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
2980 ChangeInfoResult ret = CIR_SUCCESS;
2982 switch (prop) {
2983 case 0x09:
2984 case 0x0D:
2985 case 0x0E:
2986 case 0x10:
2987 case 0x11:
2988 case 0x12:
2989 buf->ReadByte();
2990 break;
2992 case 0x0A:
2993 case 0x0B:
2994 case 0x0C:
2995 case 0x0F:
2996 buf->ReadWord();
2997 break;
2999 default:
3000 ret = CIR_UNKNOWN;
3001 break;
3003 return ret;
3007 * Define properties for industry tiles
3008 * @param indtid Local ID of the industry tile.
3009 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3010 * @param prop The property to change.
3011 * @param buf The property value.
3012 * @return ChangeInfoResult.
3014 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3016 ChangeInfoResult ret = CIR_SUCCESS;
3018 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3019 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3020 return CIR_INVALID_ID;
3023 /* Allocate industry tile specs if they haven't been allocated already. */
3024 if (_cur.grffile->indtspec == NULL) {
3025 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3028 for (int i = 0; i < numinfo; i++) {
3029 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3031 if (prop != 0x08 && tsp == NULL) {
3032 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3033 if (cir > ret) ret = cir;
3034 continue;
3037 switch (prop) {
3038 case 0x08: { // Substitute industry tile type
3039 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3040 byte subs_id = buf->ReadByte();
3042 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3043 /* The substitute id must be one of the original industry tile. */
3044 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3045 continue;
3048 /* Allocate space for this industry. */
3049 if (*tilespec == NULL) {
3050 *tilespec = CallocT<IndustryTileSpec>(1);
3051 tsp = *tilespec;
3053 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3054 tsp->enabled = true;
3056 /* A copied tile should not have the animation infos copied too.
3057 * The anim_state should be left untouched, though
3058 * It is up to the author to animate them himself */
3059 tsp->anim_production = INDUSTRYTILE_NOANIM;
3060 tsp->anim_next = INDUSTRYTILE_NOANIM;
3062 tsp->grf_prop.local_id = indtid + i;
3063 tsp->grf_prop.subst_id = subs_id;
3064 tsp->grf_prop.grffile = _cur.grffile;
3065 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3067 break;
3070 case 0x09: { // Industry tile override
3071 byte ovrid = buf->ReadByte();
3073 /* The industry being overridden must be an original industry. */
3074 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3075 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3076 continue;
3079 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3080 break;
3083 case 0x0A: // Tile acceptance
3084 case 0x0B:
3085 case 0x0C: {
3086 uint16 acctp = buf->ReadWord();
3087 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3088 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3089 break;
3092 case 0x0D: // Land shape flags
3093 tsp->slopes_refused = (Slope)buf->ReadByte();
3094 break;
3096 case 0x0E: // Callback mask
3097 tsp->callback_mask = buf->ReadByte();
3098 break;
3100 case 0x0F: // Animation information
3101 tsp->animation.frames = buf->ReadByte();
3102 tsp->animation.status = buf->ReadByte();
3103 break;
3105 case 0x10: // Animation speed
3106 tsp->animation.speed = buf->ReadByte();
3107 break;
3109 case 0x11: // Triggers for callback 25
3110 tsp->animation.triggers = buf->ReadByte();
3111 break;
3113 case 0x12: // Special flags
3114 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3115 break;
3117 default:
3118 ret = CIR_UNKNOWN;
3119 break;
3123 return ret;
3127 * Ignore an industry property
3128 * @param prop The property to ignore.
3129 * @param buf The property value.
3130 * @return ChangeInfoResult.
3132 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3134 ChangeInfoResult ret = CIR_SUCCESS;
3136 switch (prop) {
3137 case 0x09:
3138 case 0x0B:
3139 case 0x0F:
3140 case 0x12:
3141 case 0x13:
3142 case 0x14:
3143 case 0x17:
3144 case 0x18:
3145 case 0x19:
3146 case 0x21:
3147 case 0x22:
3148 buf->ReadByte();
3149 break;
3151 case 0x0C:
3152 case 0x0D:
3153 case 0x0E:
3154 case 0x10:
3155 case 0x1B:
3156 case 0x1F:
3157 case 0x24:
3158 buf->ReadWord();
3159 break;
3161 case 0x11:
3162 case 0x1A:
3163 case 0x1C:
3164 case 0x1D:
3165 case 0x1E:
3166 case 0x20:
3167 case 0x23:
3168 buf->ReadDWord();
3169 break;
3171 case 0x0A: {
3172 byte num_table = buf->ReadByte();
3173 for (byte j = 0; j < num_table; j++) {
3174 for (uint k = 0;; k++) {
3175 byte x = buf->ReadByte();
3176 if (x == 0xFE && k == 0) {
3177 buf->ReadByte();
3178 buf->ReadByte();
3179 break;
3182 byte y = buf->ReadByte();
3183 if (x == 0 && y == 0x80) break;
3185 byte gfx = buf->ReadByte();
3186 if (gfx == 0xFE) buf->ReadWord();
3189 break;
3192 case 0x16:
3193 for (byte j = 0; j < 3; j++) buf->ReadByte();
3194 break;
3196 case 0x15: {
3197 byte number_of_sounds = buf->ReadByte();
3198 for (uint8 j = 0; j < number_of_sounds; j++) {
3199 buf->ReadByte();
3201 break;
3204 default:
3205 ret = CIR_UNKNOWN;
3206 break;
3208 return ret;
3212 * Validate the industry layout; e.g. to prevent duplicate tiles.
3213 * @param layout The layout to check.
3214 * @param size The size of the layout.
3215 * @return True if the layout is deemed valid.
3217 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3219 for (int i = 0; i < size - 1; i++) {
3220 for (int j = i + 1; j < size; j++) {
3221 if (layout[i].ti.x == layout[j].ti.x &&
3222 layout[i].ti.y == layout[j].ti.y) {
3223 return false;
3227 return true;
3230 /** Clean the tile table of the IndustrySpec if it's needed. */
3231 static void CleanIndustryTileTable(IndustrySpec *ind)
3233 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3234 for (int j = 0; j < ind->num_table; j++) {
3235 /* remove the individual layouts */
3236 free(ind->table[j]);
3238 /* remove the layouts pointers */
3239 free(ind->table);
3240 ind->table = NULL;
3245 * Define properties for industries
3246 * @param indid Local ID of the industry.
3247 * @param numinfo Number of subsequent industry IDs to change the property for.
3248 * @param prop The property to change.
3249 * @param buf The property value.
3250 * @return ChangeInfoResult.
3252 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3254 ChangeInfoResult ret = CIR_SUCCESS;
3256 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3257 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3258 return CIR_INVALID_ID;
3261 /* Allocate industry specs if they haven't been allocated already. */
3262 if (_cur.grffile->industryspec == NULL) {
3263 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3266 for (int i = 0; i < numinfo; i++) {
3267 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3269 if (prop != 0x08 && indsp == NULL) {
3270 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3271 if (cir > ret) ret = cir;
3272 continue;
3275 switch (prop) {
3276 case 0x08: { // Substitute industry type
3277 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3278 byte subs_id = buf->ReadByte();
3280 if (subs_id == 0xFF) {
3281 /* Instead of defining a new industry, a substitute industry id
3282 * of 0xFF disables the old industry with the current id. */
3283 _industry_specs[indid + i].enabled = false;
3284 continue;
3285 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3286 /* The substitute id must be one of the original industry. */
3287 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3288 continue;
3291 /* Allocate space for this industry.
3292 * Only need to do it once. If ever it is called again, it should not
3293 * do anything */
3294 if (*indspec == NULL) {
3295 *indspec = CallocT<IndustrySpec>(1);
3296 indsp = *indspec;
3298 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3299 indsp->enabled = true;
3300 indsp->grf_prop.local_id = indid + i;
3301 indsp->grf_prop.subst_id = subs_id;
3302 indsp->grf_prop.grffile = _cur.grffile;
3303 /* If the grf industry needs to check its surounding upon creation, it should
3304 * rely on callbacks, not on the original placement functions */
3305 indsp->check_proc = CHECK_NOTHING;
3307 break;
3310 case 0x09: { // Industry type override
3311 byte ovrid = buf->ReadByte();
3313 /* The industry being overridden must be an original industry. */
3314 if (ovrid >= NEW_INDUSTRYOFFSET) {
3315 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3316 continue;
3318 indsp->grf_prop.override = ovrid;
3319 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3320 break;
3323 case 0x0A: { // Set industry layout(s)
3324 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3325 /* We read the total size in bytes, but we can't rely on the
3326 * newgrf to provide a sane value. First assume the value is
3327 * sane but later on we make sure we enlarge the array if the
3328 * newgrf contains more data. Each tile uses either 3 or 5
3329 * bytes, so to play it safe we assume 3. */
3330 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3331 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3332 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3333 uint size;
3334 const IndustryTileTable *copy_from;
3336 try {
3337 for (byte j = 0; j < new_num_layouts; j++) {
3338 for (uint k = 0;; k++) {
3339 if (k >= def_num_tiles) {
3340 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3341 /* Size reported by newgrf was not big enough so enlarge the array. */
3342 def_num_tiles *= 2;
3343 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3346 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3348 if (itt[k].ti.x == 0xFE && k == 0) {
3349 /* This means we have to borrow the layout from an old industry */
3350 IndustryType type = buf->ReadByte(); // industry holding required layout
3351 byte laynbr = buf->ReadByte(); // layout number to borrow
3353 copy_from = _origin_industry_specs[type].table[laynbr];
3354 for (size = 1;; size++) {
3355 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3357 break;
3360 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3362 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3363 /* Not the same terminator. The one we are using is rather
3364 x = -80, y = x . So, adjust it. */
3365 itt[k].ti.x = -0x80;
3366 itt[k].ti.y = 0;
3367 itt[k].gfx = 0;
3369 size = k + 1;
3370 copy_from = itt;
3371 break;
3374 itt[k].gfx = buf->ReadByte();
3376 if (itt[k].gfx == 0xFE) {
3377 /* Use a new tile from this GRF */
3378 int local_tile_id = buf->ReadWord();
3380 /* Read the ID from the _industile_mngr. */
3381 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3383 if (tempid == INVALID_INDUSTRYTILE) {
3384 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3385 } else {
3386 /* Declared as been valid, can be used */
3387 itt[k].gfx = tempid;
3388 size = k + 1;
3389 copy_from = itt;
3391 } else if (itt[k].gfx == 0xFF) {
3392 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3393 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3397 if (!ValidateIndustryLayout(copy_from, size)) {
3398 /* The industry layout was not valid, so skip this one. */
3399 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3400 new_num_layouts--;
3401 j--;
3402 } else {
3403 tile_table[j] = CallocT<IndustryTileTable>(size);
3404 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3407 } catch (...) {
3408 for (int i = 0; i < new_num_layouts; i++) {
3409 free(tile_table[i]);
3411 free(tile_table);
3412 free(itt);
3413 throw;
3416 /* Clean the tile table if it was already set by a previous prop A. */
3417 CleanIndustryTileTable(indsp);
3418 /* Install final layout construction in the industry spec */
3419 indsp->num_table = new_num_layouts;
3420 indsp->table = tile_table;
3421 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3422 free(itt);
3423 break;
3426 case 0x0B: // Industry production flags
3427 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3428 break;
3430 case 0x0C: // Industry closure message
3431 indsp->closure_text = buf->ReadWord();
3432 _string_to_grf_mapping[&indsp->closure_text] = _cur.grffile->grfid;
3433 break;
3435 case 0x0D: // Production increase message
3436 indsp->production_up_text = buf->ReadWord();
3437 _string_to_grf_mapping[&indsp->production_up_text] = _cur.grffile->grfid;
3438 break;
3440 case 0x0E: // Production decrease message
3441 indsp->production_down_text = buf->ReadWord();
3442 _string_to_grf_mapping[&indsp->production_down_text] = _cur.grffile->grfid;
3443 break;
3445 case 0x0F: // Fund cost multiplier
3446 indsp->cost_multiplier = buf->ReadByte();
3447 break;
3449 case 0x10: // Production cargo types
3450 for (byte j = 0; j < 2; j++) {
3451 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3453 break;
3455 case 0x11: // Acceptance cargo types
3456 for (byte j = 0; j < 3; j++) {
3457 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3459 buf->ReadByte(); // Unnused, eat it up
3460 break;
3462 case 0x12: // Production multipliers
3463 case 0x13:
3464 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3465 break;
3467 case 0x14: // Minimal amount of cargo distributed
3468 indsp->minimal_cargo = buf->ReadByte();
3469 break;
3471 case 0x15: { // Random sound effects
3472 indsp->number_of_sounds = buf->ReadByte();
3473 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3475 try {
3476 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3477 sounds[j] = buf->ReadByte();
3479 } catch (...) {
3480 free(sounds);
3481 throw;
3484 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3485 free(indsp->random_sounds);
3487 indsp->random_sounds = sounds;
3488 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3489 break;
3492 case 0x16: // Conflicting industry types
3493 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3494 break;
3496 case 0x17: // Probability in random game
3497 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3498 break;
3500 case 0x18: // Probability during gameplay
3501 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3502 break;
3504 case 0x19: // Map colour
3505 indsp->map_colour = buf->ReadByte();
3506 break;
3508 case 0x1A: // Special industry flags to define special behavior
3509 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3510 break;
3512 case 0x1B: // New industry text ID
3513 indsp->new_industry_text = buf->ReadWord();
3514 _string_to_grf_mapping[&indsp->new_industry_text] = _cur.grffile->grfid;
3515 break;
3517 case 0x1C: // Input cargo multipliers for the three input cargo types
3518 case 0x1D:
3519 case 0x1E: {
3520 uint32 multiples = buf->ReadDWord();
3521 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3522 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3523 break;
3526 case 0x1F: // Industry name
3527 indsp->name = buf->ReadWord();
3528 _string_to_grf_mapping[&indsp->name] = _cur.grffile->grfid;
3529 break;
3531 case 0x20: // Prospecting success chance
3532 indsp->prospecting_chance = buf->ReadDWord();
3533 break;
3535 case 0x21: // Callback mask
3536 case 0x22: { // Callback additional mask
3537 byte aflag = buf->ReadByte();
3538 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3539 break;
3542 case 0x23: // removal cost multiplier
3543 indsp->removal_cost_multiplier = buf->ReadDWord();
3544 break;
3546 case 0x24: // name for nearby station
3547 indsp->station_name = buf->ReadWord();
3548 if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur.grffile->grfid;
3549 break;
3551 default:
3552 ret = CIR_UNKNOWN;
3553 break;
3557 return ret;
3561 * Create a copy of the tile table so it can be freed later
3562 * without problems.
3563 * @param as The AirportSpec to copy the arrays of.
3565 static void DuplicateTileTable(AirportSpec *as)
3567 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3568 for (int i = 0; i < as->num_table; i++) {
3569 uint num_tiles = 1;
3570 const AirportTileTable *it = as->table[0];
3571 do {
3572 num_tiles++;
3573 } while ((++it)->ti.x != -0x80);
3574 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3575 MemCpyT(table_list[i], as->table[i], num_tiles);
3577 as->table = table_list;
3578 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3579 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3580 as->depot_table = depot_table;
3584 * Define properties for airports
3585 * @param airport Local ID of the airport.
3586 * @param numinfo Number of subsequent airport IDs to change the property for.
3587 * @param prop The property to change.
3588 * @param buf The property value.
3589 * @return ChangeInfoResult.
3591 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3593 ChangeInfoResult ret = CIR_SUCCESS;
3595 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3596 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3597 return CIR_INVALID_ID;
3600 /* Allocate industry specs if they haven't been allocated already. */
3601 if (_cur.grffile->airportspec == NULL) {
3602 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3605 for (int i = 0; i < numinfo; i++) {
3606 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3608 if (as == NULL && prop != 0x08 && prop != 0x09) {
3609 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3610 return CIR_INVALID_ID;
3613 switch (prop) {
3614 case 0x08: { // Modify original airport
3615 byte subs_id = buf->ReadByte();
3617 if (subs_id == 0xFF) {
3618 /* Instead of defining a new airport, an airport id
3619 * of 0xFF disables the old airport with the current id. */
3620 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3621 continue;
3622 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3623 /* The substitute id must be one of the original airports. */
3624 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3625 continue;
3628 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3629 /* Allocate space for this airport.
3630 * Only need to do it once. If ever it is called again, it should not
3631 * do anything */
3632 if (*spec == NULL) {
3633 *spec = MallocT<AirportSpec>(1);
3634 as = *spec;
3636 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3637 as->enabled = true;
3638 as->grf_prop.local_id = airport + i;
3639 as->grf_prop.subst_id = subs_id;
3640 as->grf_prop.grffile = _cur.grffile;
3641 /* override the default airport */
3642 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3643 /* Create a copy of the original tiletable so it can be freed later. */
3644 DuplicateTileTable(as);
3646 break;
3649 case 0x0A: { // Set airport layout
3650 as->num_table = buf->ReadByte(); // Number of layaouts
3651 as->rotation = MallocT<Direction>(as->num_table);
3652 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3653 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3654 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3655 int size;
3656 const AirportTileTable *copy_from;
3657 try {
3658 for (byte j = 0; j < as->num_table; j++) {
3659 as->rotation[j] = (Direction)buf->ReadByte();
3660 for (int k = 0;; k++) {
3661 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3662 att[k].ti.y = buf->ReadByte();
3664 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3665 /* Not the same terminator. The one we are using is rather
3666 * x = -80, y = 0 . So, adjust it. */
3667 att[k].ti.x = -0x80;
3668 att[k].ti.y = 0;
3669 att[k].gfx = 0;
3671 size = k + 1;
3672 copy_from = att;
3673 break;
3676 att[k].gfx = buf->ReadByte();
3678 if (att[k].gfx == 0xFE) {
3679 /* Use a new tile from this GRF */
3680 int local_tile_id = buf->ReadWord();
3682 /* Read the ID from the _airporttile_mngr. */
3683 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3685 if (tempid == INVALID_AIRPORTTILE) {
3686 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3687 } else {
3688 /* Declared as been valid, can be used */
3689 att[k].gfx = tempid;
3690 size = k + 1;
3691 copy_from = att;
3693 } else if (att[k].gfx == 0xFF) {
3694 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3695 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3698 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3699 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3700 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3701 } else {
3702 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3703 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3706 tile_table[j] = CallocT<AirportTileTable>(size);
3707 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3709 /* Install final layout construction in the airport spec */
3710 as->table = tile_table;
3711 free(att);
3712 } catch (...) {
3713 for (int i = 0; i < as->num_table; i++) {
3714 free(tile_table[i]);
3716 free(tile_table);
3717 free(att);
3718 throw;
3720 break;
3723 case 0x0C:
3724 as->min_year = buf->ReadWord();
3725 as->max_year = buf->ReadWord();
3726 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3727 break;
3729 case 0x0D:
3730 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3731 break;
3733 case 0x0E:
3734 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3735 break;
3737 case 0x0F:
3738 as->noise_level = buf->ReadByte();
3739 break;
3741 case 0x10:
3742 as->name = buf->ReadWord();
3743 _string_to_grf_mapping[&as->name] = _cur.grffile->grfid;
3744 break;
3746 case 0x11: // Maintenance cost factor
3747 as->maintenance_cost = buf->ReadWord();
3748 break;
3750 default:
3751 ret = CIR_UNKNOWN;
3752 break;
3756 return ret;
3760 * Ignore properties for objects
3761 * @param prop The property to ignore.
3762 * @param buf The property value.
3763 * @return ChangeInfoResult.
3765 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3767 ChangeInfoResult ret = CIR_SUCCESS;
3769 switch (prop) {
3770 case 0x0B:
3771 case 0x0C:
3772 case 0x0D:
3773 case 0x12:
3774 case 0x14:
3775 case 0x16:
3776 case 0x17:
3777 buf->ReadByte();
3778 break;
3780 case 0x09:
3781 case 0x0A:
3782 case 0x10:
3783 case 0x11:
3784 case 0x13:
3785 case 0x15:
3786 buf->ReadWord();
3787 break;
3789 case 0x08:
3790 case 0x0E:
3791 case 0x0F:
3792 buf->ReadDWord();
3793 break;
3795 default:
3796 ret = CIR_UNKNOWN;
3797 break;
3800 return ret;
3804 * Define properties for objects
3805 * @param id Local ID of the object.
3806 * @param numinfo Number of subsequent objectIDs to change the property for.
3807 * @param prop The property to change.
3808 * @param buf The property value.
3809 * @return ChangeInfoResult.
3811 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3813 ChangeInfoResult ret = CIR_SUCCESS;
3815 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3816 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3817 return CIR_INVALID_ID;
3820 /* Allocate object specs if they haven't been allocated already. */
3821 if (_cur.grffile->objectspec == NULL) {
3822 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3825 for (int i = 0; i < numinfo; i++) {
3826 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3828 if (prop != 0x08 && spec == NULL) {
3829 /* If the object property 08 is not yet set, ignore this property */
3830 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3831 if (cir > ret) ret = cir;
3832 continue;
3835 switch (prop) {
3836 case 0x08: { // Class ID
3837 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3839 /* Allocate space for this object. */
3840 if (*ospec == NULL) {
3841 *ospec = CallocT<ObjectSpec>(1);
3842 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3845 /* Swap classid because we read it in BE. */
3846 uint32 classid = buf->ReadDWord();
3847 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3848 (*ospec)->enabled = true;
3849 break;
3852 case 0x09: { // Class name
3853 StringID class_name = buf->ReadWord();
3854 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3855 objclass->name = class_name;
3856 _string_to_grf_mapping[&objclass->name] = _cur.grffile->grfid;
3857 break;
3860 case 0x0A: // Object name
3861 spec->name = buf->ReadWord();
3862 _string_to_grf_mapping[&spec->name] = _cur.grffile->grfid;
3863 break;
3865 case 0x0B: // Climate mask
3866 spec->climate = buf->ReadByte();
3867 break;
3869 case 0x0C: // Size
3870 spec->size = buf->ReadByte();
3871 break;
3873 case 0x0D: // Build cost multipler
3874 spec->build_cost_multiplier = buf->ReadByte();
3875 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3876 break;
3878 case 0x0E: // Introduction date
3879 spec->introduction_date = buf->ReadDWord();
3880 break;
3882 case 0x0F: // End of life
3883 spec->end_of_life_date = buf->ReadDWord();
3884 break;
3886 case 0x10: // Flags
3887 spec->flags = (ObjectFlags)buf->ReadWord();
3888 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3889 break;
3891 case 0x11: // Animation info
3892 spec->animation.frames = buf->ReadByte();
3893 spec->animation.status = buf->ReadByte();
3894 break;
3896 case 0x12: // Animation speed
3897 spec->animation.speed = buf->ReadByte();
3898 break;
3900 case 0x13: // Animation triggers
3901 spec->animation.triggers = buf->ReadWord();
3902 break;
3904 case 0x14: // Removal cost multiplier
3905 spec->clear_cost_multiplier = buf->ReadByte();
3906 break;
3908 case 0x15: // Callback mask
3909 spec->callback_mask = buf->ReadWord();
3910 break;
3912 case 0x16: // Building height
3913 spec->height = buf->ReadByte();
3914 break;
3916 case 0x17: // Views
3917 spec->views = buf->ReadByte();
3918 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
3919 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
3920 spec->views = 1;
3922 break;
3924 case 0x18: // Amount placed on 256^2 map on map creation
3925 spec->generate_amount = buf->ReadByte();
3926 break;
3928 default:
3929 ret = CIR_UNKNOWN;
3930 break;
3934 return ret;
3938 * Define properties for railtypes
3939 * @param id ID of the railtype.
3940 * @param numinfo Number of subsequent IDs to change the property for.
3941 * @param prop The property to change.
3942 * @param buf The property value.
3943 * @return ChangeInfoResult.
3945 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3947 ChangeInfoResult ret = CIR_SUCCESS;
3949 extern RailtypeInfo _railtypes[RAILTYPE_END];
3951 if (id + numinfo > RAILTYPE_END) {
3952 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
3953 return CIR_INVALID_ID;
3956 for (int i = 0; i < numinfo; i++) {
3957 RailType rt = _cur.grffile->railtype_map[id + i];
3958 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
3960 RailtypeInfo *rti = &_railtypes[rt];
3962 switch (prop) {
3963 case 0x08: // Label of rail type
3964 /* Skipped here as this is loaded during reservation stage. */
3965 buf->ReadDWord();
3966 break;
3968 case 0x09: // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
3969 rti->strings.toolbar_caption = buf->ReadWord();
3970 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur.grffile->grfid;
3971 if (_cur.grffile->grf_version < 8) {
3972 rti->strings.name = rti->strings.toolbar_caption;
3973 _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
3975 break;
3977 case 0x0A: // Menu text of railtype
3978 rti->strings.menu_text = buf->ReadWord();
3979 _string_to_grf_mapping[&rti->strings.menu_text] = _cur.grffile->grfid;
3980 break;
3982 case 0x0B: // Build window caption
3983 rti->strings.build_caption = buf->ReadWord();
3984 _string_to_grf_mapping[&rti->strings.build_caption] = _cur.grffile->grfid;
3985 break;
3987 case 0x0C: // Autoreplace text
3988 rti->strings.replace_text = buf->ReadWord();
3989 _string_to_grf_mapping[&rti->strings.replace_text] = _cur.grffile->grfid;
3990 break;
3992 case 0x0D: // New locomotive text
3993 rti->strings.new_loco = buf->ReadWord();
3994 _string_to_grf_mapping[&rti->strings.new_loco] = _cur.grffile->grfid;
3995 break;
3997 case 0x0E: // Compatible railtype list
3998 case 0x0F: // Powered railtype list
3999 case 0x18: // Railtype list required for date introduction
4000 case 0x19: // Introduced railtype list
4002 /* Rail type compatibility bits are added to the existing bits
4003 * to allow multiple GRFs to modify compatibility with the
4004 * default rail types. */
4005 int n = buf->ReadByte();
4006 for (int j = 0; j != n; j++) {
4007 RailTypeLabel label = buf->ReadDWord();
4008 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4009 if (rt != INVALID_RAILTYPE) {
4010 switch (prop) {
4011 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4012 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4013 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4014 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4018 break;
4021 case 0x10: // Rail Type flags
4022 rti->flags = (RailTypeFlags)buf->ReadByte();
4023 break;
4025 case 0x11: // Curve speed advantage
4026 rti->curve_speed = buf->ReadByte();
4027 break;
4029 case 0x12: // Station graphic
4030 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4031 break;
4033 case 0x13: // Construction cost factor
4034 rti->cost_multiplier = buf->ReadWord();
4035 break;
4037 case 0x14: // Speed limit
4038 rti->max_speed = buf->ReadWord();
4039 break;
4041 case 0x15: // Acceleration model
4042 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4043 break;
4045 case 0x16: // Map colour
4046 rti->map_colour = buf->ReadByte();
4047 break;
4049 case 0x17: // Introduction date
4050 rti->introduction_date = buf->ReadDWord();
4051 break;
4053 case 0x1A: // Sort order
4054 rti->sorting_order = buf->ReadByte();
4055 break;
4057 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4058 rti->strings.name = buf->ReadWord();
4059 _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
4060 break;
4062 case 0x1C: // Maintenance cost factor
4063 rti->maintenance_multiplier = buf->ReadWord();
4064 break;
4066 case 0x1D: // Alternate rail type label list
4067 /* Skipped here as this is loaded during reservation stage. */
4068 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4069 break;
4071 default:
4072 ret = CIR_UNKNOWN;
4073 break;
4077 return ret;
4080 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4082 ChangeInfoResult ret = CIR_SUCCESS;
4084 extern RailtypeInfo _railtypes[RAILTYPE_END];
4086 if (id + numinfo > RAILTYPE_END) {
4087 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4088 return CIR_INVALID_ID;
4091 for (int i = 0; i < numinfo; i++) {
4092 switch (prop) {
4093 case 0x08: // Label of rail type
4095 RailTypeLabel rtl = buf->ReadDWord();
4096 rtl = BSWAP32(rtl);
4098 RailType rt = GetRailTypeByLabel(rtl, false);
4099 if (rt == INVALID_RAILTYPE) {
4100 /* Set up new rail type */
4101 rt = AllocateRailType(rtl);
4104 _cur.grffile->railtype_map[id + i] = rt;
4105 break;
4108 case 0x09: // Toolbar caption of railtype
4109 case 0x0A: // Menu text
4110 case 0x0B: // Build window caption
4111 case 0x0C: // Autoreplace text
4112 case 0x0D: // New loco
4113 case 0x13: // Construction cost
4114 case 0x14: // Speed limit
4115 case 0x1B: // Name of railtype
4116 case 0x1C: // Maintenance cost factor
4117 buf->ReadWord();
4118 break;
4120 case 0x1D: // Alternate rail type label list
4121 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4122 int n = buf->ReadByte();
4123 for (int j = 0; j != n; j++) {
4124 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4126 break;
4128 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4129 /* FALL THROUGH */
4131 case 0x0E: // Compatible railtype list
4132 case 0x0F: // Powered railtype list
4133 case 0x18: // Railtype list required for date introduction
4134 case 0x19: // Introduced railtype list
4135 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4136 break;
4138 case 0x10: // Rail Type flags
4139 case 0x11: // Curve speed advantage
4140 case 0x12: // Station graphic
4141 case 0x15: // Acceleration model
4142 case 0x16: // Map colour
4143 case 0x1A: // Sort order
4144 buf->ReadByte();
4145 break;
4147 case 0x17: // Introduction date
4148 buf->ReadDWord();
4149 break;
4151 default:
4152 ret = CIR_UNKNOWN;
4153 break;
4157 return ret;
4160 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4162 ChangeInfoResult ret = CIR_SUCCESS;
4164 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4165 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4166 return CIR_INVALID_ID;
4169 /* Allocate airport tile specs if they haven't been allocated already. */
4170 if (_cur.grffile->airtspec == NULL) {
4171 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4174 for (int i = 0; i < numinfo; i++) {
4175 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4177 if (prop != 0x08 && tsp == NULL) {
4178 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4179 return CIR_INVALID_ID;
4182 switch (prop) {
4183 case 0x08: { // Substitute airport tile type
4184 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4185 byte subs_id = buf->ReadByte();
4187 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4188 /* The substitute id must be one of the original airport tiles. */
4189 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4190 continue;
4193 /* Allocate space for this airport tile. */
4194 if (*tilespec == NULL) {
4195 *tilespec = CallocT<AirportTileSpec>(1);
4196 tsp = *tilespec;
4198 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4199 tsp->enabled = true;
4201 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4203 tsp->grf_prop.local_id = airtid + i;
4204 tsp->grf_prop.subst_id = subs_id;
4205 tsp->grf_prop.grffile = _cur.grffile;
4206 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4208 break;
4211 case 0x09: { // Airport tile override
4212 byte override = buf->ReadByte();
4214 /* The airport tile being overridden must be an original airport tile. */
4215 if (override >= NEW_AIRPORTTILE_OFFSET) {
4216 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4217 continue;
4220 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4221 break;
4224 case 0x0E: // Callback mask
4225 tsp->callback_mask = buf->ReadByte();
4226 break;
4228 case 0x0F: // Animation information
4229 tsp->animation.frames = buf->ReadByte();
4230 tsp->animation.status = buf->ReadByte();
4231 break;
4233 case 0x10: // Animation speed
4234 tsp->animation.speed = buf->ReadByte();
4235 break;
4237 case 0x11: // Animation triggers
4238 tsp->animation.triggers = buf->ReadByte();
4239 break;
4241 default:
4242 ret = CIR_UNKNOWN;
4243 break;
4247 return ret;
4250 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4252 switch (cir) {
4253 default: NOT_REACHED();
4255 case CIR_DISABLED:
4256 /* Error has already been printed; just stop parsing */
4257 return true;
4259 case CIR_SUCCESS:
4260 return false;
4262 case CIR_UNHANDLED:
4263 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4264 return false;
4266 case CIR_UNKNOWN:
4267 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4268 /* FALL THROUGH */
4270 case CIR_INVALID_ID: {
4271 /* No debug message for an invalid ID, as it has already been output */
4272 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4273 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4274 return true;
4279 /* Action 0x00 */
4280 static void FeatureChangeInfo(ByteReader *buf)
4282 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4284 * B feature
4285 * B num-props how many properties to change per vehicle/station
4286 * B num-info how many vehicles/stations to change
4287 * E id ID of first vehicle/station to change, if num-info is
4288 * greater than one, this one and the following
4289 * vehicles/stations will be changed
4290 * B property what property to change, depends on the feature
4291 * V new-info new bytes of info (variable size; depends on properties) */
4293 static const VCI_Handler handler[] = {
4294 /* GSF_TRAINS */ RailVehicleChangeInfo,
4295 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4296 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4297 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4298 /* GSF_STATIONS */ StationChangeInfo,
4299 /* GSF_CANALS */ CanalChangeInfo,
4300 /* GSF_BRIDGES */ BridgeChangeInfo,
4301 /* GSF_HOUSES */ TownHouseChangeInfo,
4302 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4303 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4304 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4305 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4306 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4307 /* GSF_AIRPORTS */ AirportChangeInfo,
4308 /* GSF_SIGNALS */ NULL,
4309 /* GSF_OBJECTS */ ObjectChangeInfo,
4310 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4311 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4314 uint8 feature = buf->ReadByte();
4315 uint8 numprops = buf->ReadByte();
4316 uint numinfo = buf->ReadByte();
4317 uint engine = buf->ReadExtendedByte();
4319 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4320 feature, numprops, engine, numinfo);
4322 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4323 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4324 return;
4327 /* Mark the feature as used by the grf */
4328 SetBit(_cur.grffile->grf_features, feature);
4330 while (numprops-- && buf->HasData()) {
4331 uint8 prop = buf->ReadByte();
4333 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4334 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4338 /* Action 0x00 (GLS_SAFETYSCAN) */
4339 static void SafeChangeInfo(ByteReader *buf)
4341 uint8 feature = buf->ReadByte();
4342 uint8 numprops = buf->ReadByte();
4343 uint numinfo = buf->ReadByte();
4344 buf->ReadExtendedByte(); // id
4346 if (feature == GSF_BRIDGES && numprops == 1) {
4347 uint8 prop = buf->ReadByte();
4348 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4349 * is considered safe. */
4350 if (prop == 0x0D) return;
4351 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4352 uint8 prop = buf->ReadByte();
4353 /* Engine ID Mappings are safe, if the source is static */
4354 if (prop == 0x11) {
4355 bool is_safe = true;
4356 for (uint i = 0; i < numinfo; i++) {
4357 uint32 s = buf->ReadDWord();
4358 buf->ReadDWord(); // dest
4359 const GRFConfig *grfconfig = GetGRFConfig(s);
4360 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4361 is_safe = false;
4362 break;
4365 if (is_safe) return;
4369 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4371 /* Skip remainder of GRF */
4372 _cur.skip_sprites = -1;
4375 /* Action 0x00 (GLS_RESERVE) */
4376 static void ReserveChangeInfo(ByteReader *buf)
4378 uint8 feature = buf->ReadByte();
4380 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4382 uint8 numprops = buf->ReadByte();
4383 uint8 numinfo = buf->ReadByte();
4384 uint8 index = buf->ReadExtendedByte();
4386 while (numprops-- && buf->HasData()) {
4387 uint8 prop = buf->ReadByte();
4388 ChangeInfoResult cir = CIR_SUCCESS;
4390 switch (feature) {
4391 default: NOT_REACHED();
4392 case GSF_CARGOES:
4393 cir = CargoChangeInfo(index, numinfo, prop, buf);
4394 break;
4396 case GSF_GLOBALVAR:
4397 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4398 break;
4400 case GSF_RAILTYPES:
4401 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4402 break;
4405 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4409 /* Action 0x01 */
4410 static void NewSpriteSet(ByteReader *buf)
4412 /* Basic format: <01> <feature> <num-sets> <num-ent>
4413 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4415 * B feature feature to define sprites for
4416 * 0, 1, 2, 3: veh-type, 4: train stations
4417 * E first-set first sprite set to define
4418 * B num-sets number of sprite sets (extended byte in extended format)
4419 * E num-ent how many entries per sprite set
4420 * For vehicles, this is the number of different
4421 * vehicle directions in each sprite set
4422 * Set num-dirs=8, unless your sprites are symmetric.
4423 * In that case, use num-dirs=4.
4426 uint8 feature = buf->ReadByte();
4427 uint16 num_sets = buf->ReadByte();
4428 uint16 first_set = 0;
4430 if (num_sets == 0 && buf->HasData(3)) {
4431 /* Extended Action1 format.
4432 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4433 first_set = buf->ReadExtendedByte();
4434 num_sets = buf->ReadExtendedByte();
4436 uint16 num_ents = buf->ReadExtendedByte();
4438 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4440 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4441 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4444 for (int i = 0; i < num_sets * num_ents; i++) {
4445 _cur.nfo_line++;
4446 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4450 /* Action 0x01 (SKIP) */
4451 static void SkipAct1(ByteReader *buf)
4453 buf->ReadByte();
4454 uint16 num_sets = buf->ReadByte();
4456 if (num_sets == 0 && buf->HasData(3)) {
4457 /* Extended Action1 format.
4458 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4459 buf->ReadExtendedByte(); // first_set
4460 num_sets = buf->ReadExtendedByte();
4462 uint16 num_ents = buf->ReadExtendedByte();
4464 _cur.skip_sprites = num_sets * num_ents;
4466 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4469 /* Helper function to either create a callback or link to a previously
4470 * defined spritegroup. */
4471 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4473 if (HasBit(groupid, 15)) {
4474 assert(CallbackResultSpriteGroup::CanAllocateItem());
4475 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4478 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4479 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4480 return NULL;
4483 return _cur.spritegroups[groupid];
4487 * Helper function to either create a callback or a result sprite group.
4488 * @param feature GrfSpecFeature to define spritegroup for.
4489 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4490 * @param type Type of the currently being parsed Action2. (only for debug output)
4491 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4492 * @return Created spritegroup.
4494 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4496 if (HasBit(spriteid, 15)) {
4497 assert(CallbackResultSpriteGroup::CanAllocateItem());
4498 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4501 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4502 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4503 return NULL;
4506 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4507 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4509 /* Ensure that the sprites are loeded */
4510 assert(spriteset_start + num_sprites <= _cur.spriteid);
4512 assert(ResultSpriteGroup::CanAllocateItem());
4513 return new ResultSpriteGroup(spriteset_start, num_sprites);
4516 /* Action 0x02 */
4517 static void NewSpriteGroup(ByteReader *buf)
4519 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4521 * B feature see action 1
4522 * B set-id ID of this particular definition
4523 * B type/num-entries
4524 * if 80 or greater, this is a randomized or variational
4525 * list definition, see below
4526 * otherwise it specifies a number of entries, the exact
4527 * meaning depends on the feature
4528 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4529 SpriteGroup *act_group = NULL;
4531 uint8 feature = buf->ReadByte();
4532 uint8 setid = buf->ReadByte();
4533 uint8 type = buf->ReadByte();
4535 /* Sprite Groups are created here but they are allocated from a pool, so
4536 * we do not need to delete anything if there is an exception from the
4537 * ByteReader. */
4539 switch (type) {
4540 /* Deterministic Sprite Group */
4541 case 0x81: // Self scope, byte
4542 case 0x82: // Parent scope, byte
4543 case 0x85: // Self scope, word
4544 case 0x86: // Parent scope, word
4545 case 0x89: // Self scope, dword
4546 case 0x8A: // Parent scope, dword
4548 byte varadjust;
4549 byte varsize;
4551 assert(DeterministicSpriteGroup::CanAllocateItem());
4552 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4553 act_group = group;
4554 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4556 switch (GB(type, 2, 2)) {
4557 default: NOT_REACHED();
4558 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4559 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4560 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4563 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4564 adjusts.Clear();
4566 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4567 * from the outset, so we shall have to keep reallocing. */
4568 do {
4569 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4571 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4572 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4573 adjust->variable = buf->ReadByte();
4574 if (adjust->variable == 0x7E) {
4575 /* Link subroutine group */
4576 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4577 } else {
4578 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4581 varadjust = buf->ReadByte();
4582 adjust->shift_num = GB(varadjust, 0, 5);
4583 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4584 adjust->and_mask = buf->ReadVarSize(varsize);
4586 if (adjust->type != DSGA_TYPE_NONE) {
4587 adjust->add_val = buf->ReadVarSize(varsize);
4588 adjust->divmod_val = buf->ReadVarSize(varsize);
4589 } else {
4590 adjust->add_val = 0;
4591 adjust->divmod_val = 0;
4594 /* Continue reading var adjusts while bit 5 is set. */
4595 } while (HasBit(varadjust, 5));
4597 group->num_adjusts = adjusts.Length();
4598 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4599 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4601 group->num_ranges = buf->ReadByte();
4602 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4604 for (uint i = 0; i < group->num_ranges; i++) {
4605 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4606 group->ranges[i].low = buf->ReadVarSize(varsize);
4607 group->ranges[i].high = buf->ReadVarSize(varsize);
4610 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4611 break;
4614 /* Randomized Sprite Group */
4615 case 0x80: // Self scope
4616 case 0x83: // Parent scope
4617 case 0x84: // Relative scope
4619 assert(RandomizedSpriteGroup::CanAllocateItem());
4620 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4621 act_group = group;
4622 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4624 if (HasBit(type, 2)) {
4625 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4626 group->count = buf->ReadByte();
4629 uint8 triggers = buf->ReadByte();
4630 group->triggers = GB(triggers, 0, 7);
4631 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4632 group->lowest_randbit = buf->ReadByte();
4633 group->num_groups = buf->ReadByte();
4634 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4636 for (uint i = 0; i < group->num_groups; i++) {
4637 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4640 break;
4643 /* Neither a variable or randomized sprite group... must be a real group */
4644 default:
4646 switch (feature) {
4647 case GSF_TRAINS:
4648 case GSF_ROADVEHICLES:
4649 case GSF_SHIPS:
4650 case GSF_AIRCRAFT:
4651 case GSF_STATIONS:
4652 case GSF_CANALS:
4653 case GSF_CARGOES:
4654 case GSF_AIRPORTS:
4655 case GSF_RAILTYPES:
4657 byte num_loaded = type;
4658 byte num_loading = buf->ReadByte();
4660 if (!_cur.HasValidSpriteSets(feature)) {
4661 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4662 return;
4665 assert(RealSpriteGroup::CanAllocateItem());
4666 RealSpriteGroup *group = new RealSpriteGroup();
4667 act_group = group;
4669 group->num_loaded = num_loaded;
4670 group->num_loading = num_loading;
4671 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4672 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4674 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4675 setid, num_loaded, num_loading);
4677 for (uint i = 0; i < num_loaded; i++) {
4678 uint16 spriteid = buf->ReadWord();
4679 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4680 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4683 for (uint i = 0; i < num_loading; i++) {
4684 uint16 spriteid = buf->ReadWord();
4685 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4686 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4689 break;
4692 case GSF_HOUSES:
4693 case GSF_AIRPORTTILES:
4694 case GSF_OBJECTS:
4695 case GSF_INDUSTRYTILES: {
4696 byte num_building_sprites = max((uint8)1, type);
4698 assert(TileLayoutSpriteGroup::CanAllocateItem());
4699 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4700 act_group = group;
4702 /* On error, bail out immediately. Temporary GRF data was already freed */
4703 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4704 break;
4707 case GSF_INDUSTRIES: {
4708 if (type > 1) {
4709 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4710 break;
4713 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4714 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4715 act_group = group;
4716 group->version = type;
4717 if (type == 0) {
4718 for (uint i = 0; i < 3; i++) {
4719 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4721 for (uint i = 0; i < 2; i++) {
4722 group->add_output[i] = buf->ReadWord(); // unsigned
4724 group->again = buf->ReadByte();
4725 } else {
4726 for (uint i = 0; i < 3; i++) {
4727 group->subtract_input[i] = buf->ReadByte();
4729 for (uint i = 0; i < 2; i++) {
4730 group->add_output[i] = buf->ReadByte();
4732 group->again = buf->ReadByte();
4734 break;
4737 /* Loading of Tile Layout and Production Callback groups would happen here */
4738 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4743 _cur.spritegroups[setid] = act_group;
4746 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4748 if (feature == GSF_OBJECTS) {
4749 switch (ctype) {
4750 case 0: return 0;
4751 case 0xFF: return CT_PURCHASE_OBJECT;
4752 default:
4753 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4754 return CT_INVALID;
4757 /* Special cargo types for purchase list and stations */
4758 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4759 if (ctype == 0xFF) return CT_PURCHASE;
4761 if (_cur.grffile->cargo_list.Length() == 0) {
4762 /* No cargo table, so use bitnum values */
4763 if (ctype >= 32) {
4764 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4765 return CT_INVALID;
4768 const CargoSpec *cs;
4769 FOR_ALL_CARGOSPECS(cs) {
4770 if (cs->bitnum == ctype) {
4771 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4772 return cs->Index();
4776 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4777 return CT_INVALID;
4780 /* Check if the cargo type is out of bounds of the cargo translation table */
4781 if (ctype >= _cur.grffile->cargo_list.Length()) {
4782 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4783 return CT_INVALID;
4786 /* Look up the cargo label from the translation table */
4787 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4788 if (cl == 0) {
4789 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4790 return CT_INVALID;
4793 ctype = GetCargoIDByLabel(cl);
4794 if (ctype == CT_INVALID) {
4795 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));
4796 return CT_INVALID;
4799 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);
4800 return ctype;
4804 static bool IsValidGroupID(uint16 groupid, const char *function)
4806 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4807 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4808 return false;
4811 return true;
4814 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4816 static EngineID *last_engines;
4817 static uint last_engines_count;
4818 bool wagover = false;
4820 /* Test for 'wagon override' flag */
4821 if (HasBit(idcount, 7)) {
4822 wagover = true;
4823 /* Strip off the flag */
4824 idcount = GB(idcount, 0, 7);
4826 if (last_engines_count == 0) {
4827 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4828 return;
4831 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4832 last_engines_count, idcount);
4833 } else {
4834 if (last_engines_count != idcount) {
4835 last_engines = ReallocT(last_engines, idcount);
4836 last_engines_count = idcount;
4840 EngineID *engines = AllocaM(EngineID, idcount);
4841 for (uint i = 0; i < idcount; i++) {
4842 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4843 if (e == NULL) {
4844 /* No engine could be allocated?!? Deal with it. Okay,
4845 * this might look bad. Also make sure this NewGRF
4846 * gets disabled, as a half loaded one is bad. */
4847 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4848 return;
4851 engines[i] = e->index;
4852 if (!wagover) last_engines[i] = engines[i];
4855 uint8 cidcount = buf->ReadByte();
4856 for (uint c = 0; c < cidcount; c++) {
4857 uint8 ctype = buf->ReadByte();
4858 uint16 groupid = buf->ReadWord();
4859 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4861 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4863 ctype = TranslateCargo(feature, ctype);
4864 if (ctype == CT_INVALID) continue;
4866 for (uint i = 0; i < idcount; i++) {
4867 EngineID engine = engines[i];
4869 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4871 if (wagover) {
4872 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4873 } else {
4874 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4879 uint16 groupid = buf->ReadWord();
4880 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
4882 grfmsg(8, "-- Default group id 0x%04X", groupid);
4884 for (uint i = 0; i < idcount; i++) {
4885 EngineID engine = engines[i];
4887 if (wagover) {
4888 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4889 } else {
4890 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4891 SetEngineGRF(engine, _cur.grffile);
4897 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4899 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
4900 for (uint i = 0; i < idcount; i++) {
4901 cfs[i] = (CanalFeature)buf->ReadByte();
4904 uint8 cidcount = buf->ReadByte();
4905 buf->Skip(cidcount * 3);
4907 uint16 groupid = buf->ReadWord();
4908 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
4910 for (uint i = 0; i < idcount; i++) {
4911 CanalFeature cf = cfs[i];
4913 if (cf >= CF_END) {
4914 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
4915 continue;
4918 _water_feature[cf].grffile = _cur.grffile;
4919 _water_feature[cf].group = _cur.spritegroups[groupid];
4924 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
4926 uint8 *stations = AllocaM(uint8, idcount);
4927 for (uint i = 0; i < idcount; i++) {
4928 stations[i] = buf->ReadByte();
4931 uint8 cidcount = buf->ReadByte();
4932 for (uint c = 0; c < cidcount; c++) {
4933 uint8 ctype = buf->ReadByte();
4934 uint16 groupid = buf->ReadWord();
4935 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
4937 ctype = TranslateCargo(GSF_STATIONS, ctype);
4938 if (ctype == CT_INVALID) continue;
4940 for (uint i = 0; i < idcount; i++) {
4941 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
4943 if (statspec == NULL) {
4944 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
4945 continue;
4948 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
4952 uint16 groupid = buf->ReadWord();
4953 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
4955 for (uint i = 0; i < idcount; i++) {
4956 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
4958 if (statspec == NULL) {
4959 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
4960 continue;
4963 if (statspec->grf_prop.grffile != NULL) {
4964 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
4965 continue;
4968 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
4969 statspec->grf_prop.grffile = _cur.grffile;
4970 statspec->grf_prop.local_id = stations[i];
4971 StationClass::Assign(statspec);
4976 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
4978 uint8 *houses = AllocaM(uint8, idcount);
4979 for (uint i = 0; i < idcount; i++) {
4980 houses[i] = buf->ReadByte();
4983 /* Skip the cargo type section, we only care about the default group */
4984 uint8 cidcount = buf->ReadByte();
4985 buf->Skip(cidcount * 3);
4987 uint16 groupid = buf->ReadWord();
4988 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
4990 if (_cur.grffile->housespec == NULL) {
4991 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
4992 return;
4995 for (uint i = 0; i < idcount; i++) {
4996 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
4998 if (hs == NULL) {
4999 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5000 continue;
5003 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5007 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5009 uint8 *industries = AllocaM(uint8, idcount);
5010 for (uint i = 0; i < idcount; i++) {
5011 industries[i] = buf->ReadByte();
5014 /* Skip the cargo type section, we only care about the default group */
5015 uint8 cidcount = buf->ReadByte();
5016 buf->Skip(cidcount * 3);
5018 uint16 groupid = buf->ReadWord();
5019 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5021 if (_cur.grffile->industryspec == NULL) {
5022 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5023 return;
5026 for (uint i = 0; i < idcount; i++) {
5027 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5029 if (indsp == NULL) {
5030 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5031 continue;
5034 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5038 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5040 uint8 *indtiles = AllocaM(uint8, idcount);
5041 for (uint i = 0; i < idcount; i++) {
5042 indtiles[i] = buf->ReadByte();
5045 /* Skip the cargo type section, we only care about the default group */
5046 uint8 cidcount = buf->ReadByte();
5047 buf->Skip(cidcount * 3);
5049 uint16 groupid = buf->ReadWord();
5050 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5052 if (_cur.grffile->indtspec == NULL) {
5053 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5054 return;
5057 for (uint i = 0; i < idcount; i++) {
5058 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5060 if (indtsp == NULL) {
5061 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5062 continue;
5065 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5069 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5071 CargoID *cargoes = AllocaM(CargoID, idcount);
5072 for (uint i = 0; i < idcount; i++) {
5073 cargoes[i] = buf->ReadByte();
5076 /* Skip the cargo type section, we only care about the default group */
5077 uint8 cidcount = buf->ReadByte();
5078 buf->Skip(cidcount * 3);
5080 uint16 groupid = buf->ReadWord();
5081 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5083 for (uint i = 0; i < idcount; i++) {
5084 CargoID cid = cargoes[i];
5086 if (cid >= NUM_CARGO) {
5087 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5088 continue;
5091 CargoSpec *cs = CargoSpec::Get(cid);
5092 cs->grffile = _cur.grffile;
5093 cs->group = _cur.spritegroups[groupid];
5097 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5099 if (_cur.grffile->objectspec == NULL) {
5100 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5101 return;
5104 uint8 *objects = AllocaM(uint8, idcount);
5105 for (uint i = 0; i < idcount; i++) {
5106 objects[i] = buf->ReadByte();
5109 uint8 cidcount = buf->ReadByte();
5110 for (uint c = 0; c < cidcount; c++) {
5111 uint8 ctype = buf->ReadByte();
5112 uint16 groupid = buf->ReadWord();
5113 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5115 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5116 if (ctype == CT_INVALID) continue;
5118 for (uint i = 0; i < idcount; i++) {
5119 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5121 if (spec == NULL) {
5122 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5123 continue;
5126 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5130 uint16 groupid = buf->ReadWord();
5131 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5133 for (uint i = 0; i < idcount; i++) {
5134 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5136 if (spec == NULL) {
5137 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5138 continue;
5141 if (spec->grf_prop.grffile != NULL) {
5142 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5143 continue;
5146 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5147 spec->grf_prop.grffile = _cur.grffile;
5148 spec->grf_prop.local_id = objects[i];
5152 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5154 uint8 *railtypes = AllocaM(uint8, idcount);
5155 for (uint i = 0; i < idcount; i++) {
5156 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5159 uint8 cidcount = buf->ReadByte();
5160 for (uint c = 0; c < cidcount; c++) {
5161 uint8 ctype = buf->ReadByte();
5162 uint16 groupid = buf->ReadWord();
5163 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5165 if (ctype >= RTSG_END) continue;
5167 extern RailtypeInfo _railtypes[RAILTYPE_END];
5168 for (uint i = 0; i < idcount; i++) {
5169 if (railtypes[i] != INVALID_RAILTYPE) {
5170 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5172 rti->grffile[ctype] = _cur.grffile;
5173 rti->group[ctype] = _cur.spritegroups[groupid];
5178 /* Railtypes do not use the default group. */
5179 buf->ReadWord();
5182 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5184 uint8 *airports = AllocaM(uint8, idcount);
5185 for (uint i = 0; i < idcount; i++) {
5186 airports[i] = buf->ReadByte();
5189 /* Skip the cargo type section, we only care about the default group */
5190 uint8 cidcount = buf->ReadByte();
5191 buf->Skip(cidcount * 3);
5193 uint16 groupid = buf->ReadWord();
5194 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5196 if (_cur.grffile->airportspec == NULL) {
5197 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5198 return;
5201 for (uint i = 0; i < idcount; i++) {
5202 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5204 if (as == NULL) {
5205 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5206 continue;
5209 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5213 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5215 uint8 *airptiles = AllocaM(uint8, idcount);
5216 for (uint i = 0; i < idcount; i++) {
5217 airptiles[i] = buf->ReadByte();
5220 /* Skip the cargo type section, we only care about the default group */
5221 uint8 cidcount = buf->ReadByte();
5222 buf->Skip(cidcount * 3);
5224 uint16 groupid = buf->ReadWord();
5225 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5227 if (_cur.grffile->airtspec == NULL) {
5228 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5229 return;
5232 for (uint i = 0; i < idcount; i++) {
5233 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5235 if (airtsp == NULL) {
5236 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5237 continue;
5240 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5245 /* Action 0x03 */
5246 static void FeatureMapSpriteGroup(ByteReader *buf)
5248 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5249 * id-list := [<id>] [id-list]
5250 * cargo-list := <cargo-type> <cid> [cargo-list]
5252 * B feature see action 0
5253 * B n-id bits 0-6: how many IDs this definition applies to
5254 * bit 7: if set, this is a wagon override definition (see below)
5255 * B ids the IDs for which this definition applies
5256 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5257 * can be zero, in that case the def-cid is used always
5258 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5259 * W cid cargo ID (sprite group ID) for this type of cargo
5260 * W def-cid default cargo ID (sprite group ID) */
5262 uint8 feature = buf->ReadByte();
5263 uint8 idcount = buf->ReadByte();
5265 /* If idcount is zero, this is a feature callback */
5266 if (idcount == 0) {
5267 /* Skip number of cargo ids? */
5268 buf->ReadByte();
5269 uint16 groupid = buf->ReadWord();
5270 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5272 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5274 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5275 return;
5278 /* Mark the feature as used by the grf (generic callbacks do not count) */
5279 SetBit(_cur.grffile->grf_features, feature);
5281 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5283 switch (feature) {
5284 case GSF_TRAINS:
5285 case GSF_ROADVEHICLES:
5286 case GSF_SHIPS:
5287 case GSF_AIRCRAFT:
5288 VehicleMapSpriteGroup(buf, feature, idcount);
5289 return;
5291 case GSF_CANALS:
5292 CanalMapSpriteGroup(buf, idcount);
5293 return;
5295 case GSF_STATIONS:
5296 StationMapSpriteGroup(buf, idcount);
5297 return;
5299 case GSF_HOUSES:
5300 TownHouseMapSpriteGroup(buf, idcount);
5301 return;
5303 case GSF_INDUSTRIES:
5304 IndustryMapSpriteGroup(buf, idcount);
5305 return;
5307 case GSF_INDUSTRYTILES:
5308 IndustrytileMapSpriteGroup(buf, idcount);
5309 return;
5311 case GSF_CARGOES:
5312 CargoMapSpriteGroup(buf, idcount);
5313 return;
5315 case GSF_AIRPORTS:
5316 AirportMapSpriteGroup(buf, idcount);
5317 return;
5319 case GSF_OBJECTS:
5320 ObjectMapSpriteGroup(buf, idcount);
5321 break;
5323 case GSF_RAILTYPES:
5324 RailTypeMapSpriteGroup(buf, idcount);
5325 break;
5327 case GSF_AIRPORTTILES:
5328 AirportTileMapSpriteGroup(buf, idcount);
5329 return;
5331 default:
5332 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5333 return;
5337 /* Action 0x04 */
5338 static void FeatureNewName(ByteReader *buf)
5340 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5342 * B veh-type see action 0 (as 00..07, + 0A
5343 * But IF veh-type = 48, then generic text
5344 * B language-id If bit 6 is set, This is the extended language scheme,
5345 * with up to 64 language.
5346 * Otherwise, it is a mapping where set bits have meaning
5347 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5348 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5349 * B num-veh number of vehicles which are getting a new name
5350 * B/W offset number of the first vehicle that gets a new name
5351 * Byte : ID of vehicle to change
5352 * Word : ID of string to change/add
5353 * S data new texts, each of them zero-terminated, after
5354 * which the next name begins. */
5356 bool new_scheme = _cur.grffile->grf_version >= 7;
5358 uint8 feature = buf->ReadByte();
5359 uint8 lang = buf->ReadByte();
5360 uint8 num = buf->ReadByte();
5361 bool generic = HasBit(lang, 7);
5362 uint16 id;
5363 if (generic) {
5364 id = buf->ReadWord();
5365 } else if (feature <= GSF_AIRCRAFT) {
5366 id = buf->ReadExtendedByte();
5367 } else {
5368 id = buf->ReadByte();
5371 ClrBit(lang, 7);
5373 uint16 endid = id + num;
5375 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5376 id, endid, feature, lang);
5378 for (; id < endid && buf->HasData(); id++) {
5379 const char *name = buf->ReadString();
5380 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5382 switch (feature) {
5383 case GSF_TRAINS:
5384 case GSF_ROADVEHICLES:
5385 case GSF_SHIPS:
5386 case GSF_AIRCRAFT:
5387 if (!generic) {
5388 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5389 if (e == NULL) break;
5390 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5391 e->info.string_id = string;
5392 } else {
5393 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5395 break;
5397 case GSF_INDUSTRIES: {
5398 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5399 break;
5402 case GSF_HOUSES:
5403 default:
5404 switch (GB(id, 8, 8)) {
5405 case 0xC4: // Station class name
5406 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5407 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5408 } else {
5409 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5410 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5412 break;
5414 case 0xC5: // Station name
5415 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5416 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5417 } else {
5418 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5420 break;
5422 case 0xC7: // Airporttile name
5423 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5424 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5425 } else {
5426 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5428 break;
5430 case 0xC9: // House name
5431 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5432 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5433 } else {
5434 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5436 break;
5438 case 0xD0:
5439 case 0xD1:
5440 case 0xD2:
5441 case 0xD3:
5442 case 0xDC:
5443 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5444 break;
5446 default:
5447 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5448 break;
5450 break;
5456 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5457 * @param num The number of sprites to load.
5458 * @param offset Offset from the base.
5459 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5460 * @param name Used for error warnings.
5461 * @return The number of sprites that is going to be skipped.
5463 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5466 if (offset >= max_sprites) {
5467 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5468 uint orig_num = num;
5469 num = 0;
5470 return orig_num;
5473 if (offset + num > max_sprites) {
5474 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5475 uint orig_num = num;
5476 num = max(max_sprites - offset, 0);
5477 return orig_num - num;
5480 return 0;
5484 /** The type of action 5 type. */
5485 enum Action5BlockType {
5486 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5487 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5488 A5BLOCK_INVALID, ///< unknown/not-implemented type
5490 /** Information about a single action 5 type. */
5491 struct Action5Type {
5492 Action5BlockType block_type; ///< How is this Action5 type processed?
5493 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5494 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5495 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5496 const char *name; ///< Name for error messages.
5499 /** The information about action 5 types. */
5500 static const Action5Type _action5_types[] = {
5501 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5502 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5503 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5504 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5505 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5506 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5507 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
5508 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5509 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5510 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5511 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5512 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5513 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5514 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5515 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5516 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5517 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5518 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5519 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5520 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5521 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5522 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5523 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5524 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5525 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5528 /* Action 0x05 */
5529 static void GraphicsNew(ByteReader *buf)
5531 /* <05> <graphics-type> <num-sprites> <other data...>
5533 * B graphics-type What set of graphics the sprites define.
5534 * E num-sprites How many sprites are in this set?
5535 * V other data Graphics type specific data. Currently unused. */
5536 /* TODO */
5538 uint8 type = buf->ReadByte();
5539 uint16 num = buf->ReadExtendedByte();
5540 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5541 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5543 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
5544 /* Special not-TTDP-compatible case used in openttd.grf
5545 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5546 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5547 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5548 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5549 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5550 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5551 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5552 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5553 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5554 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5555 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5556 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5557 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5558 return;
5561 /* Supported type? */
5562 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5563 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5564 _cur.skip_sprites = num;
5565 return;
5568 const Action5Type *action5_type = &_action5_types[type];
5570 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5571 * except for the long version of the shore type:
5572 * Ignore offset if not allowed */
5573 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5574 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5575 offset = 0;
5578 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5579 * This does not make sense, if <offset> is allowed */
5580 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5581 grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
5582 _cur.skip_sprites = num;
5583 return;
5586 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5587 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5588 SpriteID replace = action5_type->sprite_base + offset;
5590 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5591 grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
5593 for (; num > 0; num--) {
5594 _cur.nfo_line++;
5595 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5598 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5600 _cur.skip_sprites = skip_num;
5603 /* Action 0x05 (SKIP) */
5604 static void SkipAct5(ByteReader *buf)
5606 /* Ignore type byte */
5607 buf->ReadByte();
5609 /* Skip the sprites of this action */
5610 _cur.skip_sprites = buf->ReadExtendedByte();
5612 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5616 * Check whether we are (obviously) missing some of the extra
5617 * (Action 0x05) sprites that we like to use.
5618 * When missing sprites are found a warning will be shown.
5620 void CheckForMissingSprites()
5622 /* Don't break out quickly, but allow to check the other
5623 * sprites as well, so we can give the best information. */
5624 bool missing = false;
5625 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
5626 const Action5Type *type = &_action5_types[i];
5627 if (type->block_type == A5BLOCK_INVALID) continue;
5629 for (uint j = 0; j < type->max_sprites; j++) {
5630 if (!SpriteExists(type->sprite_base + j)) {
5631 DEBUG(grf, 0, "%s sprites are missing", type->name);
5632 missing = true;
5633 /* No need to log more of the same. */
5634 break;
5639 if (missing) {
5640 ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
5645 * Reads a variable common to VarAction2 and Action7/9/D.
5647 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5648 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5650 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5651 * @param value returns the value of the variable.
5652 * @param grffile NewGRF querying the variable
5653 * @return true iff the variable is known and the value is returned in 'value'.
5655 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5657 switch (param) {
5658 case 0x00: // current date
5659 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5660 return true;
5662 case 0x01: // current year
5663 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5664 return true;
5666 case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
5667 YearMonthDay ymd;
5668 ConvertDateToYMD(_date, &ymd);
5669 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5670 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5671 return true;
5674 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5675 *value = _settings_game.game_creation.landscape;
5676 return true;
5678 case 0x06: // road traffic side, bit 4 clear=left, set=right
5679 *value = _settings_game.vehicle.road_side << 4;
5680 return true;
5682 case 0x09: // date fraction
5683 *value = _date_fract * 885;
5684 return true;
5686 case 0x0A: // animation counter
5687 *value = _tick_counter;
5688 return true;
5690 case 0x0B: { // TTDPatch version
5691 uint major = 2;
5692 uint minor = 6;
5693 uint revision = 1; // special case: 2.0.1 is 2.0.10
5694 uint build = 1382;
5695 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5696 return true;
5699 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5700 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5701 return true;
5703 case 0x0E: // Y-offset for train sprites
5704 *value = _cur.grffile->traininfo_vehicle_pitch;
5705 return true;
5707 case 0x0F: // Rail track type cost factors
5708 *value = 0;
5709 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5710 if (_settings_game.vehicle.disable_elrails) {
5711 /* skip elrail multiplier - disabled */
5712 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5713 } else {
5714 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5715 /* Skip monorail multiplier - no space in result */
5717 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5718 return true;
5720 case 0x11: // current rail tool type
5721 *value = 0; // constant fake value to avoid desync
5722 return true;
5724 case 0x12: // Game mode
5725 *value = _game_mode;
5726 return true;
5728 /* case 0x13: // Tile refresh offset to left not implemented */
5729 /* case 0x14: // Tile refresh offset to right not implemented */
5730 /* case 0x15: // Tile refresh offset upwards not implemented */
5731 /* case 0x16: // Tile refresh offset downwards not implemented */
5732 /* case 0x17: // temperate snow line not implemented */
5734 case 0x1A: // Always -1
5735 *value = UINT_MAX;
5736 return true;
5738 case 0x1B: // Display options
5739 *value = 0x3F; // constant fake value to avoid desync
5740 return true;
5742 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5743 *value = 1;
5744 return true;
5746 case 0x1E: // Miscellaneous GRF features
5747 *value = _misc_grf_features;
5749 /* Add the local flags */
5750 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5751 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5752 return true;
5754 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5756 case 0x20: { // snow line height
5757 byte snowline = GetSnowLine();
5758 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
5759 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5760 } else {
5761 /* No snow */
5762 *value = 0xFF;
5764 return true;
5767 case 0x21: // OpenTTD version
5768 *value = _openttd_newgrf_version;
5769 return true;
5771 case 0x22: // difficulty level
5772 *value = SP_CUSTOM;
5773 return true;
5775 case 0x23: // long format date
5776 *value = _date;
5777 return true;
5779 case 0x24: // long format year
5780 *value = _cur_year;
5781 return true;
5783 default: return false;
5787 static uint32 GetParamVal(byte param, uint32 *cond_val)
5789 /* First handle variable common with VarAction2 */
5790 uint32 value;
5791 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5793 /* Non-common variable */
5794 switch (param) {
5795 case 0x84: { // GRF loading stage
5796 uint32 res = 0;
5798 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5799 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5800 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5801 return res;
5804 case 0x85: // TTDPatch flags, only for bit tests
5805 if (cond_val == NULL) {
5806 /* Supported in Action 0x07 and 0x09, not 0x0D */
5807 return 0;
5808 } else {
5809 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5810 *cond_val %= 0x20;
5811 return param_val;
5814 case 0x88: // GRF ID check
5815 return 0;
5817 /* case 0x99: Global ID offset not implemented */
5819 default:
5820 /* GRF Parameter */
5821 if (param < 0x80) return _cur.grffile->GetParam(param);
5823 /* In-game variable. */
5824 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5825 return UINT_MAX;
5829 /* Action 0x06 */
5830 static void CfgApply(ByteReader *buf)
5832 /* <06> <param-num> <param-size> <offset> ... <FF>
5834 * B param-num Number of parameter to substitute (First = "zero")
5835 * Ignored if that parameter was not specified in newgrf.cfg
5836 * B param-size How many bytes to replace. If larger than 4, the
5837 * bytes of the following parameter are used. In that
5838 * case, nothing is applied unless *all* parameters
5839 * were specified.
5840 * B offset Offset into data from beginning of next sprite
5841 * to place where parameter is to be stored. */
5843 /* Preload the next sprite */
5844 size_t pos = FioGetPos();
5845 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5846 uint8 type = FioReadByte();
5847 byte *preload_sprite = NULL;
5849 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5850 if (type == 0xFF) {
5851 preload_sprite = MallocT<byte>(num);
5852 FioReadBlock(preload_sprite, num);
5855 /* Reset the file position to the start of the next sprite */
5856 FioSeekTo(pos, SEEK_SET);
5858 if (type != 0xFF) {
5859 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5860 free(preload_sprite);
5861 return;
5864 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5865 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5866 if (it != _grf_line_to_action6_sprite_override.end()) {
5867 free(preload_sprite);
5868 preload_sprite = _grf_line_to_action6_sprite_override[location];
5869 } else {
5870 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5873 /* Now perform the Action 0x06 on our data. */
5875 for (;;) {
5876 uint i;
5877 uint param_num;
5878 uint param_size;
5879 uint offset;
5880 bool add_value;
5882 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5883 param_num = buf->ReadByte();
5884 if (param_num == 0xFF) break;
5886 /* Get the size of the parameter to use. If the size covers multiple
5887 * double words, sequential parameter values are used. */
5888 param_size = buf->ReadByte();
5890 /* Bit 7 of param_size indicates we should add to the original value
5891 * instead of replacing it. */
5892 add_value = HasBit(param_size, 7);
5893 param_size = GB(param_size, 0, 7);
5895 /* Where to apply the data to within the pseudo sprite data. */
5896 offset = buf->ReadExtendedByte();
5898 /* If the parameter is a GRF parameter (not an internal variable) check
5899 * if it (and all further sequential parameters) has been defined. */
5900 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5901 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5902 break;
5905 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5907 bool carry = false;
5908 for (i = 0; i < param_size && offset + i < num; i++) {
5909 uint32 value = GetParamVal(param_num + i / 4, NULL);
5910 /* Reset carry flag for each iteration of the variable (only really
5911 * matters if param_size is greater than 4) */
5912 if (i % 4 == 0) carry = false;
5914 if (add_value) {
5915 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5916 preload_sprite[offset + i] = GB(new_value, 0, 8);
5917 /* Check if the addition overflowed */
5918 carry = new_value >= 256;
5919 } else {
5920 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
5927 * Disable a static NewGRF when it is influencing another (non-static)
5928 * NewGRF as this could cause desyncs.
5930 * We could just tell the NewGRF querying that the file doesn't exist,
5931 * but that might give unwanted results. Disabling the NewGRF gives the
5932 * best result as no NewGRF author can complain about that.
5933 * @param c The NewGRF to disable.
5935 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
5937 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
5938 error->data = strdup(_cur.grfconfig->GetName());
5941 /* Action 0x07
5942 * Action 0x09 */
5943 static void SkipIf(ByteReader *buf)
5945 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
5947 * B param-num
5948 * B param-size
5949 * B condition-type
5950 * V value
5951 * B num-sprites */
5952 /* TODO: More params. More condition types. */
5953 uint32 cond_val = 0;
5954 uint32 mask = 0;
5955 bool result;
5957 uint8 param = buf->ReadByte();
5958 uint8 paramsize = buf->ReadByte();
5959 uint8 condtype = buf->ReadByte();
5961 if (condtype < 2) {
5962 /* Always 1 for bit tests, the given value should be ignored. */
5963 paramsize = 1;
5966 switch (paramsize) {
5967 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
5968 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
5969 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
5970 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
5971 default: break;
5974 if (param < 0x80 && _cur.grffile->param_end <= param) {
5975 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
5976 return;
5979 uint32 param_val = GetParamVal(param, &cond_val);
5981 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
5984 * Parameter (variable in specs) 0x88 can only have GRF ID checking
5985 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
5986 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
5987 * So, when the condition type is one of those, the specific variable
5988 * 0x88 code is skipped, so the "general" code for the cargo
5989 * availability conditions kicks in.
5991 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
5992 /* GRF ID checks */
5994 GRFConfig *c = GetGRFConfig(cond_val, mask);
5996 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
5997 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
5998 c = NULL;
6001 if (condtype != 10 && c == NULL) {
6002 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6003 return;
6006 switch (condtype) {
6007 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6008 case 0x06: // Is GRFID active?
6009 result = c->status == GCS_ACTIVATED;
6010 break;
6012 case 0x07: // Is GRFID non-active?
6013 result = c->status != GCS_ACTIVATED;
6014 break;
6016 case 0x08: // GRFID is not but will be active?
6017 result = c->status == GCS_INITIALISED;
6018 break;
6020 case 0x09: // GRFID is or will be active?
6021 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6022 break;
6024 case 0x0A: // GRFID is not nor will be active
6025 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6026 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6027 break;
6029 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6031 } else {
6032 /* Parameter or variable tests */
6033 switch (condtype) {
6034 case 0x00: result = !!(param_val & (1 << cond_val));
6035 break;
6036 case 0x01: result = !(param_val & (1 << cond_val));
6037 break;
6038 case 0x02: result = (param_val & mask) == cond_val;
6039 break;
6040 case 0x03: result = (param_val & mask) != cond_val;
6041 break;
6042 case 0x04: result = (param_val & mask) < cond_val;
6043 break;
6044 case 0x05: result = (param_val & mask) > cond_val;
6045 break;
6046 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6047 break;
6048 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6049 break;
6050 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6051 break;
6052 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6053 break;
6055 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6059 if (!result) {
6060 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6061 return;
6064 uint8 numsprites = buf->ReadByte();
6066 /* numsprites can be a GOTO label if it has been defined in the GRF
6067 * file. The jump will always be the first matching label that follows
6068 * the current nfo_line. If no matching label is found, the first matching
6069 * label in the file is used. */
6070 GRFLabel *choice = NULL;
6071 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6072 if (label->label != numsprites) continue;
6074 /* Remember a goto before the current line */
6075 if (choice == NULL) choice = label;
6076 /* If we find a label here, this is definitely good */
6077 if (label->nfo_line > _cur.nfo_line) {
6078 choice = label;
6079 break;
6083 if (choice != NULL) {
6084 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6085 FioSeekTo(choice->pos, SEEK_SET);
6086 _cur.nfo_line = choice->nfo_line;
6087 return;
6090 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6091 _cur.skip_sprites = numsprites;
6092 if (_cur.skip_sprites == 0) {
6093 /* Zero means there are no sprites to skip, so
6094 * we use -1 to indicate that all further
6095 * sprites should be skipped. */
6096 _cur.skip_sprites = -1;
6098 /* If an action 8 hasn't been encountered yet, disable the grf. */
6099 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6100 DisableGrf();
6106 /* Action 0x08 (GLS_FILESCAN) */
6107 static void ScanInfo(ByteReader *buf)
6109 uint8 grf_version = buf->ReadByte();
6110 uint32 grfid = buf->ReadDWord();
6111 const char *name = buf->ReadString();
6113 _cur.grfconfig->ident.grfid = grfid;
6115 if (grf_version < 2 || grf_version > 8) {
6116 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6117 DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
6120 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6121 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6123 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6125 if (buf->HasData()) {
6126 const char *info = buf->ReadString();
6127 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6130 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6131 _cur.skip_sprites = -1;
6134 /* Action 0x08 */
6135 static void GRFInfo(ByteReader *buf)
6137 /* <08> <version> <grf-id> <name> <info>
6139 * B version newgrf version, currently 06
6140 * 4*B grf-id globally unique ID of this .grf file
6141 * S name name of this .grf set
6142 * S info string describing the set, and e.g. author and copyright */
6144 uint8 version = buf->ReadByte();
6145 uint32 grfid = buf->ReadDWord();
6146 const char *name = buf->ReadString();
6148 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6149 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6150 return;
6153 if (_cur.grffile->grfid != grfid) {
6154 DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
6155 _cur.grffile->grfid = grfid;
6158 _cur.grffile->grf_version = version;
6159 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6161 /* Do swap the GRFID for displaying purposes since people expect that */
6162 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
6165 /* Action 0x0A */
6166 static void SpriteReplace(ByteReader *buf)
6168 /* <0A> <num-sets> <set1> [<set2> ...]
6169 * <set>: <num-sprites> <first-sprite>
6171 * B num-sets How many sets of sprites to replace.
6172 * Each set:
6173 * B num-sprites How many sprites are in this set
6174 * W first-sprite First sprite number to replace */
6176 uint8 num_sets = buf->ReadByte();
6178 for (uint i = 0; i < num_sets; i++) {
6179 uint8 num_sprites = buf->ReadByte();
6180 uint16 first_sprite = buf->ReadWord();
6182 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6183 i, num_sprites, first_sprite
6186 for (uint j = 0; j < num_sprites; j++) {
6187 int load_index = first_sprite + j;
6188 _cur.nfo_line++;
6189 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6191 /* Shore sprites now located at different addresses.
6192 * So detect when the old ones get replaced. */
6193 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6194 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6200 /* Action 0x0A (SKIP) */
6201 static void SkipActA(ByteReader *buf)
6203 uint8 num_sets = buf->ReadByte();
6205 for (uint i = 0; i < num_sets; i++) {
6206 /* Skip the sprites this replaces */
6207 _cur.skip_sprites += buf->ReadByte();
6208 /* But ignore where they go */
6209 buf->ReadWord();
6212 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6215 /* Action 0x0B */
6216 static void GRFLoadError(ByteReader *buf)
6218 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6220 * B severity 00: notice, contine loading grf file
6221 * 01: warning, continue loading grf file
6222 * 02: error, but continue loading grf file, and attempt
6223 * loading grf again when loading or starting next game
6224 * 03: error, abort loading and prevent loading again in
6225 * the future (only when restarting the patch)
6226 * B language-id see action 4, use 1F for built-in error messages
6227 * B message-id message to show, see below
6228 * S message for custom messages (message-id FF), text of the message
6229 * not present for built-in messages.
6230 * V data additional data for built-in (or custom) messages
6231 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6233 static const StringID msgstr[] = {
6234 STR_NEWGRF_ERROR_VERSION_NUMBER,
6235 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6236 STR_NEWGRF_ERROR_UNSET_SWITCH,
6237 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6238 STR_NEWGRF_ERROR_LOAD_BEFORE,
6239 STR_NEWGRF_ERROR_LOAD_AFTER,
6240 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6243 static const StringID sevstr[] = {
6244 STR_NEWGRF_ERROR_MSG_INFO,
6245 STR_NEWGRF_ERROR_MSG_WARNING,
6246 STR_NEWGRF_ERROR_MSG_ERROR,
6247 STR_NEWGRF_ERROR_MSG_FATAL
6250 byte severity = buf->ReadByte();
6251 byte lang = buf->ReadByte();
6252 byte message_id = buf->ReadByte();
6254 /* Skip the error if it isn't valid for the current language. */
6255 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6257 /* Skip the error until the activation stage unless bit 7 of the severity
6258 * is set. */
6259 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6260 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6261 return;
6263 ClrBit(severity, 7);
6265 if (severity >= lengthof(sevstr)) {
6266 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6267 severity = 2;
6268 } else if (severity == 3) {
6269 /* This is a fatal error, so make sure the GRF is deactivated and no
6270 * more of it gets loaded. */
6271 DisableGrf();
6273 /* Make sure we show fatal errors, instead of silly infos from before */
6274 delete _cur.grfconfig->error;
6275 _cur.grfconfig->error = NULL;
6278 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6279 grfmsg(7, "GRFLoadError: Invalid message id.");
6280 return;
6283 if (buf->Remaining() <= 1) {
6284 grfmsg(7, "GRFLoadError: No message data supplied.");
6285 return;
6288 /* For now we can only show one message per newgrf file. */
6289 if (_cur.grfconfig->error != NULL) return;
6291 GRFError *error = new GRFError(sevstr[severity]);
6293 if (message_id == 0xFF) {
6294 /* This is a custom error message. */
6295 if (buf->HasData()) {
6296 const char *message = buf->ReadString();
6298 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6299 } else {
6300 grfmsg(7, "GRFLoadError: No custom message supplied.");
6301 error->custom_message = strdup("");
6303 } else {
6304 error->message = msgstr[message_id];
6307 if (buf->HasData()) {
6308 const char *data = buf->ReadString();
6310 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6311 } else {
6312 grfmsg(7, "GRFLoadError: No message data supplied.");
6313 error->data = strdup("");
6316 /* Only two parameter numbers can be used in the string. */
6317 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6318 uint param_number = buf->ReadByte();
6319 error->param_value[i] = _cur.grffile->GetParam(param_number);
6322 _cur.grfconfig->error = error;
6325 /* Action 0x0C */
6326 static void GRFComment(ByteReader *buf)
6328 /* <0C> [<ignored...>]
6330 * V ignored Anything following the 0C is ignored */
6332 if (!buf->HasData()) return;
6334 const char *text = buf->ReadString();
6335 grfmsg(2, "GRFComment: %s", text);
6338 /* Action 0x0D (GLS_SAFETYSCAN) */
6339 static void SafeParamSet(ByteReader *buf)
6341 uint8 target = buf->ReadByte();
6343 /* Only writing GRF parameters is considered safe */
6344 if (target < 0x80) return;
6346 /* GRM could be unsafe, but as here it can only happen after other GRFs
6347 * are loaded, it should be okay. If the GRF tried to use the slots it
6348 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6349 * sprites is considered safe. */
6351 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6353 /* Skip remainder of GRF */
6354 _cur.skip_sprites = -1;
6358 static uint32 GetPatchVariable(uint8 param)
6360 switch (param) {
6361 /* start year - 1920 */
6362 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6364 /* freight trains weight factor */
6365 case 0x0E: return _settings_game.vehicle.freight_trains;
6367 /* empty wagon speed increase */
6368 case 0x0F: return 0;
6370 /* plane speed factor; our patch option is reversed from TTDPatch's,
6371 * the following is good for 1x, 2x and 4x (most common?) and...
6372 * well not really for 3x. */
6373 case 0x10:
6374 switch (_settings_game.vehicle.plane_speed) {
6375 default:
6376 case 4: return 1;
6377 case 3: return 2;
6378 case 2: return 2;
6379 case 1: return 4;
6383 /* 2CC colourmap base sprite */
6384 case 0x11: return SPR_2CCMAP_BASE;
6386 /* map size: format = -MABXYSS
6387 * M : the type of map
6388 * bit 0 : set : squared map. Bit 1 is now not relevant
6389 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6390 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6391 * clear : X is the bigger edge.
6392 * A : minimum edge(log2) of the map
6393 * B : maximum edge(log2) of the map
6394 * XY : edges(log2) of each side of the map.
6395 * SS : combination of both X and Y, thus giving the size(log2) of the map
6397 case 0x13: {
6398 byte map_bits = 0;
6399 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6400 byte log_Y = MapLogY() - 6;
6401 byte max_edge = max(log_X, log_Y);
6403 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6404 SetBit(map_bits, 0);
6405 } else {
6406 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6409 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6410 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6413 /* The maximum height of the map. */
6414 case 0x14:
6415 return MAX_TILE_HEIGHT;
6417 /* Extra foundations base sprite */
6418 case 0x15:
6419 return SPR_SLOPES_BASE;
6421 /* Shore base sprite */
6422 case 0x16:
6423 return SPR_SHORE_BASE;
6425 default:
6426 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6427 return 0;
6432 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6434 uint start = 0;
6435 uint size = 0;
6437 if (op == 6) {
6438 /* Return GRFID of set that reserved ID */
6439 return grm[_cur.grffile->GetParam(target)];
6442 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6443 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6445 for (uint i = start; i < num_ids; i++) {
6446 if (grm[i] == 0) {
6447 size++;
6448 } else {
6449 if (op == 2 || op == 3) break;
6450 start = i + 1;
6451 size = 0;
6454 if (size == count) break;
6457 if (size == count) {
6458 /* Got the slot... */
6459 if (op == 0 || op == 3) {
6460 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6461 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6463 return start;
6466 /* Unable to allocate */
6467 if (op != 4 && op != 5) {
6468 /* Deactivate GRF */
6469 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6470 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6471 return UINT_MAX;
6474 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6475 return UINT_MAX;
6479 /** Action 0x0D: Set parameter */
6480 static void ParamSet(ByteReader *buf)
6482 /* <0D> <target> <operation> <source1> <source2> [<data>]
6484 * B target parameter number where result is stored
6485 * B operation operation to perform, see below
6486 * B source1 first source operand
6487 * B source2 second source operand
6488 * D data data to use in the calculation, not necessary
6489 * if both source1 and source2 refer to actual parameters
6491 * Operations
6492 * 00 Set parameter equal to source1
6493 * 01 Addition, source1 + source2
6494 * 02 Subtraction, source1 - source2
6495 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6496 * 04 Signed multiplication, source1 * source2 (both signed)
6497 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6498 * signed quantity; left shift if positive and right shift if
6499 * negative, source1 is unsigned)
6500 * 06 Signed bit shift, source1 by source2
6501 * (source2 like in 05, and source1 as well)
6504 uint8 target = buf->ReadByte();
6505 uint8 oper = buf->ReadByte();
6506 uint32 src1 = buf->ReadByte();
6507 uint32 src2 = buf->ReadByte();
6509 uint32 data = 0;
6510 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6512 /* You can add 80 to the operation to make it apply only if the target
6513 * is not defined yet. In this respect, a parameter is taken to be
6514 * defined if any of the following applies:
6515 * - it has been set to any value in the newgrf(w).cfg parameter list
6516 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6517 * an earlier action D */
6518 if (HasBit(oper, 7)) {
6519 if (target < 0x80 && target < _cur.grffile->param_end) {
6520 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6521 return;
6524 oper = GB(oper, 0, 7);
6527 if (src2 == 0xFE) {
6528 if (GB(data, 0, 8) == 0xFF) {
6529 if (data == 0x0000FFFF) {
6530 /* Patch variables */
6531 src1 = GetPatchVariable(src1);
6532 } else {
6533 /* GRF Resource Management */
6534 uint8 op = src1;
6535 uint8 feature = GB(data, 8, 8);
6536 uint16 count = GB(data, 16, 16);
6538 if (_cur.stage == GLS_RESERVE) {
6539 if (feature == 0x08) {
6540 /* General sprites */
6541 if (op == 0) {
6542 /* Check if the allocated sprites will fit below the original sprite limit */
6543 if (_cur.spriteid + count >= 16384) {
6544 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6545 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6546 return;
6549 /* Reserve space at the current sprite ID */
6550 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6551 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6552 _cur.spriteid += count;
6555 /* Ignore GRM result during reservation */
6556 src1 = 0;
6557 } else if (_cur.stage == GLS_ACTIVATION) {
6558 switch (feature) {
6559 case 0x00: // Trains
6560 case 0x01: // Road Vehicles
6561 case 0x02: // Ships
6562 case 0x03: // Aircraft
6563 if (!_settings_game.vehicle.dynamic_engines) {
6564 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6565 if (_cur.skip_sprites == -1) return;
6566 } else {
6567 /* GRM does not apply for dynamic engine allocation. */
6568 switch (op) {
6569 case 2:
6570 case 3:
6571 src1 = _cur.grffile->GetParam(target);
6572 break;
6574 default:
6575 src1 = 0;
6576 break;
6579 break;
6581 case 0x08: // General sprites
6582 switch (op) {
6583 case 0:
6584 /* Return space reserved during reservation stage */
6585 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6586 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6587 break;
6589 case 1:
6590 src1 = _cur.spriteid;
6591 break;
6593 default:
6594 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6595 return;
6597 break;
6599 case 0x0B: // Cargo
6600 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6601 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6602 if (_cur.skip_sprites == -1) return;
6603 break;
6605 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6607 } else {
6608 /* Ignore GRM during initialization */
6609 src1 = 0;
6612 } else {
6613 /* Read another GRF File's parameter */
6614 const GRFFile *file = GetFileByGRFID(data);
6615 GRFConfig *c = GetGRFConfig(data);
6616 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6617 /* Disable the read GRF if it is a static NewGRF. */
6618 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6619 src1 = 0;
6620 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6621 src1 = 0;
6622 } else if (src1 == 0xFE) {
6623 src1 = c->version;
6624 } else {
6625 src1 = file->GetParam(src1);
6628 } else {
6629 /* The source1 and source2 operands refer to the grf parameter number
6630 * like in action 6 and 7. In addition, they can refer to the special
6631 * variables available in action 7, or they can be FF to use the value
6632 * of <data>. If referring to parameters that are undefined, a value
6633 * of 0 is used instead. */
6634 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6635 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6638 /* TODO: You can access the parameters of another GRF file by using
6639 * source2=FE, source1=the other GRF's parameter number and data=GRF
6640 * ID. This is only valid with operation 00 (set). If the GRF ID
6641 * cannot be found, a value of 0 is used for the parameter value
6642 * instead. */
6644 uint32 res;
6645 switch (oper) {
6646 case 0x00:
6647 res = src1;
6648 break;
6650 case 0x01:
6651 res = src1 + src2;
6652 break;
6654 case 0x02:
6655 res = src1 - src2;
6656 break;
6658 case 0x03:
6659 res = src1 * src2;
6660 break;
6662 case 0x04:
6663 res = (int32)src1 * (int32)src2;
6664 break;
6666 case 0x05:
6667 if ((int32)src2 < 0) {
6668 res = src1 >> -(int32)src2;
6669 } else {
6670 res = src1 << src2;
6672 break;
6674 case 0x06:
6675 if ((int32)src2 < 0) {
6676 res = (int32)src1 >> -(int32)src2;
6677 } else {
6678 res = (int32)src1 << src2;
6680 break;
6682 case 0x07: // Bitwise AND
6683 res = src1 & src2;
6684 break;
6686 case 0x08: // Bitwise OR
6687 res = src1 | src2;
6688 break;
6690 case 0x09: // Unsigned division
6691 if (src2 == 0) {
6692 res = src1;
6693 } else {
6694 res = src1 / src2;
6696 break;
6698 case 0x0A: // Signed divison
6699 if (src2 == 0) {
6700 res = src1;
6701 } else {
6702 res = (int32)src1 / (int32)src2;
6704 break;
6706 case 0x0B: // Unsigned modulo
6707 if (src2 == 0) {
6708 res = src1;
6709 } else {
6710 res = src1 % src2;
6712 break;
6714 case 0x0C: // Signed modulo
6715 if (src2 == 0) {
6716 res = src1;
6717 } else {
6718 res = (int32)src1 % (int32)src2;
6720 break;
6722 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6725 switch (target) {
6726 case 0x8E: // Y-Offset for train sprites
6727 _cur.grffile->traininfo_vehicle_pitch = res;
6728 break;
6730 case 0x8F: { // Rail track type cost factors
6731 extern RailtypeInfo _railtypes[RAILTYPE_END];
6732 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6733 if (_settings_game.vehicle.disable_elrails) {
6734 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6735 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6736 } else {
6737 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6738 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6740 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6741 break;
6744 /* @todo implement */
6745 case 0x93: // Tile refresh offset to left
6746 case 0x94: // Tile refresh offset to right
6747 case 0x95: // Tile refresh offset upwards
6748 case 0x96: // Tile refresh offset downwards
6749 case 0x97: // Snow line height
6750 case 0x99: // Global ID offset
6751 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6752 break;
6754 case 0x9E: // Miscellaneous GRF features
6755 /* Set train list engine width */
6756 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6757 /* Remove the local flags from the global flags */
6758 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6760 _misc_grf_features = res;
6761 break;
6763 case 0x9F: // locale-dependent settings
6764 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6765 break;
6767 default:
6768 if (target < 0x80) {
6769 _cur.grffile->param[target] = res;
6770 /* param is zeroed by default */
6771 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6772 } else {
6773 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6775 break;
6779 /* Action 0x0E (GLS_SAFETYSCAN) */
6780 static void SafeGRFInhibit(ByteReader *buf)
6782 /* <0E> <num> <grfids...>
6784 * B num Number of GRFIDs that follow
6785 * D grfids GRFIDs of the files to deactivate */
6787 uint8 num = buf->ReadByte();
6789 for (uint i = 0; i < num; i++) {
6790 uint32 grfid = buf->ReadDWord();
6792 /* GRF is unsafe it if tries to deactivate other GRFs */
6793 if (grfid != _cur.grfconfig->ident.grfid) {
6794 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6796 /* Skip remainder of GRF */
6797 _cur.skip_sprites = -1;
6799 return;
6804 /* Action 0x0E */
6805 static void GRFInhibit(ByteReader *buf)
6807 /* <0E> <num> <grfids...>
6809 * B num Number of GRFIDs that follow
6810 * D grfids GRFIDs of the files to deactivate */
6812 uint8 num = buf->ReadByte();
6814 for (uint i = 0; i < num; i++) {
6815 uint32 grfid = buf->ReadDWord();
6816 GRFConfig *file = GetGRFConfig(grfid);
6818 /* Unset activation flag */
6819 if (file != NULL && file != _cur.grfconfig) {
6820 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6821 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6822 error->data = strdup(_cur.grfconfig->GetName());
6827 /** Action 0x0F - Define Town names */
6828 static void FeatureTownName(ByteReader *buf)
6830 /* <0F> <id> <style-name> <num-parts> <parts>
6832 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6833 * V style-name Name of the style (only for final definition)
6834 * B num-parts Number of parts in this definition
6835 * V parts The parts */
6837 uint32 grfid = _cur.grffile->grfid;
6839 GRFTownName *townname = AddGRFTownName(grfid);
6841 byte id = buf->ReadByte();
6842 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6844 if (HasBit(id, 7)) {
6845 /* Final definition */
6846 ClrBit(id, 7);
6847 bool new_scheme = _cur.grffile->grf_version >= 7;
6849 byte lang = buf->ReadByte();
6851 byte nb_gen = townname->nb_gen;
6852 do {
6853 ClrBit(lang, 7);
6855 const char *name = buf->ReadString();
6857 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6858 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6859 free(lang_name);
6861 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6863 lang = buf->ReadByte();
6864 } while (lang != 0);
6865 townname->id[nb_gen] = id;
6866 townname->nb_gen++;
6869 byte nb = buf->ReadByte();
6870 grfmsg(6, "FeatureTownName: %u parts", nb);
6872 townname->nbparts[id] = nb;
6873 townname->partlist[id] = CallocT<NamePartList>(nb);
6875 for (int i = 0; i < nb; i++) {
6876 byte nbtext = buf->ReadByte();
6877 townname->partlist[id][i].bitstart = buf->ReadByte();
6878 townname->partlist[id][i].bitcount = buf->ReadByte();
6879 townname->partlist[id][i].maxprob = 0;
6880 townname->partlist[id][i].partcount = nbtext;
6881 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6882 grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i, nbtext, townname->partlist[id][i].bitstart, townname->partlist[id][i].bitcount);
6884 for (int j = 0; j < nbtext; j++) {
6885 byte prob = buf->ReadByte();
6887 if (HasBit(prob, 7)) {
6888 byte ref_id = buf->ReadByte();
6890 if (townname->nbparts[ref_id] == 0) {
6891 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6892 DelGRFTownName(grfid);
6893 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6894 return;
6897 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6898 townname->partlist[id][i].parts[j].data.id = ref_id;
6899 } else {
6900 const char *text = buf->ReadString();
6901 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6902 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6904 townname->partlist[id][i].parts[j].prob = prob;
6905 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6907 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6911 /** Action 0x10 - Define goto label */
6912 static void DefineGotoLabel(ByteReader *buf)
6914 /* <10> <label> [<comment>]
6916 * B label The label to define
6917 * V comment Optional comment - ignored */
6919 byte nfo_label = buf->ReadByte();
6921 GRFLabel *label = MallocT<GRFLabel>(1);
6922 label->label = nfo_label;
6923 label->nfo_line = _cur.nfo_line;
6924 label->pos = FioGetPos();
6925 label->next = NULL;
6927 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6928 if (_cur.grffile->label == NULL) {
6929 _cur.grffile->label = label;
6930 } else {
6931 /* Attach the label to the end of the list */
6932 GRFLabel *l;
6933 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
6934 l->next = label;
6937 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
6941 * Process a sound import from another GRF file.
6942 * @param sound Destination for sound.
6944 static void ImportGRFSound(SoundEntry *sound)
6946 const GRFFile *file;
6947 uint32 grfid = FioReadDword();
6948 SoundID sound_id = FioReadWord();
6950 file = GetFileByGRFID(grfid);
6951 if (file == NULL || file->sound_offset == 0) {
6952 grfmsg(1, "ImportGRFSound: Source file not available");
6953 return;
6956 if (sound_id >= file->num_sounds) {
6957 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
6958 return;
6961 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
6963 *sound = *GetSound(file->sound_offset + sound_id);
6965 /* Reset volume and priority, which TTDPatch doesn't copy */
6966 sound->volume = 128;
6967 sound->priority = 0;
6971 * Load a sound from a file.
6972 * @param offs File offset to read sound from.
6973 * @param sound Destination for sound.
6975 static void LoadGRFSound(size_t offs, SoundEntry *sound)
6977 /* Set default volume and priority */
6978 sound->volume = 0x80;
6979 sound->priority = 0;
6981 if (offs != SIZE_MAX) {
6982 /* Sound is present in the NewGRF. */
6983 sound->file_slot = _cur.file_index;
6984 sound->file_offset = offs;
6985 sound->grf_container_ver = _cur.grf_container_ver;
6989 /* Action 0x11 */
6990 static void GRFSound(ByteReader *buf)
6992 /* <11> <num>
6994 * W num Number of sound files that follow */
6996 uint16 num = buf->ReadWord();
6997 if (num == 0) return;
6999 SoundEntry *sound;
7000 if (_cur.grffile->sound_offset == 0) {
7001 _cur.grffile->sound_offset = GetNumSounds();
7002 _cur.grffile->num_sounds = num;
7003 sound = AllocateSound(num);
7004 } else {
7005 sound = GetSound(_cur.grffile->sound_offset);
7008 for (int i = 0; i < num; i++) {
7009 _cur.nfo_line++;
7011 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7012 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7013 bool invalid = i >= _cur.grffile->num_sounds;
7015 size_t offs = FioGetPos();
7017 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7018 byte type = FioReadByte();
7020 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7021 /* Reference to sprite section. */
7022 if (invalid) {
7023 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7024 FioSkipBytes(len);
7025 } else if (len != 4) {
7026 grfmsg(1, "GRFSound: Invalid sprite section import");
7027 FioSkipBytes(len);
7028 } else {
7029 uint32 id = FioReadDword();
7030 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7032 continue;
7035 if (type != 0xFF) {
7036 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7037 FioSkipBytes(7);
7038 SkipSpriteData(type, len - 8);
7039 continue;
7042 if (invalid) {
7043 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7044 FioSkipBytes(len);
7047 byte action = FioReadByte();
7048 switch (action) {
7049 case 0xFF:
7050 /* Allocate sound only in init stage. */
7051 if (_cur.stage == GLS_INIT) {
7052 if (_cur.grf_container_ver >= 2) {
7053 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7054 } else {
7055 LoadGRFSound(offs, sound + i);
7058 FioSkipBytes(len - 1); // already read <action>
7059 break;
7061 case 0xFE:
7062 if (_cur.stage == GLS_ACTIVATION) {
7063 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7064 * importing sounds, so this is probably all wrong... */
7065 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7066 ImportGRFSound(sound + i);
7067 } else {
7068 FioSkipBytes(len - 1); // already read <action>
7070 break;
7072 default:
7073 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7074 FioSkipBytes(len - 1); // already read <action>
7075 break;
7080 /* Action 0x11 (SKIP) */
7081 static void SkipAct11(ByteReader *buf)
7083 /* <11> <num>
7085 * W num Number of sound files that follow */
7087 _cur.skip_sprites = buf->ReadWord();
7089 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7092 /** Action 0x12 */
7093 static void LoadFontGlyph(ByteReader *buf)
7095 /* <12> <num_def> <font_size> <num_char> <base_char>
7097 * B num_def Number of definitions
7098 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7099 * B num_char Number of consecutive glyphs
7100 * W base_char First character index */
7102 uint8 num_def = buf->ReadByte();
7104 for (uint i = 0; i < num_def; i++) {
7105 FontSize size = (FontSize)buf->ReadByte();
7106 uint8 num_char = buf->ReadByte();
7107 uint16 base_char = buf->ReadWord();
7109 if (size >= FS_END) {
7110 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7113 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7115 for (uint c = 0; c < num_char; c++) {
7116 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7117 _cur.nfo_line++;
7118 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7123 /** Action 0x12 (SKIP) */
7124 static void SkipAct12(ByteReader *buf)
7126 /* <12> <num_def> <font_size> <num_char> <base_char>
7128 * B num_def Number of definitions
7129 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7130 * B num_char Number of consecutive glyphs
7131 * W base_char First character index */
7133 uint8 num_def = buf->ReadByte();
7135 for (uint i = 0; i < num_def; i++) {
7136 /* Ignore 'size' byte */
7137 buf->ReadByte();
7139 /* Sum up number of characters */
7140 _cur.skip_sprites += buf->ReadByte();
7142 /* Ignore 'base_char' word */
7143 buf->ReadWord();
7146 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7149 /** Action 0x13 */
7150 static void TranslateGRFStrings(ByteReader *buf)
7152 /* <13> <grfid> <num-ent> <offset> <text...>
7154 * 4*B grfid The GRFID of the file whose texts are to be translated
7155 * B num-ent Number of strings
7156 * W offset First text ID
7157 * S text... Zero-terminated strings */
7159 uint32 grfid = buf->ReadDWord();
7160 const GRFConfig *c = GetGRFConfig(grfid);
7161 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7162 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7163 return;
7166 if (c->status == GCS_INITIALISED) {
7167 /* If the file is not active but will be activated later, give an error
7168 * and disable this file. */
7169 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7171 char tmp[256];
7172 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7173 error->data = strdup(tmp);
7175 return;
7178 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7179 * to be added as a generic string, thus the language id of 0x7F. For this to work
7180 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7181 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7182 * not change anything if a string has been provided specifically for this language. */
7183 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7184 byte num_strings = buf->ReadByte();
7185 uint16 first_id = buf->ReadWord();
7187 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7188 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7189 return;
7192 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7193 const char *string = buf->ReadString();
7195 if (StrEmpty(string)) {
7196 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7197 continue;
7200 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7204 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7205 static bool ChangeGRFName(byte langid, const char *str)
7207 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7208 return true;
7211 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7212 static bool ChangeGRFDescription(byte langid, const char *str)
7214 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7215 return true;
7218 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7219 static bool ChangeGRFURL(byte langid, const char *str)
7221 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7222 return true;
7225 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7226 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7228 if (len != 1) {
7229 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7230 buf->Skip(len);
7231 } else {
7232 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7234 return true;
7237 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7238 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7240 if (len != 1) {
7241 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7242 buf->Skip(len);
7243 } else {
7244 char data = buf->ReadByte();
7245 GRFPalette pal = GRFP_GRF_UNSET;
7246 switch (data) {
7247 case '*':
7248 case 'A': pal = GRFP_GRF_ANY; break;
7249 case 'W': pal = GRFP_GRF_WINDOWS; break;
7250 case 'D': pal = GRFP_GRF_DOS; break;
7251 default:
7252 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7253 break;
7255 if (pal != GRFP_GRF_UNSET) {
7256 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7257 _cur.grfconfig->palette |= pal;
7260 return true;
7263 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7264 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7266 if (len != 1) {
7267 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7268 buf->Skip(len);
7269 } else {
7270 char data = buf->ReadByte();
7271 GRFPalette pal = GRFP_BLT_UNSET;
7272 switch (data) {
7273 case '8': pal = GRFP_BLT_UNSET; break;
7274 case '3': pal = GRFP_BLT_32BPP; break;
7275 default:
7276 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7277 return true;
7279 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7280 _cur.grfconfig->palette |= pal;
7282 return true;
7285 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7286 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7288 if (len != 4) {
7289 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7290 buf->Skip(len);
7291 } else {
7292 /* Set min_loadable_version as well (default to minimal compatibility) */
7293 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7295 return true;
7298 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7299 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7301 if (len != 4) {
7302 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7303 buf->Skip(len);
7304 } else {
7305 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7306 if (_cur.grfconfig->version == 0) {
7307 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7308 _cur.grfconfig->min_loadable_version = 0;
7310 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7311 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7312 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7315 return true;
7318 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7320 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7321 static bool ChangeGRFParamName(byte langid, const char *str)
7323 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7324 return true;
7327 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7328 static bool ChangeGRFParamDescription(byte langid, const char *str)
7330 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7331 return true;
7334 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7335 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7337 if (len != 1) {
7338 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7339 buf->Skip(len);
7340 } else {
7341 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7342 if (type < PTYPE_END) {
7343 _cur_parameter->type = type;
7344 } else {
7345 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7348 return true;
7351 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7352 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7354 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7355 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7356 buf->Skip(len);
7357 } else if (len != 8) {
7358 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7359 buf->Skip(len);
7360 } else {
7361 _cur_parameter->min_value = buf->ReadDWord();
7362 _cur_parameter->max_value = buf->ReadDWord();
7364 return true;
7367 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7368 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7370 if (len < 1 || len > 3) {
7371 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7372 buf->Skip(len);
7373 } else {
7374 byte param_nr = buf->ReadByte();
7375 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7376 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7377 buf->Skip(len - 1);
7378 } else {
7379 _cur_parameter->param_nr = param_nr;
7380 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7381 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7385 return true;
7388 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7389 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7391 if (len != 4) {
7392 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7393 buf->Skip(len);
7394 } else {
7395 _cur_parameter->def_value = buf->ReadDWord();
7397 _cur.grfconfig->has_param_defaults = true;
7398 return true;
7401 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7402 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7403 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7406 * Data structure to store the allowed id/type combinations for action 14. The
7407 * data can be represented as a tree with 3 types of nodes:
7408 * 1. Branch nodes (identified by 'C' for choice).
7409 * 2. Binary leaf nodes (identified by 'B').
7410 * 3. Text leaf nodes (identified by 'T').
7412 struct AllowedSubtags {
7413 /** Create empty subtags object used to identify the end of a list. */
7414 AllowedSubtags() :
7415 id(0),
7416 type(0)
7420 * Create a binary leaf node.
7421 * @param id The id for this node.
7422 * @param handler The callback function to call.
7424 AllowedSubtags(uint32 id, DataHandler handler) :
7425 id(id),
7426 type('B')
7428 this->handler.data = handler;
7432 * Create a text leaf node.
7433 * @param id The id for this node.
7434 * @param handler The callback function to call.
7436 AllowedSubtags(uint32 id, TextHandler handler) :
7437 id(id),
7438 type('T')
7440 this->handler.text = handler;
7444 * Create a branch node with a callback handler
7445 * @param id The id for this node.
7446 * @param handler The callback function to call.
7448 AllowedSubtags(uint32 id, BranchHandler handler) :
7449 id(id),
7450 type('C')
7452 this->handler.call_handler = true;
7453 this->handler.u.branch = handler;
7457 * Create a branch node with a list of sub-nodes.
7458 * @param id The id for this node.
7459 * @param subtags Array with all valid subtags.
7461 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7462 id(id),
7463 type('C')
7465 this->handler.call_handler = false;
7466 this->handler.u.subtags = subtags;
7469 uint32 id; ///< The identifier for this node
7470 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7471 union {
7472 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7473 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7474 struct {
7475 union {
7476 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7477 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7478 } u;
7479 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7481 } handler;
7484 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7485 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7488 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7489 * of some parameter values (type uint/enum) or the names of some bits
7490 * (type bitmask). In both cases the format is the same:
7491 * Each subnode should be a text node with the value/bit number as id.
7493 static bool ChangeGRFParamValueNames(ByteReader *buf)
7495 byte type = buf->ReadByte();
7496 while (type != 0) {
7497 uint32 id = buf->ReadDWord();
7498 if (type != 'T' || id > _cur_parameter->max_value) {
7499 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7500 if (!SkipUnknownInfo(buf, type)) return false;
7501 type = buf->ReadByte();
7502 continue;
7505 byte langid = buf->ReadByte();
7506 const char *name_string = buf->ReadString();
7508 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7509 if (val_name != _cur_parameter->value_names.End()) {
7510 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7511 } else {
7512 GRFText *list = NULL;
7513 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7514 _cur_parameter->value_names.Insert(id, list);
7517 type = buf->ReadByte();
7519 return true;
7522 /** Action14 parameter tags */
7523 AllowedSubtags _tags_parameters[] = {
7524 AllowedSubtags('NAME', ChangeGRFParamName),
7525 AllowedSubtags('DESC', ChangeGRFParamDescription),
7526 AllowedSubtags('TYPE', ChangeGRFParamType),
7527 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7528 AllowedSubtags('MASK', ChangeGRFParamMask),
7529 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7530 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7531 AllowedSubtags()
7535 * Callback function for 'INFO'->'PARA' to set extra information about the
7536 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7537 * the parameter number as id. The first parameter has id 0. The maximum
7538 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7540 static bool HandleParameterInfo(ByteReader *buf)
7542 byte type = buf->ReadByte();
7543 while (type != 0) {
7544 uint32 id = buf->ReadDWord();
7545 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7546 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7547 if (!SkipUnknownInfo(buf, type)) return false;
7548 type = buf->ReadByte();
7549 continue;
7552 if (id >= _cur.grfconfig->param_info.Length()) {
7553 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7554 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7555 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7557 if (_cur.grfconfig->param_info[id] == NULL) {
7558 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7560 _cur_parameter = _cur.grfconfig->param_info[id];
7561 /* Read all parameter-data and process each node. */
7562 if (!HandleNodes(buf, _tags_parameters)) return false;
7563 type = buf->ReadByte();
7565 return true;
7568 /** Action14 tags for the INFO node */
7569 AllowedSubtags _tags_info[] = {
7570 AllowedSubtags('NAME', ChangeGRFName),
7571 AllowedSubtags('DESC', ChangeGRFDescription),
7572 AllowedSubtags('URL_', ChangeGRFURL),
7573 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7574 AllowedSubtags('PALS', ChangeGRFPalette),
7575 AllowedSubtags('BLTR', ChangeGRFBlitter),
7576 AllowedSubtags('VRSN', ChangeGRFVersion),
7577 AllowedSubtags('MINV', ChangeGRFMinVersion),
7578 AllowedSubtags('PARA', HandleParameterInfo),
7579 AllowedSubtags()
7582 /** Action14 root tags */
7583 AllowedSubtags _tags_root[] = {
7584 AllowedSubtags('INFO', _tags_info),
7585 AllowedSubtags()
7590 * Try to skip the current node and all subnodes (if it's a branch node).
7591 * @param buf Buffer.
7592 * @param type The node type to skip.
7593 * @return True if we could skip the node, false if an error occured.
7595 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7597 /* type and id are already read */
7598 switch (type) {
7599 case 'C': {
7600 byte new_type = buf->ReadByte();
7601 while (new_type != 0) {
7602 buf->ReadDWord(); // skip the id
7603 if (!SkipUnknownInfo(buf, new_type)) return false;
7604 new_type = buf->ReadByte();
7606 break;
7609 case 'T':
7610 buf->ReadByte(); // lang
7611 buf->ReadString(); // actual text
7612 break;
7614 case 'B': {
7615 uint16 size = buf->ReadWord();
7616 buf->Skip(size);
7617 break;
7620 default:
7621 return false;
7624 return true;
7628 * Handle the nodes of an Action14
7629 * @param type Type of node.
7630 * @param id ID.
7631 * @param buf Buffer.
7632 * @param subtags Allowed subtags.
7633 * @return Whether all tags could be handled.
7635 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7637 uint i = 0;
7638 AllowedSubtags *tag;
7639 while ((tag = &subtags[i++])->type != 0) {
7640 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7641 switch (type) {
7642 default: NOT_REACHED();
7644 case 'T': {
7645 byte langid = buf->ReadByte();
7646 return tag->handler.text(langid, buf->ReadString());
7649 case 'B': {
7650 size_t len = buf->ReadWord();
7651 if (buf->Remaining() < len) return false;
7652 return tag->handler.data(len, buf);
7655 case 'C': {
7656 if (tag->handler.call_handler) {
7657 return tag->handler.u.branch(buf);
7659 return HandleNodes(buf, tag->handler.u.subtags);
7663 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7664 return SkipUnknownInfo(buf, type);
7668 * Handle the contents of a 'C' choice of an Action14
7669 * @param buf Buffer.
7670 * @param subtags List of subtags.
7671 * @return Whether the nodes could all be handled.
7673 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7675 byte type = buf->ReadByte();
7676 while (type != 0) {
7677 uint32 id = buf->ReadDWord();
7678 if (!HandleNode(type, id, buf, subtags)) return false;
7679 type = buf->ReadByte();
7681 return true;
7685 * Handle Action 0x14
7686 * @param buf Buffer.
7688 static void StaticGRFInfo(ByteReader *buf)
7690 /* <14> <type> <id> <text/data...> */
7691 HandleNodes(buf, _tags_root);
7695 * Set the current NewGRF as unsafe for static use
7696 * @param buf Unused.
7697 * @note Used during safety scan on unsafe actions.
7699 static void GRFUnsafe(ByteReader *buf)
7701 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7703 /* Skip remainder of GRF */
7704 _cur.skip_sprites = -1;
7708 /** Initialize the TTDPatch flags */
7709 static void InitializeGRFSpecial()
7711 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7712 | (1 << 0x0D) // newairports
7713 | (1 << 0x0E) // largestations
7714 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7715 | (0 << 0x10) // loadtime
7716 | (1 << 0x12) // presignals
7717 | (1 << 0x13) // extpresignals
7718 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7719 | (1 << 0x1B) // multihead
7720 | (1 << 0x1D) // lowmemory
7721 | (1 << 0x1E); // generalfixes
7723 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7724 | (1 << 0x08) // mammothtrains
7725 | (1 << 0x09) // trainrefit
7726 | (0 << 0x0B) // subsidiaries
7727 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7728 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7729 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7730 | (1 << 0x14) // bridgespeedlimits
7731 | (1 << 0x16) // eternalgame
7732 | (1 << 0x17) // newtrains
7733 | (1 << 0x18) // newrvs
7734 | (1 << 0x19) // newships
7735 | (1 << 0x1A) // newplanes
7736 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7737 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7739 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7740 | (1 << 0x03) // semaphores
7741 | (1 << 0x0A) // newobjects
7742 | (0 << 0x0B) // enhancedgui
7743 | (0 << 0x0C) // newagerating
7744 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7745 | (1 << 0x0E) // fullloadany
7746 | (1 << 0x0F) // planespeed
7747 | (0 << 0x10) // moreindustriesperclimate - obsolete
7748 | (0 << 0x11) // moretoylandfeatures
7749 | (1 << 0x12) // newstations
7750 | (1 << 0x13) // tracktypecostdiff
7751 | (1 << 0x14) // manualconvert
7752 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7753 | (1 << 0x16) // canals
7754 | (1 << 0x17) // newstartyear
7755 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7756 | (1 << 0x19) // newhouses
7757 | (1 << 0x1A) // newbridges
7758 | (1 << 0x1B) // newtownnames
7759 | (1 << 0x1C) // moreanimation
7760 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7761 | (1 << 0x1E) // newshistory
7762 | (0 << 0x1F); // custombridgeheads
7764 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7765 | (1 << 0x01) // windowsnap
7766 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7767 | (1 << 0x03) // pathbasedsignalling
7768 | (0 << 0x04) // aichoosechance
7769 | (1 << 0x05) // resolutionwidth
7770 | (1 << 0x06) // resolutionheight
7771 | (1 << 0x07) // newindustries
7772 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7773 | (0 << 0x09) // townroadbranchprob
7774 | (0 << 0x0A) // tempsnowline
7775 | (1 << 0x0B) // newcargo
7776 | (1 << 0x0C) // enhancemultiplayer
7777 | (1 << 0x0D) // onewayroads
7778 | (1 << 0x0E) // irregularstations
7779 | (1 << 0x0F) // statistics
7780 | (1 << 0x10) // newsounds
7781 | (1 << 0x11) // autoreplace
7782 | (1 << 0x12) // autoslope
7783 | (0 << 0x13) // followvehicle
7784 | (1 << 0x14) // trams
7785 | (0 << 0x15) // enhancetunnels
7786 | (1 << 0x16) // shortrvs
7787 | (1 << 0x17) // articulatedrvs
7788 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7789 | (1 << 0x1E) // variablerunningcosts
7790 | (1 << 0x1F); // any switch is on
7793 /** Reset and clear all NewGRF stations */
7794 static void ResetCustomStations()
7796 const GRFFile * const *end = _grf_files.End();
7797 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7798 StationSpec **&stations = (*file)->stations;
7799 if (stations == NULL) continue;
7800 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7801 if (stations[i] == NULL) continue;
7802 StationSpec *statspec = stations[i];
7804 delete[] statspec->renderdata;
7806 /* Release platforms and layouts */
7807 if (!statspec->copied_layouts) {
7808 for (uint l = 0; l < statspec->lengths; l++) {
7809 for (uint p = 0; p < statspec->platforms[l]; p++) {
7810 free(statspec->layouts[l][p]);
7812 free(statspec->layouts[l]);
7814 free(statspec->layouts);
7815 free(statspec->platforms);
7818 /* Release this station */
7819 free(statspec);
7822 /* Free and reset the station data */
7823 free(stations);
7824 stations = NULL;
7828 /** Reset and clear all NewGRF houses */
7829 static void ResetCustomHouses()
7831 const GRFFile * const *end = _grf_files.End();
7832 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7833 HouseSpec **&housespec = (*file)->housespec;
7834 if (housespec == NULL) continue;
7835 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7836 free(housespec[i]);
7839 free(housespec);
7840 housespec = NULL;
7844 /** Reset and clear all NewGRF airports */
7845 static void ResetCustomAirports()
7847 const GRFFile * const *end = _grf_files.End();
7848 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7849 AirportSpec **aslist = (*file)->airportspec;
7850 if (aslist != NULL) {
7851 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7852 AirportSpec *as = aslist[i];
7854 if (as != NULL) {
7855 /* We need to remove the tiles layouts */
7856 for (int j = 0; j < as->num_table; j++) {
7857 /* remove the individual layouts */
7858 free(as->table[j]);
7860 free(as->table);
7861 free(as->depot_table);
7863 free(as);
7866 free(aslist);
7867 (*file)->airportspec = NULL;
7870 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7871 if (airporttilespec != NULL) {
7872 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7873 free(airporttilespec[i]);
7875 free(airporttilespec);
7876 airporttilespec = NULL;
7881 /** Reset and clear all NewGRF industries */
7882 static void ResetCustomIndustries()
7884 const GRFFile * const *end = _grf_files.End();
7885 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7886 IndustrySpec **&industryspec = (*file)->industryspec;
7887 IndustryTileSpec **&indtspec = (*file)->indtspec;
7889 /* We are verifiying both tiles and industries specs loaded from the grf file
7890 * First, let's deal with industryspec */
7891 if (industryspec != NULL) {
7892 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7893 IndustrySpec *ind = industryspec[i];
7894 if (ind == NULL) continue;
7896 /* We need to remove the sounds array */
7897 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7898 free(ind->random_sounds);
7901 /* We need to remove the tiles layouts */
7902 CleanIndustryTileTable(ind);
7904 free(ind);
7907 free(industryspec);
7908 industryspec = NULL;
7911 if (indtspec == NULL) continue;
7912 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
7913 free(indtspec[i]);
7916 free(indtspec);
7917 indtspec = NULL;
7921 /** Reset and clear all NewObjects */
7922 static void ResetCustomObjects()
7924 const GRFFile * const *end = _grf_files.End();
7925 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7926 ObjectSpec **&objectspec = (*file)->objectspec;
7927 if (objectspec == NULL) continue;
7928 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
7929 free(objectspec[i]);
7932 free(objectspec);
7933 objectspec = NULL;
7937 /** Reset and clear all NewGRFs */
7938 static void ResetNewGRF()
7940 const GRFFile * const *end = _grf_files.End();
7941 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7942 delete *file;
7945 _grf_files.Clear();
7946 _cur.grffile = NULL;
7949 /** Clear all NewGRF errors */
7950 static void ResetNewGRFErrors()
7952 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
7953 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
7954 delete c->error;
7955 c->error = NULL;
7961 * Reset all NewGRF loaded data
7962 * TODO
7964 void ResetNewGRFData()
7966 CleanUpStrings();
7967 CleanUpGRFTownNames();
7969 /* Copy/reset original engine info data */
7970 SetupEngines();
7972 /* Copy/reset original bridge info data */
7973 ResetBridges();
7975 /* Reset rail type information */
7976 ResetRailTypes();
7978 /* Allocate temporary refit/cargo class data */
7979 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
7981 /* Fill rail type label temporary data for default trains */
7982 Engine *e;
7983 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
7984 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
7987 /* Reset GRM reservations */
7988 memset(&_grm_engines, 0, sizeof(_grm_engines));
7989 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
7991 /* Reset generic feature callback lists */
7992 ResetGenericCallbacks();
7994 /* Reset price base data */
7995 ResetPriceBaseMultipliers();
7997 /* Reset the curencies array */
7998 ResetCurrencies();
8000 /* Reset the house array */
8001 ResetCustomHouses();
8002 ResetHouses();
8004 /* Reset the industries structures*/
8005 ResetCustomIndustries();
8006 ResetIndustries();
8008 /* Reset the objects. */
8009 ObjectClass::Reset();
8010 ResetCustomObjects();
8011 ResetObjects();
8013 /* Reset station classes */
8014 StationClass::Reset();
8015 ResetCustomStations();
8017 /* Reset airport-related structures */
8018 AirportClass::Reset();
8019 ResetCustomAirports();
8020 AirportSpec::ResetAirports();
8021 AirportTileSpec::ResetAirportTiles();
8023 /* Reset canal sprite groups and flags */
8024 memset(_water_feature, 0, sizeof(_water_feature));
8026 /* Reset the snowline table. */
8027 ClearSnowLine();
8029 /* Reset NewGRF files */
8030 ResetNewGRF();
8032 /* Reset NewGRF errors. */
8033 ResetNewGRFErrors();
8035 /* Set up the default cargo types */
8036 SetupCargoForClimate(_settings_game.game_creation.landscape);
8038 /* Reset misc GRF features and train list display variables */
8039 _misc_grf_features = 0;
8041 _loaded_newgrf_features.has_2CC = false;
8042 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8043 _loaded_newgrf_features.has_newhouses = false;
8044 _loaded_newgrf_features.has_newindustries = false;
8045 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8047 /* Clear all GRF overrides */
8048 _grf_id_overrides.clear();
8050 InitializeSoundPool();
8051 _spritegroup_pool.CleanPool();
8055 * Reset NewGRF data which is stored persistently in savegames.
8057 void ResetPersistentNewGRFData()
8059 /* Reset override managers */
8060 _engine_mngr.ResetToDefaultMapping();
8061 _house_mngr.ResetMapping();
8062 _industry_mngr.ResetMapping();
8063 _industile_mngr.ResetMapping();
8064 _airport_mngr.ResetMapping();
8065 _airporttile_mngr.ResetMapping();
8069 * Construct the Cargo Mapping
8070 * @note This is the reverse of a cargo translation table
8072 static void BuildCargoTranslationMap()
8074 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8076 for (CargoID c = 0; c < NUM_CARGO; c++) {
8077 const CargoSpec *cs = CargoSpec::Get(c);
8078 if (!cs->IsValid()) continue;
8080 if (_cur.grffile->cargo_list.Length() == 0) {
8081 /* Default translation table, so just a straight mapping to bitnum */
8082 _cur.grffile->cargo_map[c] = cs->bitnum;
8083 } else {
8084 /* Check the translation table for this cargo's label */
8085 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8086 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8092 * Prepare loading a NewGRF file with its config
8093 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8095 static void InitNewGRFFile(const GRFConfig *config)
8097 GRFFile *newfile = GetFileByFilename(config->filename);
8098 if (newfile != NULL) {
8099 /* We already loaded it once. */
8100 _cur.grffile = newfile;
8101 return;
8104 newfile = new GRFFile(config);
8105 *_grf_files.Append() = _cur.grffile = newfile;
8109 * Constructor for GRFFile
8110 * @param config GRFConfig to copy name, grfid and parameters from.
8112 GRFFile::GRFFile(const GRFConfig *config)
8114 this->filename = strdup(config->filename);
8115 this->grfid = config->ident.grfid;
8117 /* Initialise local settings to defaults */
8118 this->traininfo_vehicle_pitch = 0;
8119 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8121 /* Mark price_base_multipliers as 'not set' */
8122 for (Price i = PR_BEGIN; i < PR_END; i++) {
8123 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8126 /* Initialise rail type map with default rail types */
8127 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8128 this->railtype_map[0] = RAILTYPE_RAIL;
8129 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8130 this->railtype_map[2] = RAILTYPE_MONO;
8131 this->railtype_map[3] = RAILTYPE_MAGLEV;
8133 /* Copy the initial parameter list
8134 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8135 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8137 assert(config->num_params <= lengthof(config->param));
8138 this->param_end = config->num_params;
8139 if (this->param_end > 0) {
8140 MemCpyT(this->param, config->param, this->param_end);
8144 GRFFile::~GRFFile()
8146 free(this->filename);
8147 delete[] this->language_map;
8152 * List of what cargo labels are refittable for the given the vehicle-type.
8153 * Only currently active labels are applied.
8155 static const CargoLabel _default_refitmasks_rail[] = {
8156 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8157 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8158 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8159 'PLST', 'FZDR',
8160 0 };
8162 static const CargoLabel _default_refitmasks_road[] = {
8163 0 };
8165 static const CargoLabel _default_refitmasks_ships[] = {
8166 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8167 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8168 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8169 'PLST', 'FZDR',
8170 0 };
8172 static const CargoLabel _default_refitmasks_aircraft[] = {
8173 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8174 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8175 0 };
8177 static const CargoLabel * const _default_refitmasks[] = {
8178 _default_refitmasks_rail,
8179 _default_refitmasks_road,
8180 _default_refitmasks_ships,
8181 _default_refitmasks_aircraft,
8186 * Precalculate refit masks from cargo classes for all vehicles.
8188 static void CalculateRefitMasks()
8190 Engine *e;
8192 FOR_ALL_ENGINES(e) {
8193 EngineID engine = e->index;
8194 EngineInfo *ei = &e->info;
8195 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8197 /* Did the newgrf specify any refitting? If not, use defaults. */
8198 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8199 uint32 mask = 0;
8200 uint32 not_mask = 0;
8201 uint32 xor_mask = ei->refit_mask;
8203 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8204 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8205 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8207 if (_gted[engine].cargo_allowed != 0) {
8208 /* Build up the list of cargo types from the set cargo classes. */
8209 const CargoSpec *cs;
8210 FOR_ALL_CARGOSPECS(cs) {
8211 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8212 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8216 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8218 /* Apply explicit refit includes/excludes. */
8219 ei->refit_mask |= _gted[engine].ctt_include_mask;
8220 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8221 } else {
8222 uint32 xor_mask = 0;
8224 /* Don't apply default refit mask to wagons nor engines with no capacity */
8225 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8226 const CargoLabel *cl = _default_refitmasks[e->type];
8227 for (uint i = 0;; i++) {
8228 if (cl[i] == 0) break;
8230 CargoID cargo = GetCargoIDByLabel(cl[i]);
8231 if (cargo == CT_INVALID) continue;
8233 SetBit(xor_mask, cargo);
8237 ei->refit_mask = xor_mask & _cargo_mask;
8239 /* If the mask is zero, the vehicle shall only carry the default cargo */
8240 only_defaultcargo = (ei->refit_mask == 0);
8243 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8244 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8246 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8247 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8248 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8249 ei->cargo_type = CT_INVALID;
8252 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8253 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8254 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8255 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8256 const uint8 *cargo_map_for_first_refittable = NULL;
8258 const GRFFile *file = _gted[engine].defaultcargo_grf;
8259 if (file == NULL) file = e->GetGRF();
8260 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8261 cargo_map_for_first_refittable = file->cargo_map;
8265 if (cargo_map_for_first_refittable != NULL) {
8266 /* Use first refittable cargo from cargo translation table */
8267 byte best_local_slot = 0xFF;
8268 CargoID cargo_type;
8269 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8270 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8271 if (local_slot < best_local_slot) {
8272 best_local_slot = local_slot;
8273 ei->cargo_type = cargo_type;
8278 if (ei->cargo_type == CT_INVALID) {
8279 /* Use first refittable cargo slot */
8280 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8283 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8285 /* Clear refit_mask for not refittable ships */
8286 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8287 ei->refit_mask = 0;
8292 /** Set to use the correct action0 properties for each canal feature */
8293 static void FinaliseCanals()
8295 for (uint i = 0; i < CF_END; i++) {
8296 if (_water_feature[i].grffile != NULL) {
8297 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8298 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8303 /** Check for invalid engines */
8304 static void FinaliseEngineArray()
8306 Engine *e;
8308 FOR_ALL_ENGINES(e) {
8309 if (e->GetGRF() == NULL) {
8310 const EngineIDMapping &eid = _engine_mngr[e->index];
8311 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8312 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8316 /* When the train does not set property 27 (misc flags), but it
8317 * is overridden by a NewGRF graphically we want to disable the
8318 * flipping possibility. */
8319 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8320 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8323 /* Skip wagons, there livery is defined via the engine */
8324 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8325 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8326 SetBit(_loaded_newgrf_features.used_liveries, ls);
8327 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8329 if (e->type == VEH_TRAIN) {
8330 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8331 switch (ls) {
8332 case LS_STEAM:
8333 case LS_DIESEL:
8334 case LS_ELECTRIC:
8335 case LS_MONORAIL:
8336 case LS_MAGLEV:
8337 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8338 break;
8340 case LS_DMU:
8341 case LS_EMU:
8342 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8343 break;
8345 default: NOT_REACHED();
8352 /** Check for invalid cargoes */
8353 static void FinaliseCargoArray()
8355 for (CargoID c = 0; c < NUM_CARGO; c++) {
8356 CargoSpec *cs = CargoSpec::Get(c);
8357 if (!cs->IsValid()) {
8358 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8359 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8360 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8366 * Check if a given housespec is valid and disable it if it's not.
8367 * The housespecs that follow it are used to check the validity of
8368 * multitile houses.
8369 * @param hs The housespec to check.
8370 * @param next1 The housespec that follows \c hs.
8371 * @param next2 The housespec that follows \c next1.
8372 * @param next3 The housespec that follows \c next2.
8373 * @param filename The filename of the newgrf this house was defined in.
8374 * @return Whether the given housespec is valid.
8376 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8378 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8379 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8380 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8381 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8382 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8383 hs->enabled = false;
8384 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
8385 return false;
8388 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8389 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8390 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8391 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8392 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8393 hs->enabled = false;
8394 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
8395 return false;
8398 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8399 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8400 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8401 hs->enabled = false;
8402 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
8403 return false;
8406 /* Make sure that additional parts of multitile houses are not available. */
8407 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8408 hs->enabled = false;
8409 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
8410 return false;
8413 return true;
8417 * Make sure there is at least one house available in the year 0 for the given
8418 * climate / housezone combination.
8419 * @param bitmask The climate and housezone to check for. Exactly one climate
8420 * bit and one housezone bit should be set.
8422 static void EnsureEarlyHouse(HouseZones bitmask)
8424 Year min_year = MAX_YEAR;
8426 for (int i = 0; i < NUM_HOUSES; i++) {
8427 HouseSpec *hs = HouseSpec::Get(i);
8428 if (hs == NULL || !hs->enabled) continue;
8429 if ((hs->building_availability & bitmask) != bitmask) continue;
8430 if (hs->min_year < min_year) min_year = hs->min_year;
8433 if (min_year == 0) return;
8435 for (int i = 0; i < NUM_HOUSES; i++) {
8436 HouseSpec *hs = HouseSpec::Get(i);
8437 if (hs == NULL || !hs->enabled) continue;
8438 if ((hs->building_availability & bitmask) != bitmask) continue;
8439 if (hs->min_year == min_year) hs->min_year = 0;
8444 * Add all new houses to the house array. House properties can be set at any
8445 * time in the GRF file, so we can only add a house spec to the house array
8446 * after the file has finished loading. We also need to check the dates, due to
8447 * the TTDPatch behaviour described below that we need to emulate.
8449 static void FinaliseHouseArray()
8451 /* If there are no houses with start dates before 1930, then all houses
8452 * with start dates of 1930 have them reset to 0. This is in order to be
8453 * compatible with TTDPatch, where if no houses have start dates before
8454 * 1930 and the date is before 1930, the game pretends that this is 1930.
8455 * If there have been any houses defined with start dates before 1930 then
8456 * the dates are left alone.
8457 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8458 * minimum introduction date to 0.
8460 const GRFFile * const *end = _grf_files.End();
8461 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8462 HouseSpec **&housespec = (*file)->housespec;
8463 if (housespec == NULL) continue;
8465 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8466 HouseSpec *hs = housespec[i];
8468 if (hs == NULL) continue;
8470 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8471 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8472 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8474 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8476 _house_mngr.SetEntitySpec(hs);
8480 for (int i = 0; i < NUM_HOUSES; i++) {
8481 HouseSpec *hs = HouseSpec::Get(i);
8482 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8483 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8484 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8486 /* We need to check all houses again to we are sure that multitile houses
8487 * did get consecutive IDs and none of the parts are missing. */
8488 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8489 /* GetHouseNorthPart checks 3 houses that are directly before
8490 * it in the house pool. If any of those houses have multi-tile
8491 * flags set it assumes it's part of a multitile house. Since
8492 * we can have invalid houses in the pool marked as disabled, we
8493 * don't want to have them influencing valid tiles. As such set
8494 * building_flags to zero here to make sure any house following
8495 * this one in the pool is properly handled as 1x1 house. */
8496 hs->building_flags = TILE_NO_FLAG;
8500 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8501 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8502 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8503 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8504 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8505 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8507 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8508 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8509 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8510 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8511 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8512 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8517 * Add all new industries to the industry array. Industry properties can be set at any
8518 * time in the GRF file, so we can only add a industry spec to the industry array
8519 * after the file has finished loading.
8521 static void FinaliseIndustriesArray()
8523 const GRFFile * const *end = _grf_files.End();
8524 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8525 IndustrySpec **&industryspec = (*file)->industryspec;
8526 IndustryTileSpec **&indtspec = (*file)->indtspec;
8527 if (industryspec != NULL) {
8528 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8529 IndustrySpec *indsp = industryspec[i];
8531 if (indsp != NULL && indsp->enabled) {
8532 StringID strid;
8533 /* process the conversion of text at the end, so to be sure everything will be fine
8534 * and available. Check if it does not return undefind marker, which is a very good sign of a
8535 * substitute industry who has not changed the string been examined, thus using it as such */
8536 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8537 if (strid != STR_UNDEFINED) indsp->name = strid;
8539 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8540 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8542 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8543 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8545 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8546 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8548 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8549 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8551 if (indsp->station_name != STR_NULL) {
8552 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8553 * station's name. Don't want to lose the value, therefore, do not process. */
8554 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8555 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8558 _industry_mngr.SetEntitySpec(indsp);
8559 _loaded_newgrf_features.has_newindustries = true;
8564 if (indtspec != NULL) {
8565 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8566 IndustryTileSpec *indtsp = indtspec[i];
8567 if (indtsp != NULL) {
8568 _industile_mngr.SetEntitySpec(indtsp);
8574 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8575 IndustrySpec *indsp = &_industry_specs[j];
8576 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8577 for (uint i = 0; i < 3; i++) {
8578 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8581 if (!indsp->enabled) {
8582 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8588 * Add all new objects to the object array. Object properties can be set at any
8589 * time in the GRF file, so we can only add an object spec to the object array
8590 * after the file has finished loading.
8592 static void FinaliseObjectsArray()
8594 const GRFFile * const *end = _grf_files.End();
8595 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8596 ObjectSpec **&objectspec = (*file)->objectspec;
8597 if (objectspec != NULL) {
8598 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8599 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8600 _object_mngr.SetEntitySpec(objectspec[i]);
8608 * Add all new airports to the airport array. Airport properties can be set at any
8609 * time in the GRF file, so we can only add a airport spec to the airport array
8610 * after the file has finished loading.
8612 static void FinaliseAirportsArray()
8614 const GRFFile * const *end = _grf_files.End();
8615 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8616 AirportSpec **&airportspec = (*file)->airportspec;
8617 if (airportspec != NULL) {
8618 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8619 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8620 _airport_mngr.SetEntitySpec(airportspec[i]);
8625 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8626 if (airporttilespec != NULL) {
8627 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8628 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8629 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8636 /* Here we perform initial decoding of some special sprites (as are they
8637 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8638 * partial implementation yet).
8639 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8640 * a crafted invalid GRF file. We should tell that to the user somehow, or
8641 * better make this more robust in the future. */
8642 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8644 /* XXX: There is a difference between staged loading in TTDPatch and
8645 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8646 * during stage 1, whilst action 3 is carried out during stage 2 (to
8647 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8648 * IDs are valid only within a given set (action 1) block, and may be
8649 * overwritten after action 3 associates them. But overwriting happens
8650 * in an earlier stage than associating, so... We just process actions
8651 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8652 * --pasky
8653 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8654 * is not in memory and scanning the file every time would be too expensive.
8655 * In other stages we skip action 0x10 since it's already dealt with. */
8656 static const SpecialSpriteHandler handlers[][GLS_END] = {
8657 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8658 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8659 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8660 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8661 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8662 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8663 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8664 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8665 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8666 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8667 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8668 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8669 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8670 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8671 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8672 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8673 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8674 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8675 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8676 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8677 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8680 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8682 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8683 if (it == _grf_line_to_action6_sprite_override.end()) {
8684 /* No preloaded sprite to work with; read the
8685 * pseudo sprite content. */
8686 FioReadBlock(buf, num);
8687 } else {
8688 /* Use the preloaded sprite data. */
8689 buf = _grf_line_to_action6_sprite_override[location];
8690 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8692 /* Skip the real (original) content of this action. */
8693 FioSeekTo(num, SEEK_CUR);
8696 ByteReader br(buf, buf + num);
8697 ByteReader *bufp = &br;
8699 try {
8700 byte action = bufp->ReadByte();
8702 if (action == 0xFF) {
8703 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8704 } else if (action == 0xFE) {
8705 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8706 } else if (action >= lengthof(handlers)) {
8707 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8708 } else if (handlers[action][stage] == NULL) {
8709 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8710 } else {
8711 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8712 handlers[action][stage](bufp);
8714 } catch (...) {
8715 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8716 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8721 /** Signature of a container version 2 GRF. */
8722 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8725 * Get the container version of the currently opened GRF file.
8726 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8728 byte GetGRFContainerVersion()
8730 size_t pos = FioGetPos();
8732 if (FioReadWord() == 0) {
8733 /* Check for GRF container version 2, which is identified by the bytes
8734 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8735 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8736 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8739 return 2;
8742 /* Container version 1 has no header, rewind to start. */
8743 FioSeekTo(pos, SEEK_SET);
8744 return 1;
8748 * Load a particular NewGRF.
8749 * @param config The configuration of the to be loaded NewGRF.
8750 * @param file_index The Fio index of the first NewGRF to load.
8751 * @param stage The loading stage of the NewGRF.
8752 * @param subdir The sub directory to find the NewGRF in.
8754 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8756 const char *filename = config->filename;
8758 /* A .grf file is activated only if it was active when the game was
8759 * started. If a game is loaded, only its active .grfs will be
8760 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8761 * considered active if its action 8 has been processed, i.e. its
8762 * action 8 hasn't been skipped using an action 7.
8764 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8765 * carried out. All others are ignored, because they only need to be
8766 * processed once at initialization. */
8767 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8768 _cur.grffile = GetFileByFilename(filename);
8769 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8770 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8771 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8772 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
8775 if (file_index > LAST_GRF_SLOT) {
8776 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
8777 config->status = GCS_DISABLED;
8778 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8779 return;
8782 FioOpenFile(file_index, filename, subdir);
8783 _cur.file_index = file_index; // XXX
8784 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8786 _cur.grfconfig = config;
8788 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8790 _cur.grf_container_ver = GetGRFContainerVersion();
8791 if (_cur.grf_container_ver == 0) {
8792 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8793 return;
8796 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8797 /* We need the sprite offsets in the init stage for NewGRF sounds
8798 * and in the activation stage for real sprites. */
8799 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8800 } else {
8801 /* Skip sprite section offset if present. */
8802 if (_cur.grf_container_ver >= 2) FioReadDword();
8805 if (_cur.grf_container_ver >= 2) {
8806 /* Read compression value. */
8807 byte compression = FioReadByte();
8808 if (compression != 0) {
8809 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8810 return;
8814 /* Skip the first sprite; we don't care about how many sprites this
8815 * does contain; newest TTDPatches and George's longvehicles don't
8816 * neither, apparently. */
8817 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8818 if (num == 4 && FioReadByte() == 0xFF) {
8819 FioReadDword();
8820 } else {
8821 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8822 return;
8825 _cur.ClearDataForNextFile();
8827 ReusableBuffer<byte> buf;
8829 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8830 byte type = FioReadByte();
8831 _cur.nfo_line++;
8833 if (type == 0xFF) {
8834 if (_cur.skip_sprites == 0) {
8835 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8837 /* Stop all processing if we are to skip the remaining sprites */
8838 if (_cur.skip_sprites == -1) break;
8840 continue;
8841 } else {
8842 FioSkipBytes(num);
8844 } else {
8845 if (_cur.skip_sprites == 0) {
8846 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8847 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8848 break;
8851 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8852 /* Reference to data section. Container version >= 2 only. */
8853 FioSkipBytes(num);
8854 } else {
8855 FioSkipBytes(7);
8856 SkipSpriteData(type, num - 8);
8860 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8865 * Relocates the old shore sprites at new positions.
8867 * 1. If shore sprites are neither loaded by Action5 nor ActionA, the extra sprites from openttd(w/d).grf are used. (SHORE_REPLACE_ONLY_NEW)
8868 * 2. If a newgrf replaces some shore sprites by ActionA. The (maybe also replaced) grass tiles are used for corner shores. (SHORE_REPLACE_ACTION_A)
8869 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8871 static void ActivateOldShore()
8873 /* Use default graphics, if no shore sprites were loaded.
8874 * Should not happen, as the base set's extra grf should include some. */
8875 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8877 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8878 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8879 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8880 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8881 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8882 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8883 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8884 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8885 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8888 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8889 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8890 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8891 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8892 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8893 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8894 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
8895 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
8896 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
8898 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8899 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8900 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
8901 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
8906 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8908 static void FinalisePriceBaseMultipliers()
8910 extern const PriceBaseSpec _price_base_specs[];
8911 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8912 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8914 /* Evaluate grf overrides */
8915 int num_grfs = _grf_files.Length();
8916 int *grf_overrides = AllocaM(int, num_grfs);
8917 for (int i = 0; i < num_grfs; i++) {
8918 grf_overrides[i] = -1;
8920 GRFFile *source = _grf_files[i];
8921 uint32 override = _grf_id_overrides[source->grfid];
8922 if (override == 0) continue;
8924 GRFFile *dest = GetFileByGRFID(override);
8925 if (dest == NULL) continue;
8927 grf_overrides[i] = _grf_files.FindIndex(dest);
8928 assert(grf_overrides[i] >= 0);
8931 /* Override features and price base multipliers of earlier loaded grfs */
8932 for (int i = 0; i < num_grfs; i++) {
8933 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
8934 GRFFile *source = _grf_files[i];
8935 GRFFile *dest = _grf_files[grf_overrides[i]];
8937 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8938 source->grf_features |= features;
8939 dest->grf_features |= features;
8941 for (Price p = PR_BEGIN; p < PR_END; p++) {
8942 /* No price defined -> nothing to do */
8943 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
8944 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
8945 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8949 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
8950 for (int i = num_grfs - 1; i >= 0; i--) {
8951 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
8952 GRFFile *source = _grf_files[i];
8953 GRFFile *dest = _grf_files[grf_overrides[i]];
8955 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8956 source->grf_features |= features;
8957 dest->grf_features |= features;
8959 for (Price p = PR_BEGIN; p < PR_END; p++) {
8960 /* Already a price defined -> nothing to do */
8961 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
8962 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
8963 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8967 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
8968 for (int i = 0; i < num_grfs; i++) {
8969 if (grf_overrides[i] < 0) continue;
8970 GRFFile *source = _grf_files[i];
8971 GRFFile *dest = _grf_files[grf_overrides[i]];
8973 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8974 source->grf_features |= features;
8975 dest->grf_features |= features;
8977 for (Price p = PR_BEGIN; p < PR_END; p++) {
8978 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
8979 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
8980 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
8982 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
8986 /* Apply fallback prices for grf version < 8 */
8987 const GRFFile * const *end = _grf_files.End();
8988 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8989 if ((*file)->grf_version >= 8) continue;
8990 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
8991 for (Price p = PR_BEGIN; p < PR_END; p++) {
8992 Price fallback_price = _price_base_specs[p].fallback_price;
8993 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
8994 /* No price multiplier has been set.
8995 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
8996 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9001 /* Decide local/global scope of price base multipliers */
9002 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9003 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9004 for (Price p = PR_BEGIN; p < PR_END; p++) {
9005 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9006 /* No multiplier was set; set it to a neutral value */
9007 price_base_multipliers[p] = 0;
9008 } else {
9009 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9010 /* The grf does not define any objects of the feature,
9011 * so it must be a difficulty setting. Apply it globally */
9012 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9013 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9014 price_base_multipliers[p] = 0;
9015 } else {
9016 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9023 void InitDepotWindowBlockSizes();
9025 extern void InitGRFTownGeneratorNames();
9027 /** Finish loading NewGRFs and execute needed post-processing */
9028 static void AfterLoadGRFs()
9030 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
9031 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
9033 _string_to_grf_mapping.clear();
9035 /* Free the action 6 override sprites. */
9036 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9037 free((*it).second);
9039 _grf_line_to_action6_sprite_override.clear();
9041 /* Polish cargoes */
9042 FinaliseCargoArray();
9044 /* Pre-calculate all refit masks after loading GRF files. */
9045 CalculateRefitMasks();
9047 /* Polish engines */
9048 FinaliseEngineArray();
9050 /* Set the actually used Canal properties */
9051 FinaliseCanals();
9053 /* Set the block size in the depot windows based on vehicle sprite sizes */
9054 InitDepotWindowBlockSizes();
9056 /* Add all new houses to the house array. */
9057 FinaliseHouseArray();
9059 /* Add all new industries to the industry array. */
9060 FinaliseIndustriesArray();
9062 /* Add all new objects to the object array. */
9063 FinaliseObjectsArray();
9065 InitializeSortedCargoSpecs();
9067 /* Sort the list of industry types. */
9068 SortIndustryTypes();
9070 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9071 BuildIndustriesLegend();
9073 /* Build the routemap legend, based on the available cargos */
9074 BuildLinkStatsLegend();
9076 /* Add all new airports to the airports array. */
9077 FinaliseAirportsArray();
9078 BindAirportSpecs();
9080 /* Update the townname generators list */
9081 InitGRFTownGeneratorNames();
9083 /* Run all queued vehicle list order changes */
9084 CommitVehicleListOrderChanges();
9086 /* Load old shore sprites in new position, if they were replaced by ActionA */
9087 ActivateOldShore();
9089 /* Set up custom rail types */
9090 InitRailTypes();
9092 Engine *e;
9093 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9094 if (_gted[e->index].rv_max_speed != 0) {
9095 /* Set RV maximum speed from the mph/0.8 unit value */
9096 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9100 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9101 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9102 if (railtype == INVALID_RAILTYPE) {
9103 /* Rail type is not available, so disable this engine */
9104 e->info.climates = 0;
9105 } else {
9106 e->u.rail.railtype = railtype;
9110 SetYearEngineAgingStops();
9112 FinalisePriceBaseMultipliers();
9114 /* Deallocate temporary loading data */
9115 free(_gted);
9116 _grm_sprites.clear();
9120 * Load all the NewGRFs.
9121 * @param load_index The offset for the first sprite to add.
9122 * @param file_index The Fio index of the first NewGRF to load.
9124 void LoadNewGRF(uint load_index, uint file_index)
9126 /* In case of networking we need to "sync" the start values
9127 * so all NewGRFs are loaded equally. For this we use the
9128 * start date of the game and we set the counters, etc. to
9129 * 0 so they're the same too. */
9130 Date date = _date;
9131 Year year = _cur_year;
9132 DateFract date_fract = _date_fract;
9133 uint16 tick_counter = _tick_counter;
9134 byte display_opt = _display_opt;
9136 if (_networking) {
9137 _cur_year = _settings_game.game_creation.starting_year;
9138 _date = ConvertYMDToDate(_cur_year, 0, 1);
9139 _date_fract = 0;
9140 _tick_counter = 0;
9141 _display_opt = 0;
9144 InitializeGRFSpecial();
9146 ResetNewGRFData();
9149 * Reset the status of all files, so we can 'retry' to load them.
9150 * This is needed when one for example rearranges the NewGRFs in-game
9151 * and a previously disabled NewGRF becomes useable. If it would not
9152 * be reset, the NewGRF would remain disabled even though it should
9153 * have been enabled.
9155 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9156 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9159 _cur.spriteid = load_index;
9161 /* Load newgrf sprites
9162 * in each loading stage, (try to) open each file specified in the config
9163 * and load information from it. */
9164 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9165 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9166 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9167 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9168 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9171 if (stage == GLS_RESERVE) {
9172 static const uint32 overrides[][2] = {
9173 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9174 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9175 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9177 for (size_t i = 0; i < lengthof(overrides); i++) {
9178 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9182 uint slot = file_index;
9184 _cur.stage = stage;
9185 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9186 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9187 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9189 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
9190 if (!FioCheckFileExists(c->filename, subdir)) {
9191 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9192 c->status = GCS_NOT_FOUND;
9193 continue;
9196 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9197 LoadNewGRFFile(c, slot++, stage, subdir);
9198 if (stage == GLS_RESERVE) {
9199 SetBit(c->flags, GCF_RESERVED);
9200 } else if (stage == GLS_ACTIVATION) {
9201 ClrBit(c->flags, GCF_RESERVED);
9202 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9203 ClearTemporaryNewGRFData(_cur.grffile);
9204 BuildCargoTranslationMap();
9205 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9206 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9207 /* We're not going to activate this, so free whatever data we allocated */
9208 ClearTemporaryNewGRFData(_cur.grffile);
9213 /* Pseudo sprite processing is finished; free temporary stuff */
9214 _cur.ClearDataForNextFile();
9216 /* Call any functions that should be run after GRFs have been loaded. */
9217 AfterLoadGRFs();
9219 /* Now revert back to the original situation */
9220 _cur_year = year;
9221 _date = date;
9222 _date_fract = date_fract;
9223 _tick_counter = tick_counter;
9224 _display_opt = display_opt;