(svn r23005) -Fix (r23004): Of course there's still the 16-sprite version for shore...
[openttd/fttd.git] / src / newgrf.cpp
blob39ae46669b28cbd9d94f7db84e569ed9bc1ea803
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.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
39 #include "rev.h"
40 #include "fios.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
45 #include <map>
46 #include "smallmap_gui.h"
47 #include "genworld.h"
48 #include "gui.h"
49 #include "vehicle_func.h"
50 #include "language.h"
51 #include "vehicle_base.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 is 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 static 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 enum GrfDataType {
78 GDT_SOUND,
81 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
83 /** Temporary data during loading of GRFs */
84 struct GrfProcessingState {
85 private:
86 /** Definition of a single Action1 spriteset */
87 struct SpriteSet {
88 SpriteID sprite; ///< SpriteID of the first sprite of the set.
89 uint num_sprites; ///< Number of sprites in the set.
92 /** Currently referenceable spritesets */
93 std::map<uint, SpriteSet> spritesets[GSF_END];
95 public:
96 /* Global state */
97 GrfLoadingStage stage; ///< Current loading stage
98 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
100 /* Local state in the file */
101 uint file_index; ///< File index of currently processed GRF file.
102 GRFFile *grffile; ///< Currently processed GRF file.
103 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
104 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
106 /* Kind of return values when processing certain actions */
107 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
108 byte data_blocks; ///< Number of binary include sprites to read before processing the next pseudo sprite.
109 GrfDataType data_type; ///< Type of the binary include sprites to read.
111 /* Currently referenceable spritegroups */
112 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
114 /** Clear temporary data before processing the next file in the current loading stage */
115 void ClearDataForNextFile()
117 this->nfo_line = 0;
118 this->skip_sprites = 0;
119 this->data_blocks = 0;
121 for (uint i = 0; i < GSF_END; i++) {
122 this->spritesets[i].clear();
125 memset(this->spritegroups, 0, sizeof(this->spritegroups));
129 * Records new spritesets.
130 * @param feature GrfSpecFeature the set is defined for.
131 * @param first_sprite SpriteID of the first sprite in the set.
132 * @param first_set First spriteset to define.
133 * @param numsets Number of sets to define.
134 * @param numents Number of sprites per set to define.
136 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
138 assert(feature < GSF_END);
139 for (uint i = 0; i < numsets; i++) {
140 SpriteSet &set = this->spritesets[feature][first_set + i];
141 set.sprite = first_sprite + i * numents;
142 set.num_sprites = numents;
147 * Check whether there are any valid spritesets for a feature.
148 * @param feature GrfSpecFeature to check.
149 * @return true if there are any valid sets.
150 * @note Spritesets with zero sprites are valid to allow callback-failures.
152 bool HasValidSpriteSets(byte feature) const
154 assert(feature < GSF_END);
155 return !this->spritesets[feature].empty();
159 * Check whether a specific set is defined.
160 * @param feature GrfSpecFeature to check.
161 * @param set Set to check.
162 * @return true if the set is valid.
163 * @note Spritesets with zero sprites are valid to allow callback-failures.
165 bool IsValidSpriteSet(byte feature, uint set) const
167 assert(feature < GSF_END);
168 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
172 * Returns the first sprite of a spriteset.
173 * @param feature GrfSpecFeature to query.
174 * @param set Set to query.
175 * @return First sprite of the set.
177 SpriteID GetSprite(byte feature, uint set) const
179 assert(IsValidSpriteSet(feature, set));
180 return this->spritesets[feature].find(set)->second.sprite;
184 * Returns the number of sprites in a spriteset
185 * @param feature GrfSpecFeature to query.
186 * @param set Set to query.
187 * @return Number of sprites in the set.
189 uint GetNumEnts(byte feature, uint set) const
191 assert(IsValidSpriteSet(feature, set));
192 return this->spritesets[feature].find(set)->second.num_sprites;
196 static GrfProcessingState _cur;
199 class OTTDByteReaderSignal { };
201 /** Class to read from a NewGRF file */
202 class ByteReader {
203 protected:
204 byte *data;
205 byte *end;
207 public:
208 ByteReader(byte *data, byte *end) : data(data), end(end) { }
210 FORCEINLINE byte ReadByte()
212 if (data < end) return *(data)++;
213 throw OTTDByteReaderSignal();
216 uint16 ReadWord()
218 uint16 val = ReadByte();
219 return val | (ReadByte() << 8);
222 uint16 ReadExtendedByte()
224 uint16 val = ReadByte();
225 return val == 0xFF ? ReadWord() : val;
228 uint32 ReadDWord()
230 uint32 val = ReadWord();
231 return val | (ReadWord() << 16);
234 uint32 ReadVarSize(byte size)
236 switch (size) {
237 case 1: return ReadByte();
238 case 2: return ReadWord();
239 case 4: return ReadDWord();
240 default:
241 NOT_REACHED();
242 return 0;
246 const char *ReadString()
248 char *string = reinterpret_cast<char *>(data);
249 size_t string_length = ttd_strnlen(string, Remaining());
251 if (string_length == Remaining()) {
252 /* String was not NUL terminated, so make sure it is now. */
253 string[string_length - 1] = '\0';
254 grfmsg(7, "String was not terminated with a zero byte.");
255 } else {
256 /* Increase the string length to include the NUL byte. */
257 string_length++;
259 Skip(string_length);
261 return string;
264 FORCEINLINE size_t Remaining() const
266 return end - data;
269 FORCEINLINE bool HasData(size_t count = 1) const
271 return data + count <= end;
274 FORCEINLINE byte *Data()
276 return data;
279 FORCEINLINE void Skip(size_t len)
281 data += len;
282 /* It is valid to move the buffer to exactly the end of the data,
283 * as there may not be any more data read. */
284 if (data > end) throw OTTDByteReaderSignal();
288 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
290 static const uint MAX_STATIONS = 256;
292 /** Temporary engine data used when loading only */
293 struct GRFTempEngineData {
294 uint16 cargo_allowed;
295 uint16 cargo_disallowed;
296 RailTypeLabel railtypelabel;
297 const GRFFile *refitmask_grf; ///< GRF providing the cargo translation table for the refitmask.
298 bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
299 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
300 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
303 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
306 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
307 * GRM for vehicles is only used if dynamic engine allocation is disabled,
308 * so 256 is the number of original engines. */
309 static uint32 _grm_engines[256];
311 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
312 static uint32 _grm_cargos[NUM_CARGO * 2];
314 struct GRFLocation {
315 uint32 grfid;
316 uint32 nfoline;
318 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
320 bool operator<(const GRFLocation &other) const
322 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
325 bool operator == (const GRFLocation &other) const
327 return this->grfid == other.grfid && this->nfoline == other.nfoline;
331 static std::map<GRFLocation, SpriteID> _grm_sprites;
332 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
333 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
336 * DEBUG() function dedicated to newGRF debugging messages
337 * Function is essentially the same as DEBUG(grf, severity, ...) with the
338 * addition of file:line information when parsing grf files.
339 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
340 * loading/parsing grf files, not for runtime debug messages as there
341 * is no file information available during that time.
342 * @param severity debugging severity level, see debug.h
343 * @param str message in printf() format
345 void CDECL grfmsg(int severity, const char *str, ...)
347 char buf[1024];
348 va_list va;
350 va_start(va, str);
351 vsnprintf(buf, sizeof(buf), str, va);
352 va_end(va);
354 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
358 * Obtain a NewGRF file by its grfID
359 * @param grfid The grfID to obtain the file for
360 * @return The file.
362 static GRFFile *GetFileByGRFID(uint32 grfid)
364 const GRFFile * const *end = _grf_files.End();
365 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
366 if ((*file)->grfid == grfid) return *file;
368 return NULL;
372 * Obtain a NewGRF file by its filename
373 * @param filename The filename to obtain the file for.
374 * @return The file.
376 static GRFFile *GetFileByFilename(const char *filename)
378 const GRFFile * const *end = _grf_files.End();
379 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
380 if (strcmp((*file)->filename, filename) == 0) return *file;
382 return NULL;
385 /** Reset all NewGRFData that was used only while processing data */
386 static void ClearTemporaryNewGRFData(GRFFile *gf)
388 /* Clear the GOTO labels used for GRF processing */
389 for (GRFLabel *l = gf->label; l != NULL;) {
390 GRFLabel *l2 = l->next;
391 free(l);
392 l = l2;
394 gf->label = NULL;
398 * Disable a GRF
399 * @param message Error message or STR_NULL.
400 * @param config GRFConfig to disable, NULL for current.
401 * @return Error message of the GRF for further customisation.
403 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
405 GRFFile *file;
406 if (config != NULL) {
407 file = GetFileByGRFID(config->ident.grfid);
408 } else {
409 config = _cur.grfconfig;
410 file = _cur.grffile;
413 config->status = GCS_DISABLED;
414 if (file != NULL) ClearTemporaryNewGRFData(file);
415 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
417 if (message != STR_NULL) {
418 delete config->error;
419 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
422 return config->error;
426 typedef std::map<StringID *, uint32> StringIDToGRFIDMapping;
427 static StringIDToGRFIDMapping _string_to_grf_mapping;
430 * Used when setting an object's property to map to the GRF's strings
431 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
432 * @param grfid Id of the grf file.
433 * @param str StringID that we want to have the equivalent in OoenTTD.
434 * @return The properly adjusted StringID.
436 StringID MapGRFStringID(uint32 grfid, StringID str)
438 /* 0xD0 and 0xDC stand for all the TextIDs in the range
439 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
440 * These strings are unique to each grf file, and thus require to be used with the
441 * grfid in which they are declared */
442 switch (GB(str, 8, 8)) {
443 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
444 case 0xDC:
445 return GetGRFStringID(grfid, str);
447 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
448 /* Strings embedded via 0x81 have 0x400 added to them (no real
449 * explanation why...) */
450 return GetGRFStringID(grfid, str - 0x400);
452 default: break;
455 return TTDPStringIDToOTTDStringIDMapping(str);
458 static std::map<uint32, uint32> _grf_id_overrides;
461 * Set the override for a NewGRF
462 * @param source_grfid The grfID which wants to override another NewGRF.
463 * @param target_grfid The grfID which is being overridden.
465 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
467 _grf_id_overrides[source_grfid] = target_grfid;
468 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
472 * Returns the engine associated to a certain internal_id, resp. allocates it.
473 * @param file NewGRF that wants to change the engine.
474 * @param type Vehicle type.
475 * @param internal_id Engine ID inside the NewGRF.
476 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
477 * @return The requested engine.
479 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
481 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
482 * them use the same engine slots. */
483 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
484 if (_settings_game.vehicle.dynamic_engines) {
485 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
486 scope_grfid = file->grfid;
487 uint32 override = _grf_id_overrides[file->grfid];
488 if (override != 0) {
489 scope_grfid = override;
490 const GRFFile *grf_match = GetFileByGRFID(override);
491 if (grf_match == NULL) {
492 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
493 } else {
494 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
498 /* Check if the engine is registered in the override manager */
499 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
500 if (engine != INVALID_ENGINE) {
501 Engine *e = Engine::Get(engine);
502 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
503 return e;
507 /* Check if there is an unreserved slot */
508 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
509 if (engine != INVALID_ENGINE) {
510 Engine *e = Engine::Get(engine);
512 if (e->grf_prop.grffile == NULL) {
513 e->grf_prop.grffile = file;
514 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
517 /* Reserve the engine slot */
518 if (!static_access) {
519 EngineIDMapping *eid = _engine_mngr.Get(engine);
520 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
523 return e;
526 if (static_access) return NULL;
528 if (!Engine::CanAllocateItem()) {
529 grfmsg(0, "Can't allocate any more engines");
530 return NULL;
533 size_t engine_pool_size = Engine::GetPoolSize();
535 /* ... it's not, so create a new one based off an existing engine */
536 Engine *e = new Engine(type, internal_id);
537 e->grf_prop.grffile = file;
539 /* Reserve the engine slot */
540 assert(_engine_mngr.Length() == e->index);
541 EngineIDMapping *eid = _engine_mngr.Append();
542 eid->type = type;
543 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
544 eid->internal_id = internal_id;
545 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
547 if (engine_pool_size != Engine::GetPoolSize()) {
548 /* Resize temporary engine data ... */
549 _gted = ReallocT(_gted, Engine::GetPoolSize());
551 /* and blank the new block. */
552 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
553 memset(_gted + engine_pool_size, 0, len);
555 if (type == VEH_TRAIN) {
556 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
559 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
561 return e;
565 * Return the ID of a new engine
566 * @param file The NewGRF file providing the engine.
567 * @param type The Vehicle type.
568 * @param internal_id NewGRF-internal ID of the engine.
569 * @return The new EngineID.
570 * @note depending on the dynamic_engine setting and a possible override
571 * property the grfID may be unique or overwriting or partially re-defining
572 * properties of an existing engine.
574 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
576 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
577 if (_settings_game.vehicle.dynamic_engines) {
578 scope_grfid = file->grfid;
579 uint32 override = _grf_id_overrides[file->grfid];
580 if (override != 0) scope_grfid = override;
583 return _engine_mngr.GetID(type, internal_id, scope_grfid);
587 * Map the colour modifiers of TTDPatch to those that Open is using.
588 * @param grf_sprite Pointer to the structure been modified.
590 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
592 if (HasBit(grf_sprite->pal, 14)) {
593 ClrBit(grf_sprite->pal, 14);
594 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
597 if (HasBit(grf_sprite->sprite, 14)) {
598 ClrBit(grf_sprite->sprite, 14);
599 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
602 if (HasBit(grf_sprite->sprite, 15)) {
603 ClrBit(grf_sprite->sprite, 15);
604 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
609 * Read a sprite and a palette from the GRF and convert them into a format
610 * suitable to OpenTTD.
611 * @param buf Input stream.
612 * @param read_flags Whether to read TileLayoutFlags.
613 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
614 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
615 * @param feature GrfSpecFeature to use spritesets from.
616 * @param [out] grf_sprite Read sprite and palette.
617 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
618 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
619 * @return Read TileLayoutFlags.
621 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)
623 grf_sprite->sprite = buf->ReadWord();
624 grf_sprite->pal = buf->ReadWord();
625 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
627 MapSpriteMappingRecolour(grf_sprite);
629 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
630 ClrBit(grf_sprite->pal, 15);
631 if (custom_sprite) {
632 /* Use sprite from Action 1 */
633 uint index = GB(grf_sprite->sprite, 0, 14);
634 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
635 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
636 grf_sprite->sprite = SPR_IMG_QUERY;
637 grf_sprite->pal = PAL_NONE;
638 } else {
639 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
640 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
641 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
642 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
644 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
645 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
646 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
647 return flags;
650 if (flags & TLF_CUSTOM_PALETTE) {
651 /* Use palette from Action 1 */
652 uint index = GB(grf_sprite->pal, 0, 14);
653 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
654 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
655 grf_sprite->pal = PAL_NONE;
656 } else {
657 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
658 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
659 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
660 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
662 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
663 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
664 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
665 return flags;
668 return flags;
672 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
673 * @param buf Input stream.
674 * @param flags TileLayoutFlags to process.
675 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
676 * @param dts Sprite layout to insert data into.
677 * @param index Sprite index to process; 0 for ground sprite.
679 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
681 if (!(flags & TLF_DRAWING_FLAGS)) return;
683 if (dts->registers == NULL) dts->AllocateRegisters();
684 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
685 regs.flags = flags & TLF_DRAWING_FLAGS;
687 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
688 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
689 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
691 if (is_parent) {
692 if (flags & TLF_BB_XY_OFFSET) {
693 regs.delta.parent[0] = buf->ReadByte();
694 regs.delta.parent[1] = buf->ReadByte();
696 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
697 } else {
698 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
699 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
702 if (flags & TLF_SPRITE_VAR10) {
703 regs.sprite_var10 = buf->ReadByte();
704 if (regs.sprite_var10 > TLR_MAX_VAR10) {
705 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
706 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
707 return;
711 if (flags & TLF_PALETTE_VAR10) {
712 regs.palette_var10 = buf->ReadByte();
713 if (regs.palette_var10 > TLR_MAX_VAR10) {
714 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
715 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
716 return;
722 * Read a spritelayout from the GRF.
723 * @param buf Input
724 * @param num_building_sprites Number of building sprites to read
725 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
726 * @param feature GrfSpecFeature to use spritesets from.
727 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
728 * @param no_z_position Whether bounding boxes have no Z offset
729 * @param dts Layout container to output into
730 * @return True on error (GRF was disabled).
732 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
734 bool has_flags = HasBit(num_building_sprites, 6);
735 ClrBit(num_building_sprites, 6);
736 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
737 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
738 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
740 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
741 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
742 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
743 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
745 /* Groundsprite */
746 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
747 if (_cur.skip_sprites < 0) return true;
749 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
750 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
751 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
752 return true;
755 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
756 if (_cur.skip_sprites < 0) return true;
758 for (uint i = 0; i < num_building_sprites; i++) {
759 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
761 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
762 if (_cur.skip_sprites < 0) return true;
764 if (flags & ~valid_flags) {
765 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
766 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
767 return true;
770 seq->delta_x = buf->ReadByte();
771 seq->delta_y = buf->ReadByte();
773 if (!no_z_position) seq->delta_z = buf->ReadByte();
775 if (seq->IsParentSprite()) {
776 seq->size_x = buf->ReadByte();
777 seq->size_y = buf->ReadByte();
778 seq->size_z = buf->ReadByte();
781 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
782 if (_cur.skip_sprites < 0) return true;
785 /* Check if the number of sprites per spriteset is consistent */
786 bool is_consistent = true;
787 dts->consistent_max_offset = 0;
788 for (uint i = 0; i < num_building_sprites + 1; i++) {
789 if (max_sprite_offset[i] > 0) {
790 if (dts->consistent_max_offset == 0) {
791 dts->consistent_max_offset = max_sprite_offset[i];
792 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
793 is_consistent = false;
794 break;
797 if (max_palette_offset[i] > 0) {
798 if (dts->consistent_max_offset == 0) {
799 dts->consistent_max_offset = max_palette_offset[i];
800 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
801 is_consistent = false;
802 break;
807 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
808 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
810 if (!is_consistent || dts->registers != NULL) {
811 dts->consistent_max_offset = 0;
812 if (dts->registers == NULL) dts->AllocateRegisters();
814 for (uint i = 0; i < num_building_sprites + 1; i++) {
815 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
816 regs.max_sprite_offset = max_sprite_offset[i];
817 regs.max_palette_offset = max_palette_offset[i];
821 return false;
825 * Converts TTD(P) Base Price pointers into the enum used by OTTD
826 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
827 * @param base_pointer TTD(P) Base Price Pointer
828 * @param error_location Function name for grf error messages
829 * @param index If #base_pointer is valid, #index is assigned to the matching price; else it is left unchanged
831 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
833 /* Special value for 'none' */
834 if (base_pointer == 0) {
835 *index = INVALID_PRICE;
836 return;
839 static const uint32 start = 0x4B34; ///< Position of first base price
840 static const uint32 size = 6; ///< Size of each base price record
842 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
843 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
844 return;
847 *index = (Price)((base_pointer - start) / size);
850 /** Possible return values for the FeatureChangeInfo functions */
851 enum ChangeInfoResult {
852 CIR_SUCCESS, ///< Variable was parsed and read
853 CIR_DISABLED, ///< GRF was disabled due to error
854 CIR_UNHANDLED, ///< Variable was parsed but unread
855 CIR_UNKNOWN, ///< Variable is unknown
856 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
859 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
862 * Define properties common to all vehicles
863 * @param ei Engine info.
864 * @param prop The property to change.
865 * @param buf The property value.
866 * @return ChangeInfoResult.
868 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
870 switch (prop) {
871 case 0x00: // Introduction date
872 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
873 break;
875 case 0x02: // Decay speed
876 ei->decay_speed = buf->ReadByte();
877 break;
879 case 0x03: // Vehicle life
880 ei->lifelength = buf->ReadByte();
881 break;
883 case 0x04: // Model life
884 ei->base_life = buf->ReadByte();
885 break;
887 case 0x06: // Climates available
888 ei->climates = buf->ReadByte();
889 break;
891 case 0x07: // Loading speed
892 /* Amount of cargo loaded during a vehicle's "loading tick" */
893 ei->load_amount = buf->ReadByte();
894 break;
896 default:
897 return CIR_UNKNOWN;
900 return CIR_SUCCESS;
904 * Define properties for rail vehicles
905 * @param engine :ocal ID of the first vehicle.
906 * @param numinfo Number of subsequent IDs to change the property for.
907 * @param prop The property to change.
908 * @param buf The property value.
909 * @return ChangeInfoResult.
911 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
913 ChangeInfoResult ret = CIR_SUCCESS;
915 for (int i = 0; i < numinfo; i++) {
916 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
917 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
919 EngineInfo *ei = &e->info;
920 RailVehicleInfo *rvi = &e->u.rail;
922 switch (prop) {
923 case 0x05: { // Track type
924 uint8 tracktype = buf->ReadByte();
926 if (tracktype < _cur.grffile->railtype_max) {
927 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
928 break;
931 switch (tracktype) {
932 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
933 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
934 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
935 default:
936 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
937 break;
939 break;
942 case 0x08: // AI passenger service
943 /* Tells the AI that this engine is designed for
944 * passenger services and shouldn't be used for freight. */
945 rvi->ai_passenger_only = buf->ReadByte();
946 break;
948 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
949 uint16 speed = buf->ReadWord();
950 if (speed == 0xFFFF) speed = 0;
952 rvi->max_speed = speed;
953 break;
956 case PROP_TRAIN_POWER: // 0x0B Power
957 rvi->power = buf->ReadWord();
959 /* Set engine / wagon state based on power */
960 if (rvi->power != 0) {
961 if (rvi->railveh_type == RAILVEH_WAGON) {
962 rvi->railveh_type = RAILVEH_SINGLEHEAD;
964 } else {
965 rvi->railveh_type = RAILVEH_WAGON;
967 break;
969 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
970 rvi->running_cost = buf->ReadByte();
971 break;
973 case 0x0E: // Running cost base
974 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
975 break;
977 case 0x12: { // Sprite ID
978 uint8 spriteid = buf->ReadByte();
980 /* TTD sprite IDs point to a location in a 16bit array, but we use it
981 * as an array index, so we need it to be half the original value. */
982 if (spriteid < 0xFD) spriteid >>= 1;
984 rvi->image_index = spriteid;
985 break;
988 case 0x13: { // Dual-headed
989 uint8 dual = buf->ReadByte();
991 if (dual != 0) {
992 rvi->railveh_type = RAILVEH_MULTIHEAD;
993 } else {
994 rvi->railveh_type = rvi->power == 0 ?
995 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
997 break;
1000 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1001 rvi->capacity = buf->ReadByte();
1002 break;
1004 case 0x15: { // Cargo type
1005 uint8 ctype = buf->ReadByte();
1007 if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
1008 ei->cargo_type = ctype;
1009 } else if (ctype == 0xFF) {
1010 /* 0xFF is specified as 'use first refittable' */
1011 ei->cargo_type = CT_INVALID;
1012 } else {
1013 ei->cargo_type = CT_INVALID;
1014 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1016 break;
1019 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1020 SB(rvi->weight, 0, 8, buf->ReadByte());
1021 break;
1023 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1024 rvi->cost_factor = buf->ReadByte();
1025 break;
1027 case 0x18: // AI rank
1028 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1029 buf->ReadByte();
1030 break;
1032 case 0x19: { // Engine traction type
1033 /* What do the individual numbers mean?
1034 * 0x00 .. 0x07: Steam
1035 * 0x08 .. 0x27: Diesel
1036 * 0x28 .. 0x31: Electric
1037 * 0x32 .. 0x37: Monorail
1038 * 0x38 .. 0x41: Maglev
1040 uint8 traction = buf->ReadByte();
1041 EngineClass engclass;
1043 if (traction <= 0x07) {
1044 engclass = EC_STEAM;
1045 } else if (traction <= 0x27) {
1046 engclass = EC_DIESEL;
1047 } else if (traction <= 0x31) {
1048 engclass = EC_ELECTRIC;
1049 } else if (traction <= 0x37) {
1050 engclass = EC_MONORAIL;
1051 } else if (traction <= 0x41) {
1052 engclass = EC_MAGLEV;
1053 } else {
1054 break;
1057 if (_cur.grffile->railtype_max == 0) {
1058 /* Use traction type to select between normal and electrified
1059 * rail only when no translation list is in place. */
1060 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1061 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1064 rvi->engclass = engclass;
1065 break;
1068 case 0x1A: // Alter purchase list sort order
1069 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1070 break;
1072 case 0x1B: // Powered wagons power bonus
1073 rvi->pow_wag_power = buf->ReadWord();
1074 break;
1076 case 0x1C: // Refit cost
1077 ei->refit_cost = buf->ReadByte();
1078 break;
1080 case 0x1D: // Refit cargo
1081 ei->refit_mask = buf->ReadDWord();
1082 _gted[e->index].refitmask_valid = true;
1083 _gted[e->index].refitmask_grf = _cur.grffile;
1084 break;
1086 case 0x1E: // Callback
1087 ei->callback_mask = buf->ReadByte();
1088 break;
1090 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1091 rvi->tractive_effort = buf->ReadByte();
1092 break;
1094 case 0x20: // Air drag
1095 rvi->air_drag = buf->ReadByte();
1096 break;
1098 case 0x21: // Shorter vehicle
1099 rvi->shorten_factor = buf->ReadByte();
1100 break;
1102 case 0x22: // Visual effect
1103 rvi->visual_effect = buf->ReadByte();
1104 /* Avoid accidentally setting visual_effect to the default value
1105 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1106 if (rvi->visual_effect == VE_DEFAULT) {
1107 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1108 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1110 break;
1112 case 0x23: // Powered wagons weight bonus
1113 rvi->pow_wag_weight = buf->ReadByte();
1114 break;
1116 case 0x24: { // High byte of vehicle weight
1117 byte weight = buf->ReadByte();
1119 if (weight > 4) {
1120 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1121 } else {
1122 SB(rvi->weight, 8, 8, weight);
1124 break;
1127 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1128 rvi->user_def_data = buf->ReadByte();
1129 break;
1131 case 0x26: // Retire vehicle early
1132 ei->retire_early = buf->ReadByte();
1133 break;
1135 case 0x27: // Miscellaneous flags
1136 ei->misc_flags = buf->ReadByte();
1137 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1138 _gted[e->index].prop27_set = true;
1139 break;
1141 case 0x28: // Cargo classes allowed
1142 _gted[e->index].cargo_allowed = buf->ReadWord();
1143 _gted[e->index].refitmask_valid = true;
1144 break;
1146 case 0x29: // Cargo classes disallowed
1147 _gted[e->index].cargo_disallowed = buf->ReadWord();
1148 _gted[e->index].refitmask_valid = true;
1149 break;
1151 case 0x2A: // Long format introduction date (days since year 0)
1152 ei->base_intro = buf->ReadDWord();
1153 break;
1155 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1156 ei->cargo_age_period = buf->ReadWord();
1157 break;
1159 default:
1160 ret = CommonVehicleChangeInfo(ei, prop, buf);
1161 break;
1165 return ret;
1169 * Define properties for road vehicles
1170 * @param engine Local ID of the first vehicle.
1171 * @param numinfo Number of subsequent IDs to change the property for.
1172 * @param prop The property to change.
1173 * @param buf The property value.
1174 * @return ChangeInfoResult.
1176 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1178 ChangeInfoResult ret = CIR_SUCCESS;
1180 for (int i = 0; i < numinfo; i++) {
1181 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1182 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1184 EngineInfo *ei = &e->info;
1185 RoadVehicleInfo *rvi = &e->u.road;
1187 switch (prop) {
1188 case 0x08: // Speed (1 unit is 0.5 kmh)
1189 rvi->max_speed = buf->ReadByte();
1190 break;
1192 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1193 rvi->running_cost = buf->ReadByte();
1194 break;
1196 case 0x0A: // Running cost base
1197 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1198 break;
1200 case 0x0E: { // Sprite ID
1201 uint8 spriteid = buf->ReadByte();
1203 /* cars have different custom id in the GRF file */
1204 if (spriteid == 0xFF) spriteid = 0xFD;
1206 if (spriteid < 0xFD) spriteid >>= 1;
1208 rvi->image_index = spriteid;
1209 break;
1212 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1213 rvi->capacity = buf->ReadByte();
1214 break;
1216 case 0x10: { // Cargo type
1217 uint8 cargo = buf->ReadByte();
1219 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
1220 ei->cargo_type = cargo;
1221 } else if (cargo == 0xFF) {
1222 ei->cargo_type = CT_INVALID;
1223 } else {
1224 ei->cargo_type = CT_INVALID;
1225 grfmsg(2, "RoadVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
1227 break;
1230 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1231 rvi->cost_factor = buf->ReadByte();
1232 break;
1234 case 0x12: // SFX
1235 rvi->sfx = buf->ReadByte();
1236 break;
1238 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1239 rvi->power = buf->ReadByte();
1240 break;
1242 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1243 rvi->weight = buf->ReadByte();
1244 break;
1246 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1247 _gted[e->index].rv_max_speed = buf->ReadByte();
1248 break;
1250 case 0x16: // Cargos available for refitting
1251 ei->refit_mask = buf->ReadDWord();
1252 _gted[e->index].refitmask_valid = true;
1253 _gted[e->index].refitmask_grf = _cur.grffile;
1254 break;
1256 case 0x17: // Callback mask
1257 ei->callback_mask = buf->ReadByte();
1258 break;
1260 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1261 rvi->tractive_effort = buf->ReadByte();
1262 break;
1264 case 0x19: // Air drag
1265 rvi->air_drag = buf->ReadByte();
1266 break;
1268 case 0x1A: // Refit cost
1269 ei->refit_cost = buf->ReadByte();
1270 break;
1272 case 0x1B: // Retire vehicle early
1273 ei->retire_early = buf->ReadByte();
1274 break;
1276 case 0x1C: // Miscellaneous flags
1277 ei->misc_flags = buf->ReadByte();
1278 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1279 break;
1281 case 0x1D: // Cargo classes allowed
1282 _gted[e->index].cargo_allowed = buf->ReadWord();
1283 _gted[e->index].refitmask_valid = true;
1284 break;
1286 case 0x1E: // Cargo classes disallowed
1287 _gted[e->index].cargo_disallowed = buf->ReadWord();
1288 _gted[e->index].refitmask_valid = true;
1289 break;
1291 case 0x1F: // Long format introduction date (days since year 0)
1292 ei->base_intro = buf->ReadDWord();
1293 break;
1295 case 0x20: // Alter purchase list sort order
1296 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1297 break;
1299 case 0x21: // Visual effect
1300 rvi->visual_effect = buf->ReadByte();
1301 /* Avoid accidentally setting visual_effect to the default value
1302 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1303 if (rvi->visual_effect == VE_DEFAULT) {
1304 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1305 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1307 break;
1309 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1310 ei->cargo_age_period = buf->ReadWord();
1311 break;
1313 default:
1314 ret = CommonVehicleChangeInfo(ei, prop, buf);
1315 break;
1319 return ret;
1323 * Define properties for ships
1324 * @param engine Local ID of the first vehicle.
1325 * @param numinfo Number of subsequent IDs to change the property for.
1326 * @param prop The property to change.
1327 * @param buf The property value.
1328 * @return ChangeInfoResult.
1330 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1332 ChangeInfoResult ret = CIR_SUCCESS;
1334 for (int i = 0; i < numinfo; i++) {
1335 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1336 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1338 EngineInfo *ei = &e->info;
1339 ShipVehicleInfo *svi = &e->u.ship;
1341 switch (prop) {
1342 case 0x08: { // Sprite ID
1343 uint8 spriteid = buf->ReadByte();
1345 /* ships have different custom id in the GRF file */
1346 if (spriteid == 0xFF) spriteid = 0xFD;
1348 if (spriteid < 0xFD) spriteid >>= 1;
1350 svi->image_index = spriteid;
1351 break;
1354 case 0x09: // Refittable
1355 svi->old_refittable = (buf->ReadByte() != 0);
1356 break;
1358 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1359 svi->cost_factor = buf->ReadByte();
1360 break;
1362 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1363 svi->max_speed = buf->ReadByte();
1364 break;
1366 case 0x0C: { // Cargo type
1367 uint8 cargo = buf->ReadByte();
1369 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
1370 ei->cargo_type = cargo;
1371 } else if (cargo == 0xFF) {
1372 ei->cargo_type = CT_INVALID;
1373 } else {
1374 ei->cargo_type = CT_INVALID;
1375 grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
1377 break;
1380 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1381 svi->capacity = buf->ReadWord();
1382 break;
1384 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1385 svi->running_cost = buf->ReadByte();
1386 break;
1388 case 0x10: // SFX
1389 svi->sfx = buf->ReadByte();
1390 break;
1392 case 0x11: // Cargos available for refitting
1393 ei->refit_mask = buf->ReadDWord();
1394 _gted[e->index].refitmask_valid = true;
1395 _gted[e->index].refitmask_grf = _cur.grffile;
1396 break;
1398 case 0x12: // Callback mask
1399 ei->callback_mask = buf->ReadByte();
1400 break;
1402 case 0x13: // Refit cost
1403 ei->refit_cost = buf->ReadByte();
1404 break;
1406 case 0x14: // Ocean speed fraction
1407 svi->ocean_speed_frac = buf->ReadByte();
1408 break;
1410 case 0x15: // Canal speed fraction
1411 svi->canal_speed_frac = buf->ReadByte();
1412 break;
1414 case 0x16: // Retire vehicle early
1415 ei->retire_early = buf->ReadByte();
1416 break;
1418 case 0x17: // Miscellaneous flags
1419 ei->misc_flags = buf->ReadByte();
1420 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1421 break;
1423 case 0x18: // Cargo classes allowed
1424 _gted[e->index].cargo_allowed = buf->ReadWord();
1425 _gted[e->index].refitmask_valid = true;
1426 break;
1428 case 0x19: // Cargo classes disallowed
1429 _gted[e->index].cargo_disallowed = buf->ReadWord();
1430 _gted[e->index].refitmask_valid = true;
1431 break;
1433 case 0x1A: // Long format introduction date (days since year 0)
1434 ei->base_intro = buf->ReadDWord();
1435 break;
1437 case 0x1B: // Alter purchase list sort order
1438 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1439 break;
1441 case 0x1C: // Visual effect
1442 svi->visual_effect = buf->ReadByte();
1443 /* Avoid accidentally setting visual_effect to the default value
1444 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1445 if (svi->visual_effect == VE_DEFAULT) {
1446 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1447 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1449 break;
1451 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1452 ei->cargo_age_period = buf->ReadWord();
1453 break;
1455 default:
1456 ret = CommonVehicleChangeInfo(ei, prop, buf);
1457 break;
1461 return ret;
1465 * Define properties for aircraft
1466 * @param engine Local ID of the aircraft.
1467 * @param numinfo Number of subsequent IDs to change the property for.
1468 * @param prop The property to change.
1469 * @param buf The property value.
1470 * @return ChangeInfoResult.
1472 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1474 ChangeInfoResult ret = CIR_SUCCESS;
1476 for (int i = 0; i < numinfo; i++) {
1477 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1478 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1480 EngineInfo *ei = &e->info;
1481 AircraftVehicleInfo *avi = &e->u.air;
1483 switch (prop) {
1484 case 0x08: { // Sprite ID
1485 uint8 spriteid = buf->ReadByte();
1487 /* aircraft have different custom id in the GRF file */
1488 if (spriteid == 0xFF) spriteid = 0xFD;
1490 if (spriteid < 0xFD) spriteid >>= 1;
1492 avi->image_index = spriteid;
1493 break;
1496 case 0x09: // Helicopter
1497 if (buf->ReadByte() == 0) {
1498 avi->subtype = AIR_HELI;
1499 } else {
1500 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1502 break;
1504 case 0x0A: // Large
1505 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1506 break;
1508 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1509 avi->cost_factor = buf->ReadByte();
1510 break;
1512 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1513 avi->max_speed = (buf->ReadByte() * 128) / 10;
1514 break;
1516 case 0x0D: // Acceleration
1517 avi->acceleration = (buf->ReadByte() * 128) / 10;
1518 break;
1520 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1521 avi->running_cost = buf->ReadByte();
1522 break;
1524 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1525 avi->passenger_capacity = buf->ReadWord();
1526 break;
1528 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1529 avi->mail_capacity = buf->ReadByte();
1530 break;
1532 case 0x12: // SFX
1533 avi->sfx = buf->ReadByte();
1534 break;
1536 case 0x13: // Cargos available for refitting
1537 ei->refit_mask = buf->ReadDWord();
1538 _gted[e->index].refitmask_valid = true;
1539 _gted[e->index].refitmask_grf = _cur.grffile;
1540 break;
1542 case 0x14: // Callback mask
1543 ei->callback_mask = buf->ReadByte();
1544 break;
1546 case 0x15: // Refit cost
1547 ei->refit_cost = buf->ReadByte();
1548 break;
1550 case 0x16: // Retire vehicle early
1551 ei->retire_early = buf->ReadByte();
1552 break;
1554 case 0x17: // Miscellaneous flags
1555 ei->misc_flags = buf->ReadByte();
1556 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1557 break;
1559 case 0x18: // Cargo classes allowed
1560 _gted[e->index].cargo_allowed = buf->ReadWord();
1561 _gted[e->index].refitmask_valid = true;
1562 break;
1564 case 0x19: // Cargo classes disallowed
1565 _gted[e->index].cargo_disallowed = buf->ReadWord();
1566 _gted[e->index].refitmask_valid = true;
1567 break;
1569 case 0x1A: // Long format introduction date (days since year 0)
1570 ei->base_intro = buf->ReadDWord();
1571 break;
1573 case 0x1B: // Alter purchase list sort order
1574 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1575 break;
1577 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1578 ei->cargo_age_period = buf->ReadWord();
1579 break;
1581 default:
1582 ret = CommonVehicleChangeInfo(ei, prop, buf);
1583 break;
1587 return ret;
1591 * Define properties for stations
1592 * @param stdid StationID of the first station tile.
1593 * @param numinfo Number of subsequent station tiles to change the property for.
1594 * @param prop The property to change.
1595 * @param buf The property value.
1596 * @return ChangeInfoResult.
1598 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1600 ChangeInfoResult ret = CIR_SUCCESS;
1602 if (stid + numinfo > MAX_STATIONS) {
1603 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
1604 return CIR_INVALID_ID;
1607 /* Allocate station specs if necessary */
1608 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
1610 for (int i = 0; i < numinfo; i++) {
1611 StationSpec *statspec = _cur.grffile->stations[stid + i];
1613 /* Check that the station we are modifying is defined. */
1614 if (statspec == NULL && prop != 0x08) {
1615 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1616 return CIR_INVALID_ID;
1619 switch (prop) {
1620 case 0x08: { // Class ID
1621 StationSpec **spec = &_cur.grffile->stations[stid + i];
1623 /* Property 0x08 is special; it is where the station is allocated */
1624 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1626 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1627 uint32 classid = buf->ReadDWord();
1628 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1629 break;
1632 case 0x09: // Define sprite layout
1633 statspec->tiles = buf->ReadExtendedByte();
1634 delete[] statspec->renderdata; // delete earlier loaded stuff
1635 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1637 for (uint t = 0; t < statspec->tiles; t++) {
1638 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1639 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1641 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1642 buf->Skip(4);
1643 extern const DrawTileSprites _station_display_datas_rail[8];
1644 dts->Clone(&_station_display_datas_rail[t % 8]);
1645 continue;
1648 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1649 /* On error, bail out immediately. Temporary GRF data was already freed */
1650 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1652 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1653 tmp_layout.Clear();
1654 for (;;) {
1655 /* no relative bounding box support */
1656 DrawTileSeqStruct *dtss = tmp_layout.Append();
1657 MemSetT(dtss, 0);
1659 dtss->delta_x = buf->ReadByte();
1660 if (dtss->IsTerminator()) break;
1661 dtss->delta_y = buf->ReadByte();
1662 dtss->delta_z = buf->ReadByte();
1663 dtss->size_x = buf->ReadByte();
1664 dtss->size_y = buf->ReadByte();
1665 dtss->size_z = buf->ReadByte();
1667 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1668 /* On error, bail out immediately. Temporary GRF data was already freed */
1669 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1671 dts->Clone(tmp_layout.Begin());
1673 break;
1675 case 0x0A: { // Copy sprite layout
1676 byte srcid = buf->ReadByte();
1677 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1679 if (srcstatspec == NULL) {
1680 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1681 continue;
1684 delete[] statspec->renderdata; // delete earlier loaded stuff
1686 statspec->tiles = srcstatspec->tiles;
1687 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1688 for (uint t = 0; t < statspec->tiles; t++) {
1689 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1691 break;
1694 case 0x0B: // Callback mask
1695 statspec->callback_mask = buf->ReadByte();
1696 break;
1698 case 0x0C: // Disallowed number of platforms
1699 statspec->disallowed_platforms = buf->ReadByte();
1700 break;
1702 case 0x0D: // Disallowed platform lengths
1703 statspec->disallowed_lengths = buf->ReadByte();
1704 break;
1706 case 0x0E: // Define custom layout
1707 statspec->copied_layouts = false;
1709 while (buf->HasData()) {
1710 byte length = buf->ReadByte();
1711 byte number = buf->ReadByte();
1712 StationLayout layout;
1713 uint l, p;
1715 if (length == 0 || number == 0) break;
1717 if (length > statspec->lengths) {
1718 statspec->platforms = ReallocT(statspec->platforms, length);
1719 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1721 statspec->layouts = ReallocT(statspec->layouts, length);
1722 memset(statspec->layouts + statspec->lengths, 0,
1723 (length - statspec->lengths) * sizeof(*statspec->layouts));
1725 statspec->lengths = length;
1727 l = length - 1; // index is zero-based
1729 if (number > statspec->platforms[l]) {
1730 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1731 /* We expect NULL being 0 here, but C99 guarantees that. */
1732 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1733 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1735 statspec->platforms[l] = number;
1738 p = 0;
1739 layout = MallocT<byte>(length * number);
1740 try {
1741 for (l = 0; l < length; l++) {
1742 for (p = 0; p < number; p++) {
1743 layout[l * number + p] = buf->ReadByte();
1746 } catch (...) {
1747 free(layout);
1748 throw;
1751 l--;
1752 p--;
1753 free(statspec->layouts[l][p]);
1754 statspec->layouts[l][p] = layout;
1756 break;
1758 case 0x0F: { // Copy custom layout
1759 byte srcid = buf->ReadByte();
1760 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1762 if (srcstatspec == NULL) {
1763 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
1764 continue;
1767 statspec->lengths = srcstatspec->lengths;
1768 statspec->platforms = srcstatspec->platforms;
1769 statspec->layouts = srcstatspec->layouts;
1770 statspec->copied_layouts = true;
1771 break;
1774 case 0x10: // Little/lots cargo threshold
1775 statspec->cargo_threshold = buf->ReadWord();
1776 break;
1778 case 0x11: // Pylon placement
1779 statspec->pylons = buf->ReadByte();
1780 break;
1782 case 0x12: // Cargo types for random triggers
1783 statspec->cargo_triggers = buf->ReadDWord();
1784 break;
1786 case 0x13: // General flags
1787 statspec->flags = buf->ReadByte();
1788 break;
1790 case 0x14: // Overhead wire placement
1791 statspec->wires = buf->ReadByte();
1792 break;
1794 case 0x15: // Blocked tiles
1795 statspec->blocked = buf->ReadByte();
1796 break;
1798 case 0x16: // Animation info
1799 statspec->animation.frames = buf->ReadByte();
1800 statspec->animation.status = buf->ReadByte();
1801 break;
1803 case 0x17: // Animation speed
1804 statspec->animation.speed = buf->ReadByte();
1805 break;
1807 case 0x18: // Animation triggers
1808 statspec->animation.triggers = buf->ReadWord();
1809 break;
1811 case 0x1A: // Advanced sprite layout
1812 statspec->tiles = buf->ReadExtendedByte();
1813 delete[] statspec->renderdata; // delete earlier loaded stuff
1814 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1816 for (uint t = 0; t < statspec->tiles; t++) {
1817 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1818 uint num_building_sprites = buf->ReadByte();
1819 /* On error, bail out immediately. Temporary GRF data was already freed */
1820 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
1822 break;
1824 default:
1825 ret = CIR_UNKNOWN;
1826 break;
1830 return ret;
1834 * Define properties for water features
1835 * @param id Type of the first water feature.
1836 * @param numinfo Number of subsequent water feature ids to change the property for.
1837 * @param prop The property to change.
1838 * @param buf The property value.
1839 * @return ChangeInfoResult.
1841 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
1843 ChangeInfoResult ret = CIR_SUCCESS;
1845 if (id + numinfo > CF_END) {
1846 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END);
1847 return CIR_INVALID_ID;
1850 for (int i = 0; i < numinfo; i++) {
1851 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
1853 switch (prop) {
1854 case 0x08:
1855 cp->callback_mask = buf->ReadByte();
1856 break;
1858 case 0x09:
1859 cp->flags = buf->ReadByte();
1860 break;
1862 default:
1863 ret = CIR_UNKNOWN;
1864 break;
1868 return ret;
1872 * Define properties for bridges
1873 * @param brid BridgeID of the bridge.
1874 * @param numinfo Number of subsequent bridgeIDs to change the property for.
1875 * @param prop The property to change.
1876 * @param buf The property value.
1877 * @return ChangeInfoResult.
1879 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
1881 ChangeInfoResult ret = CIR_SUCCESS;
1883 if (brid + numinfo > MAX_BRIDGES) {
1884 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
1885 return CIR_INVALID_ID;
1888 for (int i = 0; i < numinfo; i++) {
1889 BridgeSpec *bridge = &_bridge[brid + i];
1891 switch (prop) {
1892 case 0x08: { // Year of availability
1893 /* We treat '0' as always available */
1894 byte year = buf->ReadByte();
1895 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
1896 break;
1899 case 0x09: // Minimum length
1900 bridge->min_length = buf->ReadByte();
1901 break;
1903 case 0x0A: // Maximum length
1904 bridge->max_length = buf->ReadByte();
1905 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
1906 break;
1908 case 0x0B: // Cost factor
1909 bridge->price = buf->ReadByte();
1910 break;
1912 case 0x0C: // Maximum speed
1913 bridge->speed = buf->ReadWord();
1914 break;
1916 case 0x0D: { // Bridge sprite tables
1917 byte tableid = buf->ReadByte();
1918 byte numtables = buf->ReadByte();
1920 if (bridge->sprite_table == NULL) {
1921 /* Allocate memory for sprite table pointers and zero out */
1922 bridge->sprite_table = CallocT<PalSpriteID*>(7);
1925 for (; numtables-- != 0; tableid++) {
1926 if (tableid >= 7) { // skip invalid data
1927 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
1928 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
1929 continue;
1932 if (bridge->sprite_table[tableid] == NULL) {
1933 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
1936 for (byte sprite = 0; sprite < 32; sprite++) {
1937 SpriteID image = buf->ReadWord();
1938 PaletteID pal = buf->ReadWord();
1940 bridge->sprite_table[tableid][sprite].sprite = image;
1941 bridge->sprite_table[tableid][sprite].pal = pal;
1943 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
1946 break;
1949 case 0x0E: // Flags; bit 0 - disable far pillars
1950 bridge->flags = buf->ReadByte();
1951 break;
1953 case 0x0F: // Long format year of availability (year since year 0)
1954 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
1955 break;
1957 case 0x10: { // purchase string
1958 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
1959 if (newone != STR_UNDEFINED) bridge->material = newone;
1960 break;
1963 case 0x11: // description of bridge with rails or roads
1964 case 0x12: {
1965 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
1966 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
1967 break;
1970 case 0x13: // 16 bits cost multiplier
1971 bridge->price = buf->ReadWord();
1972 break;
1974 default:
1975 ret = CIR_UNKNOWN;
1976 break;
1980 return ret;
1984 * Ignore a house property
1985 * @param prop Property to read.
1986 * @param buf Property value.
1987 * @return ChangeInfoResult.
1989 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
1991 ChangeInfoResult ret = CIR_SUCCESS;
1993 switch (prop) {
1994 case 0x09:
1995 case 0x0B:
1996 case 0x0C:
1997 case 0x0D:
1998 case 0x0E:
1999 case 0x0F:
2000 case 0x11:
2001 case 0x14:
2002 case 0x15:
2003 case 0x16:
2004 case 0x18:
2005 case 0x19:
2006 case 0x1A:
2007 case 0x1B:
2008 case 0x1C:
2009 case 0x1D:
2010 case 0x1F:
2011 buf->ReadByte();
2012 break;
2014 case 0x0A:
2015 case 0x10:
2016 case 0x12:
2017 case 0x13:
2018 case 0x21:
2019 case 0x22:
2020 buf->ReadWord();
2021 break;
2023 case 0x1E:
2024 buf->ReadDWord();
2025 break;
2027 case 0x17:
2028 for (uint j = 0; j < 4; j++) buf->ReadByte();
2029 break;
2031 case 0x20: {
2032 byte count = buf->ReadByte();
2033 for (byte j = 0; j < count; j++) buf->ReadByte();
2034 ret = CIR_UNHANDLED;
2035 break;
2038 default:
2039 ret = CIR_UNKNOWN;
2040 break;
2042 return ret;
2046 * Define properties for houses
2047 * @param hid HouseID of the house.
2048 * @param numinfo Number of subsequent houseIDs to change the property for.
2049 * @param prop The property to change.
2050 * @param buf The property value.
2051 * @return ChangeInfoResult.
2053 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2055 ChangeInfoResult ret = CIR_SUCCESS;
2057 if (hid + numinfo > HOUSE_MAX) {
2058 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
2059 return CIR_INVALID_ID;
2062 /* Allocate house specs if they haven't been allocated already. */
2063 if (_cur.grffile->housespec == NULL) {
2064 _cur.grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
2067 for (int i = 0; i < numinfo; i++) {
2068 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2070 if (prop != 0x08 && housespec == NULL) {
2071 /* If the house property 08 is not yet set, ignore this property */
2072 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2073 if (cir > ret) ret = cir;
2074 continue;
2077 switch (prop) {
2078 case 0x08: { // Substitute building type, and definition of a new house
2079 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2080 byte subs_id = buf->ReadByte();
2082 if (subs_id == 0xFF) {
2083 /* Instead of defining a new house, a substitute house id
2084 * of 0xFF disables the old house with the current id. */
2085 HouseSpec::Get(hid + i)->enabled = false;
2086 continue;
2087 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2088 /* The substitute id must be one of the original houses. */
2089 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2090 continue;
2093 /* Allocate space for this house. */
2094 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2096 housespec = *house;
2098 MemCpyT(housespec, HouseSpec::Get(subs_id));
2100 housespec->enabled = true;
2101 housespec->grf_prop.local_id = hid + i;
2102 housespec->grf_prop.subst_id = subs_id;
2103 housespec->grf_prop.grffile = _cur.grffile;
2104 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2105 housespec->random_colour[1] = 0x08; // for all new houses
2106 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2107 housespec->random_colour[3] = 0x06;
2109 /* Make sure that the third cargo type is valid in this
2110 * climate. This can cause problems when copying the properties
2111 * of a house that accepts food, where the new house is valid
2112 * in the temperate climate. */
2113 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2114 housespec->cargo_acceptance[2] = 0;
2118 * New houses do not (currently) expect to have a default start
2119 * date before 1930, as this breaks the build date stuff.
2120 * @see FinaliseHouseArray() for more details.
2122 if (housespec->min_year < 1930) housespec->min_year = 1930;
2124 _loaded_newgrf_features.has_newhouses = true;
2125 break;
2128 case 0x09: // Building flags
2129 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2130 break;
2132 case 0x0A: { // Availability years
2133 uint16 years = buf->ReadWord();
2134 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2135 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2136 break;
2139 case 0x0B: // Population
2140 housespec->population = buf->ReadByte();
2141 break;
2143 case 0x0C: // Mail generation multiplier
2144 housespec->mail_generation = buf->ReadByte();
2145 break;
2147 case 0x0D: // Passenger acceptance
2148 case 0x0E: // Mail acceptance
2149 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2150 break;
2152 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2153 int8 goods = buf->ReadByte();
2155 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2156 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2157 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2158 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2160 /* Make sure the cargo type is valid in this climate. */
2161 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2163 housespec->accepts_cargo[2] = cid;
2164 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2165 break;
2168 case 0x10: // Local authority rating decrease on removal
2169 housespec->remove_rating_decrease = buf->ReadWord();
2170 break;
2172 case 0x11: // Removal cost multiplier
2173 housespec->removal_cost = buf->ReadByte();
2174 break;
2176 case 0x12: // Building name ID
2177 housespec->building_name = buf->ReadWord();
2178 _string_to_grf_mapping[&housespec->building_name] = _cur.grffile->grfid;
2179 break;
2181 case 0x13: // Building availability mask
2182 housespec->building_availability = (HouseZones)buf->ReadWord();
2183 break;
2185 case 0x14: // House callback mask
2186 housespec->callback_mask |= buf->ReadByte();
2187 break;
2189 case 0x15: { // House override byte
2190 byte override = buf->ReadByte();
2192 /* The house being overridden must be an original house. */
2193 if (override >= NEW_HOUSE_OFFSET) {
2194 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2195 continue;
2198 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2199 break;
2202 case 0x16: // Periodic refresh multiplier
2203 housespec->processing_time = min(buf->ReadByte(), 63);
2204 break;
2206 case 0x17: // Four random colours to use
2207 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2208 break;
2210 case 0x18: // Relative probability of appearing
2211 housespec->probability = buf->ReadByte();
2212 break;
2214 case 0x19: // Extra flags
2215 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2216 break;
2218 case 0x1A: // Animation frames
2219 housespec->animation.frames = buf->ReadByte();
2220 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2221 SB(housespec->animation.frames, 7, 1, 0);
2222 break;
2224 case 0x1B: // Animation speed
2225 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2226 break;
2228 case 0x1C: // Class of the building type
2229 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2230 break;
2232 case 0x1D: // Callback mask part 2
2233 housespec->callback_mask |= (buf->ReadByte() << 8);
2234 break;
2236 case 0x1E: { // Accepted cargo types
2237 uint32 cargotypes = buf->ReadDWord();
2239 /* Check if the cargo types should not be changed */
2240 if (cargotypes == 0xFFFFFFFF) break;
2242 for (uint j = 0; j < 3; j++) {
2243 /* Get the cargo number from the 'list' */
2244 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2245 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2247 if (cargo == CT_INVALID) {
2248 /* Disable acceptance of invalid cargo type */
2249 housespec->cargo_acceptance[j] = 0;
2250 } else {
2251 housespec->accepts_cargo[j] = cargo;
2254 break;
2257 case 0x1F: // Minimum life span
2258 housespec->minimum_life = buf->ReadByte();
2259 break;
2261 case 0x20: { // @todo Cargo acceptance watch list
2262 byte count = buf->ReadByte();
2263 for (byte j = 0; j < count; j++) buf->ReadByte();
2264 ret = CIR_UNHANDLED;
2265 break;
2268 case 0x21: // long introduction year
2269 housespec->min_year = buf->ReadWord();
2270 break;
2272 case 0x22: // long maximum year
2273 housespec->max_year = buf->ReadWord();
2274 break;
2276 default:
2277 ret = CIR_UNKNOWN;
2278 break;
2282 return ret;
2286 * Get the language map associated with a given NewGRF and language.
2287 * @param grfid The NewGRF to get the map for.
2288 * @param language_id The (NewGRF) language ID to get the map for.
2289 * @return The LanguageMap, or NULL if it couldn't be found.
2291 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2293 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2294 const GRFFile *grffile = GetFileByGRFID(grfid);
2295 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2299 * Define properties for global variables
2300 * @param gvid ID of the global variable.
2301 * @param numinfo Number of subsequent IDs to change the property for.
2302 * @param prop The property to change.
2303 * @param buf The property value.
2304 * @return ChangeInfoResult.
2306 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2308 ChangeInfoResult ret = CIR_SUCCESS;
2310 for (int i = 0; i < numinfo; i++) {
2311 switch (prop) {
2312 case 0x08: { // Cost base factor
2313 int factor = buf->ReadByte();
2314 uint price = gvid + i;
2316 if (price < PR_END) {
2317 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2318 } else {
2319 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2321 break;
2324 case 0x09: // Cargo translation table
2325 /* This is loaded during the reservation stage, so just skip it here. */
2326 /* Each entry is 4 bytes. */
2327 buf->Skip(4);
2328 break;
2330 case 0x0A: { // Currency display names
2331 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2332 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2334 if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
2335 _currency_specs[curidx].name = newone;
2337 break;
2340 case 0x0B: { // Currency multipliers
2341 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2342 uint32 rate = buf->ReadDWord();
2344 if (curidx < NUM_CURRENCY) {
2345 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2346 * which OTTD does not. For this reason, divide grf value by 1000,
2347 * to be compatible */
2348 _currency_specs[curidx].rate = rate / 1000;
2349 } else {
2350 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2352 break;
2355 case 0x0C: { // Currency options
2356 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2357 uint16 options = buf->ReadWord();
2359 if (curidx < NUM_CURRENCY) {
2360 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2361 _currency_specs[curidx].separator[1] = '\0';
2362 /* By specifying only one bit, we prevent errors,
2363 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2364 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2365 } else {
2366 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2368 break;
2371 case 0x0D: { // Currency prefix symbol
2372 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2373 uint32 tempfix = buf->ReadDWord();
2375 if (curidx < NUM_CURRENCY) {
2376 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2377 _currency_specs[curidx].prefix[4] = 0;
2378 } else {
2379 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2381 break;
2384 case 0x0E: { // Currency suffix symbol
2385 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2386 uint32 tempfix = buf->ReadDWord();
2388 if (curidx < NUM_CURRENCY) {
2389 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2390 _currency_specs[curidx].suffix[4] = 0;
2391 } else {
2392 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2394 break;
2397 case 0x0F: { // Euro introduction dates
2398 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2399 Year year_euro = buf->ReadWord();
2401 if (curidx < NUM_CURRENCY) {
2402 _currency_specs[curidx].to_euro = year_euro;
2403 } else {
2404 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2406 break;
2409 case 0x10: // Snow line height table
2410 if (numinfo > 1 || IsSnowLineSet()) {
2411 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2412 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2413 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2414 } else {
2415 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2417 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2418 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2419 table[i][j] = buf->ReadByte();
2422 SetSnowLine(table);
2424 break;
2426 case 0x11: // GRF match for engine allocation
2427 /* This is loaded during the reservation stage, so just skip it here. */
2428 /* Each entry is 8 bytes. */
2429 buf->Skip(8);
2430 break;
2432 case 0x12: // Rail type translation table
2433 /* This is loaded during the reservation stage, so just skip it here. */
2434 /* Each entry is 4 bytes. */
2435 buf->Skip(4);
2436 break;
2438 case 0x13: // Gender translation table
2439 case 0x14: // Case translation table
2440 case 0x15: { // Plural form translation
2441 uint curidx = gvid + i; // The current index, i.e. language.
2442 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2443 if (lang == NULL) {
2444 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2445 /* Skip over the data. */
2446 while (buf->ReadByte() != 0) {
2447 buf->ReadString();
2449 break;
2452 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2454 if (prop == 0x15) {
2455 uint plural_form = buf->ReadByte();
2456 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2457 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2458 } else {
2459 _cur.grffile->language_map[curidx].plural_form = plural_form;
2461 break;
2464 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2465 while (newgrf_id != 0) {
2466 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2468 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2469 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2470 * is just a subset of UTF8, or they need the bigger UTF8 characters
2471 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2472 WChar c;
2473 size_t len = Utf8Decode(&c, name);
2474 if (c == NFO_UTF8_IDENTIFIER) name += len;
2476 LanguageMap::Mapping map;
2477 map.newgrf_id = newgrf_id;
2478 if (prop == 0x13) {
2479 map.openttd_id = lang->GetGenderIndex(name);
2480 if (map.openttd_id >= MAX_NUM_GENDERS) {
2481 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2482 } else {
2483 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2485 } else {
2486 map.openttd_id = lang->GetCaseIndex(name);
2487 if (map.openttd_id >= MAX_NUM_CASES) {
2488 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2489 } else {
2490 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2493 newgrf_id = buf->ReadByte();
2495 break;
2498 default:
2499 ret = CIR_UNKNOWN;
2500 break;
2504 return ret;
2507 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2509 ChangeInfoResult ret = CIR_SUCCESS;
2511 for (int i = 0; i < numinfo; i++) {
2512 switch (prop) {
2513 case 0x08: // Cost base factor
2514 case 0x15: // Plural form translation
2515 buf->ReadByte();
2516 break;
2518 case 0x09: { // Cargo Translation Table
2519 if (i == 0) {
2520 if (gvid != 0) {
2521 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
2522 return CIR_INVALID_ID;
2525 free(_cur.grffile->cargo_list);
2526 _cur.grffile->cargo_max = numinfo;
2527 _cur.grffile->cargo_list = MallocT<CargoLabel>(numinfo);
2530 CargoLabel cl = buf->ReadDWord();
2531 _cur.grffile->cargo_list[i] = BSWAP32(cl);
2532 break;
2535 case 0x0A: // Currency display names
2536 case 0x0C: // Currency options
2537 case 0x0F: // Euro introduction dates
2538 buf->ReadWord();
2539 break;
2541 case 0x0B: // Currency multipliers
2542 case 0x0D: // Currency prefix symbol
2543 case 0x0E: // Currency suffix symbol
2544 buf->ReadDWord();
2545 break;
2547 case 0x10: // Snow line height table
2548 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2549 break;
2551 case 0x11: { // GRF match for engine allocation
2552 uint32 s = buf->ReadDWord();
2553 uint32 t = buf->ReadDWord();
2554 SetNewGRFOverride(s, t);
2555 break;
2558 case 0x12: { // Rail type translation table
2559 if (i == 0) {
2560 if (gvid != 0) {
2561 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
2562 return CIR_INVALID_ID;
2565 free(_cur.grffile->railtype_list);
2566 _cur.grffile->railtype_max = numinfo;
2567 _cur.grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
2570 RailTypeLabel rtl = buf->ReadDWord();
2571 _cur.grffile->railtype_list[i] = BSWAP32(rtl);
2572 break;
2575 case 0x13: // Gender translation table
2576 case 0x14: // Case translation table
2577 while (buf->ReadByte() != 0) {
2578 buf->ReadString();
2580 break;
2582 default:
2583 ret = CIR_UNKNOWN;
2584 break;
2588 return ret;
2593 * Define properties for cargos
2594 * @param cid Local ID of the cargo.
2595 * @param numinfo Number of subsequent IDs to change the property for.
2596 * @param prop The property to change.
2597 * @param buf The property value.
2598 * @return ChangeInfoResult.
2600 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2602 ChangeInfoResult ret = CIR_SUCCESS;
2604 if (cid + numinfo > NUM_CARGO) {
2605 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2606 return CIR_INVALID_ID;
2609 for (int i = 0; i < numinfo; i++) {
2610 CargoSpec *cs = CargoSpec::Get(cid + i);
2612 switch (prop) {
2613 case 0x08: // Bit number of cargo
2614 cs->bitnum = buf->ReadByte();
2615 if (cs->IsValid()) {
2616 cs->grffile = _cur.grffile;
2617 SetBit(_cargo_mask, cid + i);
2618 } else {
2619 ClrBit(_cargo_mask, cid + i);
2621 break;
2623 case 0x09: // String ID for cargo type name
2624 cs->name = buf->ReadWord();
2625 _string_to_grf_mapping[&cs->name] = _cur.grffile->grfid;
2626 break;
2628 case 0x0A: // String for 1 unit of cargo
2629 cs->name_single = buf->ReadWord();
2630 _string_to_grf_mapping[&cs->name_single] = _cur.grffile->grfid;
2631 break;
2633 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2634 case 0x1B: // String for cargo units
2635 /* String for units of cargo. This is different in OpenTTD
2636 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2637 * Property 1B is used to set OpenTTD's behaviour. */
2638 cs->units_volume = buf->ReadWord();
2639 _string_to_grf_mapping[&cs->units_volume] = _cur.grffile->grfid;
2640 break;
2642 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2643 case 0x1C: // String for any amount of cargo
2644 /* Strings for an amount of cargo. This is different in OpenTTD
2645 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2646 * Property 1C is used to set OpenTTD's behaviour. */
2647 cs->quantifier = buf->ReadWord();
2648 _string_to_grf_mapping[&cs->quantifier] = _cur.grffile->grfid;
2649 break;
2651 case 0x0D: // String for two letter cargo abbreviation
2652 cs->abbrev = buf->ReadWord();
2653 _string_to_grf_mapping[&cs->abbrev] = _cur.grffile->grfid;
2654 break;
2656 case 0x0E: // Sprite ID for cargo icon
2657 cs->sprite = buf->ReadWord();
2658 break;
2660 case 0x0F: // Weight of one unit of cargo
2661 cs->weight = buf->ReadByte();
2662 break;
2664 case 0x10: // Used for payment calculation
2665 cs->transit_days[0] = buf->ReadByte();
2666 break;
2668 case 0x11: // Used for payment calculation
2669 cs->transit_days[1] = buf->ReadByte();
2670 break;
2672 case 0x12: // Base cargo price
2673 cs->initial_payment = buf->ReadDWord();
2674 break;
2676 case 0x13: // Colour for station rating bars
2677 cs->rating_colour = buf->ReadByte();
2678 break;
2680 case 0x14: // Colour for cargo graph
2681 cs->legend_colour = buf->ReadByte();
2682 break;
2684 case 0x15: // Freight status
2685 cs->is_freight = (buf->ReadByte() != 0);
2686 break;
2688 case 0x16: // Cargo classes
2689 cs->classes = buf->ReadWord();
2690 break;
2692 case 0x17: // Cargo label
2693 cs->label = buf->ReadDWord();
2694 cs->label = BSWAP32(cs->label);
2695 break;
2697 case 0x18: { // Town growth substitute type
2698 uint8 substitute_type = buf->ReadByte();
2700 switch (substitute_type) {
2701 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2702 case 0x02: cs->town_effect = TE_MAIL; break;
2703 case 0x05: cs->town_effect = TE_GOODS; break;
2704 case 0x09: cs->town_effect = TE_WATER; break;
2705 case 0x0B: cs->town_effect = TE_FOOD; break;
2706 default:
2707 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2708 case 0xFF: cs->town_effect = TE_NONE; break;
2710 break;
2713 case 0x19: // Town growth coefficient
2714 cs->multipliertowngrowth = buf->ReadWord();
2715 break;
2717 case 0x1A: // Bitmask of callbacks to use
2718 cs->callback_mask = buf->ReadByte();
2719 break;
2721 default:
2722 ret = CIR_UNKNOWN;
2723 break;
2727 return ret;
2732 * Define properties for sound effects
2733 * @param sid Local ID of the sound.
2734 * @param numinfo Number of subsequent IDs to change the property for.
2735 * @param prop The property to change.
2736 * @param buf The property value.
2737 * @return ChangeInfoResult.
2739 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
2741 ChangeInfoResult ret = CIR_SUCCESS;
2743 if (_cur.grffile->sound_offset == 0) {
2744 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
2745 return CIR_INVALID_ID;
2748 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
2749 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
2750 return CIR_INVALID_ID;
2753 for (int i = 0; i < numinfo; i++) {
2754 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
2756 switch (prop) {
2757 case 0x08: // Relative volume
2758 sound->volume = buf->ReadByte();
2759 break;
2761 case 0x09: // Priority
2762 sound->priority = buf->ReadByte();
2763 break;
2765 case 0x0A: { // Override old sound
2766 SoundID orig_sound = buf->ReadByte();
2768 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
2769 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
2770 } else {
2771 SoundEntry *old_sound = GetSound(orig_sound);
2773 /* Literally copy the data of the new sound over the original */
2774 *old_sound = *sound;
2776 break;
2779 default:
2780 ret = CIR_UNKNOWN;
2781 break;
2785 return ret;
2789 * Ignore an industry tile property
2790 * @param prop The property to ignore.
2791 * @param buf The property value.
2792 * @return ChangeInfoResult.
2794 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
2796 ChangeInfoResult ret = CIR_SUCCESS;
2798 switch (prop) {
2799 case 0x09:
2800 case 0x0D:
2801 case 0x0E:
2802 case 0x10:
2803 case 0x11:
2804 case 0x12:
2805 buf->ReadByte();
2806 break;
2808 case 0x0A:
2809 case 0x0B:
2810 case 0x0C:
2811 case 0x0F:
2812 buf->ReadWord();
2813 break;
2815 default:
2816 ret = CIR_UNKNOWN;
2817 break;
2819 return ret;
2823 * Define properties for industry tiles
2824 * @param indtid Local ID of the industry tile.
2825 * @param numinfo Number of subsequent industry tile IDs to change the property for.
2826 * @param prop The property to change.
2827 * @param buf The property value.
2828 * @return ChangeInfoResult.
2830 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
2832 ChangeInfoResult ret = CIR_SUCCESS;
2834 if (indtid + numinfo > NUM_INDUSTRYTILES) {
2835 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
2836 return CIR_INVALID_ID;
2839 /* Allocate industry tile specs if they haven't been allocated already. */
2840 if (_cur.grffile->indtspec == NULL) {
2841 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
2844 for (int i = 0; i < numinfo; i++) {
2845 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
2847 if (prop != 0x08 && tsp == NULL) {
2848 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
2849 if (cir > ret) ret = cir;
2850 continue;
2853 switch (prop) {
2854 case 0x08: { // Substitute industry tile type
2855 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
2856 byte subs_id = buf->ReadByte();
2858 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
2859 /* The substitute id must be one of the original industry tile. */
2860 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
2861 continue;
2864 /* Allocate space for this industry. */
2865 if (*tilespec == NULL) {
2866 *tilespec = CallocT<IndustryTileSpec>(1);
2867 tsp = *tilespec;
2869 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
2870 tsp->enabled = true;
2872 /* A copied tile should not have the animation infos copied too.
2873 * The anim_state should be left untouched, though
2874 * It is up to the author to animate them himself */
2875 tsp->anim_production = INDUSTRYTILE_NOANIM;
2876 tsp->anim_next = INDUSTRYTILE_NOANIM;
2878 tsp->grf_prop.local_id = indtid + i;
2879 tsp->grf_prop.subst_id = subs_id;
2880 tsp->grf_prop.grffile = _cur.grffile;
2881 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
2883 break;
2886 case 0x09: { // Industry tile override
2887 byte ovrid = buf->ReadByte();
2889 /* The industry being overridden must be an original industry. */
2890 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
2891 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
2892 continue;
2895 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
2896 break;
2899 case 0x0A: // Tile acceptance
2900 case 0x0B:
2901 case 0x0C: {
2902 uint16 acctp = buf->ReadWord();
2903 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
2904 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
2905 break;
2908 case 0x0D: // Land shape flags
2909 tsp->slopes_refused = (Slope)buf->ReadByte();
2910 break;
2912 case 0x0E: // Callback mask
2913 tsp->callback_mask = buf->ReadByte();
2914 break;
2916 case 0x0F: // Animation information
2917 tsp->animation.frames = buf->ReadByte();
2918 tsp->animation.status = buf->ReadByte();
2919 break;
2921 case 0x10: // Animation speed
2922 tsp->animation.speed = buf->ReadByte();
2923 break;
2925 case 0x11: // Triggers for callback 25
2926 tsp->animation.triggers = buf->ReadByte();
2927 break;
2929 case 0x12: // Special flags
2930 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
2931 break;
2933 default:
2934 ret = CIR_UNKNOWN;
2935 break;
2939 return ret;
2943 * Ignore an industry property
2944 * @param prop The property to ignore.
2945 * @param buf The property value.
2946 * @return ChangeInfoResult.
2948 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
2950 ChangeInfoResult ret = CIR_SUCCESS;
2952 switch (prop) {
2953 case 0x09:
2954 case 0x0B:
2955 case 0x0F:
2956 case 0x12:
2957 case 0x13:
2958 case 0x14:
2959 case 0x17:
2960 case 0x18:
2961 case 0x19:
2962 case 0x21:
2963 case 0x22:
2964 buf->ReadByte();
2965 break;
2967 case 0x0C:
2968 case 0x0D:
2969 case 0x0E:
2970 case 0x10:
2971 case 0x1B:
2972 case 0x1F:
2973 case 0x24:
2974 buf->ReadWord();
2975 break;
2977 case 0x11:
2978 case 0x1A:
2979 case 0x1C:
2980 case 0x1D:
2981 case 0x1E:
2982 case 0x20:
2983 case 0x23:
2984 buf->ReadDWord();
2985 break;
2987 case 0x0A: {
2988 byte num_table = buf->ReadByte();
2989 for (byte j = 0; j < num_table; j++) {
2990 for (uint k = 0;; k++) {
2991 byte x = buf->ReadByte();
2992 if (x == 0xFE && k == 0) {
2993 buf->ReadByte();
2994 buf->ReadByte();
2995 break;
2998 byte y = buf->ReadByte();
2999 if (x == 0 && y == 0x80) break;
3001 byte gfx = buf->ReadByte();
3002 if (gfx == 0xFE) buf->ReadWord();
3005 break;
3008 case 0x16:
3009 for (byte j = 0; j < 3; j++) buf->ReadByte();
3010 break;
3012 case 0x15: {
3013 byte number_of_sounds = buf->ReadByte();
3014 for (uint8 j = 0; j < number_of_sounds; j++) {
3015 buf->ReadByte();
3017 break;
3020 default:
3021 ret = CIR_UNKNOWN;
3022 break;
3024 return ret;
3028 * Validate the industry layout; e.g. to prevent duplicate tiles.
3029 * @param layout The layout to check.
3030 * @param size The size of the layout.
3031 * @return True if the layout is deemed valid.
3033 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3035 for (int i = 0; i < size - 1; i++) {
3036 for (int j = i + 1; j < size; j++) {
3037 if (layout[i].ti.x == layout[j].ti.x &&
3038 layout[i].ti.y == layout[j].ti.y) {
3039 return false;
3043 return true;
3046 /** Clean the tile table of the IndustrySpec if it's needed. */
3047 static void CleanIndustryTileTable(IndustrySpec *ind)
3049 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3050 for (int j = 0; j < ind->num_table; j++) {
3051 /* remove the individual layouts */
3052 free((void*)ind->table[j]);
3054 /* remove the layouts pointers */
3055 free((void*)ind->table);
3056 ind->table = NULL;
3061 * Define properties for industries
3062 * @param indid Local ID of the industry.
3063 * @param numinfo Number of subsequent industry IDs to change the property for.
3064 * @param prop The property to change.
3065 * @param buf The property value.
3066 * @return ChangeInfoResult.
3068 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3070 ChangeInfoResult ret = CIR_SUCCESS;
3072 if (indid + numinfo > NUM_INDUSTRYTYPES) {
3073 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
3074 return CIR_INVALID_ID;
3077 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
3079 /* Allocate industry specs if they haven't been allocated already. */
3080 if (_cur.grffile->industryspec == NULL) {
3081 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
3084 for (int i = 0; i < numinfo; i++) {
3085 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3087 if (prop != 0x08 && indsp == NULL) {
3088 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3089 if (cir > ret) ret = cir;
3090 continue;
3093 switch (prop) {
3094 case 0x08: { // Substitute industry type
3095 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3096 byte subs_id = buf->ReadByte();
3098 if (subs_id == 0xFF) {
3099 /* Instead of defining a new industry, a substitute industry id
3100 * of 0xFF disables the old industry with the current id. */
3101 _industry_specs[indid + i].enabled = false;
3102 continue;
3103 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3104 /* The substitute id must be one of the original industry. */
3105 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3106 continue;
3109 /* Allocate space for this industry.
3110 * Only need to do it once. If ever it is called again, it should not
3111 * do anything */
3112 if (*indspec == NULL) {
3113 *indspec = CallocT<IndustrySpec>(1);
3114 indsp = *indspec;
3116 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3117 indsp->enabled = true;
3118 indsp->grf_prop.local_id = indid + i;
3119 indsp->grf_prop.subst_id = subs_id;
3120 indsp->grf_prop.grffile = _cur.grffile;
3121 /* If the grf industry needs to check its surounding upon creation, it should
3122 * rely on callbacks, not on the original placement functions */
3123 indsp->check_proc = CHECK_NOTHING;
3125 break;
3128 case 0x09: { // Industry type override
3129 byte ovrid = buf->ReadByte();
3131 /* The industry being overridden must be an original industry. */
3132 if (ovrid >= NEW_INDUSTRYOFFSET) {
3133 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3134 continue;
3136 indsp->grf_prop.override = ovrid;
3137 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3138 break;
3141 case 0x0A: { // Set industry layout(s)
3142 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3143 /* We read the total size in bytes, but we can't rely on the
3144 * newgrf to provide a sane value. First assume the value is
3145 * sane but later on we make sure we enlarge the array if the
3146 * newgrf contains more data. Each tile uses either 3 or 5
3147 * bytes, so to play it safe we assume 3. */
3148 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3149 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3150 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3151 uint size;
3152 const IndustryTileTable *copy_from;
3154 try {
3155 for (byte j = 0; j < new_num_layouts; j++) {
3156 for (uint k = 0;; k++) {
3157 if (k >= def_num_tiles) {
3158 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3159 /* Size reported by newgrf was not big enough so enlarge the array. */
3160 def_num_tiles *= 2;
3161 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3164 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3166 if (itt[k].ti.x == 0xFE && k == 0) {
3167 /* This means we have to borrow the layout from an old industry */
3168 IndustryType type = buf->ReadByte(); // industry holding required layout
3169 byte laynbr = buf->ReadByte(); // layout number to borrow
3171 copy_from = _origin_industry_specs[type].table[laynbr];
3172 for (size = 1;; size++) {
3173 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3175 break;
3178 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3180 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3181 /* Not the same terminator. The one we are using is rather
3182 x = -80, y = x . So, adjust it. */
3183 itt[k].ti.x = -0x80;
3184 itt[k].ti.y = 0;
3185 itt[k].gfx = 0;
3187 size = k + 1;
3188 copy_from = itt;
3189 break;
3192 itt[k].gfx = buf->ReadByte();
3194 if (itt[k].gfx == 0xFE) {
3195 /* Use a new tile from this GRF */
3196 int local_tile_id = buf->ReadWord();
3198 /* Read the ID from the _industile_mngr. */
3199 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3201 if (tempid == INVALID_INDUSTRYTILE) {
3202 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3203 } else {
3204 /* Declared as been valid, can be used */
3205 itt[k].gfx = tempid;
3206 size = k + 1;
3207 copy_from = itt;
3209 } else if (itt[k].gfx == 0xFF) {
3210 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3211 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3215 if (!ValidateIndustryLayout(copy_from, size)) {
3216 /* The industry layout was not valid, so skip this one. */
3217 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3218 new_num_layouts--;
3219 j--;
3220 } else {
3221 tile_table[j] = CallocT<IndustryTileTable>(size);
3222 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3225 } catch (...) {
3226 for (int i = 0; i < new_num_layouts; i++) {
3227 free(tile_table[i]);
3229 free(tile_table);
3230 free(itt);
3231 throw;
3234 /* Clean the tile table if it was already set by a previous prop A. */
3235 CleanIndustryTileTable(indsp);
3236 /* Install final layout construction in the industry spec */
3237 indsp->num_table = new_num_layouts;
3238 indsp->table = tile_table;
3239 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3240 free(itt);
3241 break;
3244 case 0x0B: // Industry production flags
3245 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3246 break;
3248 case 0x0C: // Industry closure message
3249 indsp->closure_text = buf->ReadWord();
3250 _string_to_grf_mapping[&indsp->closure_text] = _cur.grffile->grfid;
3251 break;
3253 case 0x0D: // Production increase message
3254 indsp->production_up_text = buf->ReadWord();
3255 _string_to_grf_mapping[&indsp->production_up_text] = _cur.grffile->grfid;
3256 break;
3258 case 0x0E: // Production decrease message
3259 indsp->production_down_text = buf->ReadWord();
3260 _string_to_grf_mapping[&indsp->production_down_text] = _cur.grffile->grfid;
3261 break;
3263 case 0x0F: // Fund cost multiplier
3264 indsp->cost_multiplier = buf->ReadByte();
3265 break;
3267 case 0x10: // Production cargo types
3268 for (byte j = 0; j < 2; j++) {
3269 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3271 break;
3273 case 0x11: // Acceptance cargo types
3274 for (byte j = 0; j < 3; j++) {
3275 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3277 buf->ReadByte(); // Unnused, eat it up
3278 break;
3280 case 0x12: // Production multipliers
3281 case 0x13:
3282 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3283 break;
3285 case 0x14: // Minimal amount of cargo distributed
3286 indsp->minimal_cargo = buf->ReadByte();
3287 break;
3289 case 0x15: { // Random sound effects
3290 indsp->number_of_sounds = buf->ReadByte();
3291 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3293 try {
3294 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3295 sounds[j] = buf->ReadByte();
3297 } catch (...) {
3298 free(sounds);
3299 throw;
3302 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3303 free((void*)indsp->random_sounds);
3305 indsp->random_sounds = sounds;
3306 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3307 break;
3310 case 0x16: // Conflicting industry types
3311 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3312 break;
3314 case 0x17: // Probability in random game
3315 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3316 break;
3318 case 0x18: // Probability during gameplay
3319 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3320 break;
3322 case 0x19: // Map colour
3323 indsp->map_colour = buf->ReadByte();
3324 break;
3326 case 0x1A: // Special industry flags to define special behavior
3327 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3328 break;
3330 case 0x1B: // New industry text ID
3331 indsp->new_industry_text = buf->ReadWord();
3332 _string_to_grf_mapping[&indsp->new_industry_text] = _cur.grffile->grfid;
3333 break;
3335 case 0x1C: // Input cargo multipliers for the three input cargo types
3336 case 0x1D:
3337 case 0x1E: {
3338 uint32 multiples = buf->ReadDWord();
3339 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3340 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3341 break;
3344 case 0x1F: // Industry name
3345 indsp->name = buf->ReadWord();
3346 _string_to_grf_mapping[&indsp->name] = _cur.grffile->grfid;
3347 break;
3349 case 0x20: // Prospecting success chance
3350 indsp->prospecting_chance = buf->ReadDWord();
3351 break;
3353 case 0x21: // Callback mask
3354 case 0x22: { // Callback additional mask
3355 byte aflag = buf->ReadByte();
3356 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3357 break;
3360 case 0x23: // removal cost multiplier
3361 indsp->removal_cost_multiplier = buf->ReadDWord();
3362 break;
3364 case 0x24: // name for nearby station
3365 indsp->station_name = buf->ReadWord();
3366 if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur.grffile->grfid;
3367 break;
3369 default:
3370 ret = CIR_UNKNOWN;
3371 break;
3375 return ret;
3379 * Create a copy of the tile table so it can be freed later
3380 * without problems.
3381 * @param as The AirportSpec to copy the arrays of.
3383 static void DuplicateTileTable(AirportSpec *as)
3385 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3386 for (int i = 0; i < as->num_table; i++) {
3387 uint num_tiles = 1;
3388 const AirportTileTable *it = as->table[0];
3389 do {
3390 num_tiles++;
3391 } while ((++it)->ti.x != -0x80);
3392 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3393 MemCpyT(table_list[i], as->table[i], num_tiles);
3395 as->table = table_list;
3396 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3397 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3398 as->depot_table = depot_table;
3402 * Define properties for airports
3403 * @param airport Local ID of the airport.
3404 * @param numinfo Number of subsequent airport IDs to change the property for.
3405 * @param prop The property to change.
3406 * @param buf The property value.
3407 * @return ChangeInfoResult.
3409 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3411 ChangeInfoResult ret = CIR_SUCCESS;
3413 if (airport + numinfo > NUM_AIRPORTS) {
3414 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS);
3415 return CIR_INVALID_ID;
3418 grfmsg(1, "AirportChangeInfo: newid %u", airport);
3420 /* Allocate industry specs if they haven't been allocated already. */
3421 if (_cur.grffile->airportspec == NULL) {
3422 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS);
3425 for (int i = 0; i < numinfo; i++) {
3426 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3428 if (as == NULL && prop != 0x08 && prop != 0x09) {
3429 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3430 return CIR_INVALID_ID;
3433 switch (prop) {
3434 case 0x08: { // Modify original airport
3435 byte subs_id = buf->ReadByte();
3437 if (subs_id == 0xFF) {
3438 /* Instead of defining a new airport, an airport id
3439 * of 0xFF disables the old airport with the current id. */
3440 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3441 continue;
3442 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3443 /* The substitute id must be one of the original airports. */
3444 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3445 continue;
3448 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3449 /* Allocate space for this airport.
3450 * Only need to do it once. If ever it is called again, it should not
3451 * do anything */
3452 if (*spec == NULL) {
3453 *spec = MallocT<AirportSpec>(1);
3454 as = *spec;
3456 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3457 as->enabled = true;
3458 as->grf_prop.local_id = airport + i;
3459 as->grf_prop.subst_id = subs_id;
3460 as->grf_prop.grffile = _cur.grffile;
3461 /* override the default airport */
3462 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3463 /* Create a copy of the original tiletable so it can be freed later. */
3464 DuplicateTileTable(as);
3466 break;
3469 case 0x0A: { // Set airport layout
3470 as->num_table = buf->ReadByte(); // Number of layaouts
3471 as->rotation = MallocT<Direction>(as->num_table);
3472 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3473 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3474 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3475 int size;
3476 const AirportTileTable *copy_from;
3477 try {
3478 for (byte j = 0; j < as->num_table; j++) {
3479 as->rotation[j] = (Direction)buf->ReadByte();
3480 for (int k = 0;; k++) {
3481 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3482 att[k].ti.y = buf->ReadByte();
3484 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3485 /* Not the same terminator. The one we are using is rather
3486 x= -80, y = 0 . So, adjust it. */
3487 att[k].ti.x = -0x80;
3488 att[k].ti.y = 0;
3489 att[k].gfx = 0;
3491 size = k + 1;
3492 copy_from = att;
3493 break;
3496 att[k].gfx = buf->ReadByte();
3498 if (att[k].gfx == 0xFE) {
3499 /* Use a new tile from this GRF */
3500 int local_tile_id = buf->ReadWord();
3502 /* Read the ID from the _airporttile_mngr. */
3503 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3505 if (tempid == INVALID_AIRPORTTILE) {
3506 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3507 } else {
3508 /* Declared as been valid, can be used */
3509 att[k].gfx = tempid;
3510 size = k + 1;
3511 copy_from = att;
3513 } else if (att[k].gfx == 0xFF) {
3514 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3515 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3518 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3519 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3520 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3521 } else {
3522 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3523 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3526 tile_table[j] = CallocT<AirportTileTable>(size);
3527 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3529 /* Install final layout construction in the airport spec */
3530 as->table = tile_table;
3531 free(att);
3532 } catch (...) {
3533 for (int i = 0; i < as->num_table; i++) {
3534 free(tile_table[i]);
3536 free(tile_table);
3537 free(att);
3538 throw;
3540 break;
3543 case 0x0C:
3544 as->min_year = buf->ReadWord();
3545 as->max_year = buf->ReadWord();
3546 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3547 break;
3549 case 0x0D:
3550 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3551 break;
3553 case 0x0E:
3554 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3555 break;
3557 case 0x0F:
3558 as->noise_level = buf->ReadByte();
3559 break;
3561 case 0x10:
3562 as->name = buf->ReadWord();
3563 _string_to_grf_mapping[&as->name] = _cur.grffile->grfid;
3564 break;
3566 default:
3567 ret = CIR_UNKNOWN;
3568 break;
3572 return ret;
3576 * Ignore properties for objects
3577 * @param prop The property to ignore.
3578 * @param buf The property value.
3579 * @return ChangeInfoResult.
3581 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3583 ChangeInfoResult ret = CIR_SUCCESS;
3585 switch (prop) {
3586 case 0x0B:
3587 case 0x0C:
3588 case 0x0D:
3589 case 0x12:
3590 case 0x14:
3591 case 0x16:
3592 case 0x17:
3593 buf->ReadByte();
3595 case 0x09:
3596 case 0x0A:
3597 case 0x10:
3598 case 0x11:
3599 case 0x13:
3600 case 0x15:
3601 buf->ReadWord();
3602 break;
3604 case 0x08:
3605 case 0x0E:
3606 case 0x0F:
3607 buf->ReadDWord();
3608 break;
3610 default:
3611 ret = CIR_UNKNOWN;
3612 break;
3615 return ret;
3619 * Define properties for objects
3620 * @param id Local ID of the object.
3621 * @param numinfo Number of subsequent objectIDs to change the property for.
3622 * @param prop The property to change.
3623 * @param buf The property value.
3624 * @return ChangeInfoResult.
3626 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3628 ChangeInfoResult ret = CIR_SUCCESS;
3630 if (id + numinfo > NUM_OBJECTS) {
3631 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS);
3632 return CIR_INVALID_ID;
3635 /* Allocate object specs if they haven't been allocated already. */
3636 if (_cur.grffile->objectspec == NULL) {
3637 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS);
3640 for (int i = 0; i < numinfo; i++) {
3641 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3643 if (prop != 0x08 && spec == NULL) {
3644 /* If the object property 08 is not yet set, ignore this property */
3645 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3646 if (cir > ret) ret = cir;
3647 continue;
3650 switch (prop) {
3651 case 0x08: { // Class ID
3652 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3654 /* Allocate space for this object. */
3655 if (*ospec == NULL) {
3656 *ospec = CallocT<ObjectSpec>(1);
3657 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3660 /* Swap classid because we read it in BE. */
3661 uint32 classid = buf->ReadDWord();
3662 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3663 (*ospec)->enabled = true;
3664 break;
3667 case 0x09: { // Class name
3668 StringID class_name = buf->ReadWord();
3669 ObjectClass::SetName(spec->cls_id, class_name);
3670 _string_to_grf_mapping[&ObjectClass::classes[spec->cls_id].name] = _cur.grffile->grfid;
3671 break;
3674 case 0x0A: // Object name
3675 spec->name = buf->ReadWord();
3676 _string_to_grf_mapping[&spec->name] = _cur.grffile->grfid;
3677 break;
3679 case 0x0B: // Climate mask
3680 spec->climate = buf->ReadByte();
3681 break;
3683 case 0x0C: // Size
3684 spec->size = buf->ReadByte();
3685 break;
3687 case 0x0D: // Build cost multipler
3688 spec->build_cost_multiplier = buf->ReadByte();
3689 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3690 break;
3692 case 0x0E: // Introduction date
3693 spec->introduction_date = buf->ReadDWord();
3694 break;
3696 case 0x0F: // End of life
3697 spec->end_of_life_date = buf->ReadDWord();
3698 break;
3700 case 0x10: // Flags
3701 spec->flags = (ObjectFlags)buf->ReadWord();
3702 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3703 break;
3705 case 0x11: // Animation info
3706 spec->animation.frames = buf->ReadByte();
3707 spec->animation.status = buf->ReadByte();
3708 break;
3710 case 0x12: // Animation speed
3711 spec->animation.speed = buf->ReadByte();
3712 break;
3714 case 0x13: // Animation triggers
3715 spec->animation.triggers = buf->ReadWord();
3716 break;
3718 case 0x14: // Removal cost multiplier
3719 spec->clear_cost_multiplier = buf->ReadByte();
3720 break;
3722 case 0x15: // Callback mask
3723 spec->callback_mask = buf->ReadWord();
3724 break;
3726 case 0x16: // Building height
3727 spec->height = buf->ReadByte();
3728 break;
3730 case 0x17: // Views
3731 spec->views = buf->ReadByte();
3732 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
3733 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
3734 spec->views = 1;
3736 break;
3738 default:
3739 ret = CIR_UNKNOWN;
3740 break;
3744 return ret;
3748 * Define properties for railtypes
3749 * @param id ID of the railtype.
3750 * @param numinfo Number of subsequent IDs to change the property for.
3751 * @param prop The property to change.
3752 * @param buf The property value.
3753 * @return ChangeInfoResult.
3755 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3757 ChangeInfoResult ret = CIR_SUCCESS;
3759 extern RailtypeInfo _railtypes[RAILTYPE_END];
3761 if (id + numinfo > RAILTYPE_END) {
3762 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
3763 return CIR_INVALID_ID;
3766 for (int i = 0; i < numinfo; i++) {
3767 RailType rt = _cur.grffile->railtype_map[id + i];
3768 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
3770 RailtypeInfo *rti = &_railtypes[rt];
3772 switch (prop) {
3773 case 0x08: // Label of rail type
3774 /* Skipped here as this is loaded during reservation stage. */
3775 buf->ReadDWord();
3776 break;
3778 case 0x09: // Name of railtype
3779 rti->strings.toolbar_caption = buf->ReadWord();
3780 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur.grffile->grfid;
3781 break;
3783 case 0x0A: // Menu text of railtype
3784 rti->strings.menu_text = buf->ReadWord();
3785 _string_to_grf_mapping[&rti->strings.menu_text] = _cur.grffile->grfid;
3786 break;
3788 case 0x0B: // Build window caption
3789 rti->strings.build_caption = buf->ReadWord();
3790 _string_to_grf_mapping[&rti->strings.build_caption] = _cur.grffile->grfid;
3791 break;
3793 case 0x0C: // Autoreplace text
3794 rti->strings.replace_text = buf->ReadWord();
3795 _string_to_grf_mapping[&rti->strings.replace_text] = _cur.grffile->grfid;
3796 break;
3798 case 0x0D: // New locomotive text
3799 rti->strings.new_loco = buf->ReadWord();
3800 _string_to_grf_mapping[&rti->strings.new_loco] = _cur.grffile->grfid;
3801 break;
3803 case 0x0E: // Compatible railtype list
3804 case 0x0F: // Powered railtype list
3805 case 0x18: // Railtype list required for date introduction
3806 case 0x19: // Introduced railtype list
3808 /* Rail type compatibility bits are added to the existing bits
3809 * to allow multiple GRFs to modify compatibility with the
3810 * default rail types. */
3811 int n = buf->ReadByte();
3812 for (int j = 0; j != n; j++) {
3813 RailTypeLabel label = buf->ReadDWord();
3814 RailType rt = GetRailTypeByLabel(BSWAP32(label));
3815 if (rt != INVALID_RAILTYPE) {
3816 switch (prop) {
3817 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
3818 case 0x0F: SetBit(rti->powered_railtypes, rt); break;
3819 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
3820 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
3824 break;
3827 case 0x10: // Rail Type flags
3828 rti->flags = (RailTypeFlags)buf->ReadByte();
3829 break;
3831 case 0x11: // Curve speed advantage
3832 rti->curve_speed = buf->ReadByte();
3833 break;
3835 case 0x12: // Station graphic
3836 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
3837 break;
3839 case 0x13: // Construction cost factor
3840 rti->cost_multiplier = buf->ReadWord();
3841 break;
3843 case 0x14: // Speed limit
3844 rti->max_speed = buf->ReadWord();
3845 break;
3847 case 0x15: // Acceleration model
3848 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
3849 break;
3851 case 0x16: // Map colour
3852 rti->map_colour = buf->ReadByte();
3853 break;
3855 case 0x17: // Introduction date
3856 rti->introduction_date = buf->ReadDWord();
3857 break;
3859 case 0x1A: // Sort order
3860 rti->sorting_order = buf->ReadByte();
3861 break;
3863 default:
3864 ret = CIR_UNKNOWN;
3865 break;
3869 return ret;
3872 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
3874 ChangeInfoResult ret = CIR_SUCCESS;
3876 if (id + numinfo > RAILTYPE_END) {
3877 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
3878 return CIR_INVALID_ID;
3881 for (int i = 0; i < numinfo; i++) {
3882 switch (prop) {
3883 case 0x08: // Label of rail type
3885 RailTypeLabel rtl = buf->ReadDWord();
3886 rtl = BSWAP32(rtl);
3888 RailType rt = GetRailTypeByLabel(rtl);
3889 if (rt == INVALID_RAILTYPE) {
3890 /* Set up new rail type */
3891 rt = AllocateRailType(rtl);
3894 _cur.grffile->railtype_map[id + i] = rt;
3895 break;
3898 case 0x09: // Name of railtype
3899 case 0x0A: // Menu text
3900 case 0x0B: // Build window caption
3901 case 0x0C: // Autoreplace text
3902 case 0x0D: // New loco
3903 case 0x13: // Construction cost
3904 case 0x14: // Speed limit
3905 buf->ReadWord();
3906 break;
3908 case 0x0E: // Compatible railtype list
3909 case 0x0F: // Powered railtype list
3910 case 0x18: // Railtype list required for date introduction
3911 case 0x19: // Introduced railtype list
3912 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
3913 break;
3915 case 0x10: // Rail Type flags
3916 case 0x11: // Curve speed advantage
3917 case 0x12: // Station graphic
3918 case 0x15: // Acceleration model
3919 case 0x16: // Map colour
3920 case 0x1A: // Sort order
3921 buf->ReadByte();
3922 break;
3924 case 0x17: // Introduction date
3925 buf->ReadDWord();
3926 break;
3928 default:
3929 ret = CIR_UNKNOWN;
3930 break;
3934 return ret;
3937 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
3939 ChangeInfoResult ret = CIR_SUCCESS;
3941 if (airtid + numinfo > NUM_AIRPORTTILES) {
3942 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
3943 return CIR_INVALID_ID;
3946 /* Allocate airport tile specs if they haven't been allocated already. */
3947 if (_cur.grffile->airtspec == NULL) {
3948 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
3951 for (int i = 0; i < numinfo; i++) {
3952 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
3954 if (prop != 0x08 && tsp == NULL) {
3955 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
3956 return CIR_INVALID_ID;
3959 switch (prop) {
3960 case 0x08: { // Substitute airport tile type
3961 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
3962 byte subs_id = buf->ReadByte();
3964 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
3965 /* The substitute id must be one of the original airport tiles. */
3966 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
3967 continue;
3970 /* Allocate space for this airport tile. */
3971 if (*tilespec == NULL) {
3972 *tilespec = CallocT<AirportTileSpec>(1);
3973 tsp = *tilespec;
3975 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
3976 tsp->enabled = true;
3978 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
3980 tsp->grf_prop.local_id = airtid + i;
3981 tsp->grf_prop.subst_id = subs_id;
3982 tsp->grf_prop.grffile = _cur.grffile;
3983 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3985 break;
3988 case 0x09: { // Airport tile override
3989 byte override = buf->ReadByte();
3991 /* The airport tile being overridden must be an original airport tile. */
3992 if (override >= NEW_AIRPORTTILE_OFFSET) {
3993 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
3994 continue;
3997 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
3998 break;
4001 case 0x0E: // Callback mask
4002 tsp->callback_mask = buf->ReadByte();
4003 break;
4005 case 0x0F: // Animation information
4006 tsp->animation.frames = buf->ReadByte();
4007 tsp->animation.status = buf->ReadByte();
4008 break;
4010 case 0x10: // Animation speed
4011 tsp->animation.speed = buf->ReadByte();
4012 break;
4014 case 0x11: // Animation triggers
4015 tsp->animation.triggers = buf->ReadByte();
4016 break;
4018 default:
4019 ret = CIR_UNKNOWN;
4020 break;
4024 return ret;
4027 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4029 switch (cir) {
4030 default: NOT_REACHED();
4032 case CIR_DISABLED:
4033 /* Error has already been printed; just stop parsing */
4034 return true;
4036 case CIR_SUCCESS:
4037 return false;
4039 case CIR_UNHANDLED:
4040 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4041 return false;
4043 case CIR_UNKNOWN:
4044 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4045 /* FALL THROUGH */
4047 case CIR_INVALID_ID:
4048 /* No debug message for an invalid ID, as it has already been output */
4049 DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4050 return true;
4054 /* Action 0x00 */
4055 static void FeatureChangeInfo(ByteReader *buf)
4057 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4059 * B feature
4060 * B num-props how many properties to change per vehicle/station
4061 * B num-info how many vehicles/stations to change
4062 * E id ID of first vehicle/station to change, if num-info is
4063 * greater than one, this one and the following
4064 * vehicles/stations will be changed
4065 * B property what property to change, depends on the feature
4066 * V new-info new bytes of info (variable size; depends on properties) */
4068 static const VCI_Handler handler[] = {
4069 /* GSF_TRAINS */ RailVehicleChangeInfo,
4070 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4071 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4072 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4073 /* GSF_STATIONS */ StationChangeInfo,
4074 /* GSF_CANALS */ CanalChangeInfo,
4075 /* GSF_BRIDGES */ BridgeChangeInfo,
4076 /* GSF_HOUSES */ TownHouseChangeInfo,
4077 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4078 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4079 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4080 /* GSF_CARGOS */ NULL, // Cargo is handled during reservation
4081 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4082 /* GSF_AIRPORTS */ AirportChangeInfo,
4083 /* GSF_SIGNALS */ NULL,
4084 /* GSF_OBJECTS */ ObjectChangeInfo,
4085 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4086 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4089 uint8 feature = buf->ReadByte();
4090 uint8 numprops = buf->ReadByte();
4091 uint numinfo = buf->ReadByte();
4092 uint engine = buf->ReadExtendedByte();
4094 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4095 feature, numprops, engine, numinfo);
4097 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4098 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4099 return;
4102 /* Mark the feature as used by the grf */
4103 SetBit(_cur.grffile->grf_features, feature);
4105 while (numprops-- && buf->HasData()) {
4106 uint8 prop = buf->ReadByte();
4108 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4109 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4113 /* Action 0x00 (GLS_SAFETYSCAN) */
4114 static void SafeChangeInfo(ByteReader *buf)
4116 uint8 feature = buf->ReadByte();
4117 uint8 numprops = buf->ReadByte();
4118 uint numinfo = buf->ReadByte();
4119 buf->ReadExtendedByte(); // id
4121 if (feature == GSF_BRIDGES && numprops == 1) {
4122 uint8 prop = buf->ReadByte();
4123 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4124 * is considered safe. */
4125 if (prop == 0x0D) return;
4126 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4127 uint8 prop = buf->ReadByte();
4128 /* Engine ID Mappings are safe, if the source is static */
4129 if (prop == 0x11) {
4130 bool is_safe = true;
4131 for (uint i = 0; i < numinfo; i++) {
4132 uint32 s = buf->ReadDWord();
4133 buf->ReadDWord(); // dest
4134 const GRFConfig *grfconfig = GetGRFConfig(s);
4135 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4136 is_safe = false;
4137 break;
4140 if (is_safe) return;
4144 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4146 /* Skip remainder of GRF */
4147 _cur.skip_sprites = -1;
4150 /* Action 0x00 (GLS_RESERVE) */
4151 static void ReserveChangeInfo(ByteReader *buf)
4153 uint8 feature = buf->ReadByte();
4155 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4157 uint8 numprops = buf->ReadByte();
4158 uint8 numinfo = buf->ReadByte();
4159 uint8 index = buf->ReadExtendedByte();
4161 while (numprops-- && buf->HasData()) {
4162 uint8 prop = buf->ReadByte();
4163 ChangeInfoResult cir = CIR_SUCCESS;
4165 switch (feature) {
4166 default: NOT_REACHED();
4167 case GSF_CARGOS:
4168 cir = CargoChangeInfo(index, numinfo, prop, buf);
4169 break;
4171 case GSF_GLOBALVAR:
4172 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4173 break;
4175 case GSF_RAILTYPES:
4176 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4177 break;
4180 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4184 /* Action 0x01 */
4185 static void NewSpriteSet(ByteReader *buf)
4187 /* <01> <feature> <num-sets> <num-ent>
4189 * B feature feature to define sprites for
4190 * 0, 1, 2, 3: veh-type, 4: train stations
4191 * B num-sets number of sprite sets
4192 * E num-ent how many entries per sprite set
4193 * For vehicles, this is the number of different
4194 * vehicle directions in each sprite set
4195 * Set num-dirs=8, unless your sprites are symmetric.
4196 * In that case, use num-dirs=4.
4199 uint8 feature = buf->ReadByte();
4200 uint8 num_sets = buf->ReadByte();
4201 uint16 first_set = 0;
4203 if (num_sets == 0 && buf->HasData(2)) {
4204 /* Extended Action1 format.
4205 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4206 first_set = buf->ReadExtendedByte();
4207 num_sets = buf->ReadExtendedByte();
4209 uint16 num_ents = buf->ReadExtendedByte();
4211 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4213 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4214 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4217 for (int i = 0; i < num_sets * num_ents; i++) {
4218 _cur.nfo_line++;
4219 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
4223 /* Action 0x01 (SKIP) */
4224 static void SkipAct1(ByteReader *buf)
4226 buf->ReadByte();
4227 uint8 num_sets = buf->ReadByte();
4228 uint16 num_ents = buf->ReadExtendedByte();
4230 _cur.skip_sprites = num_sets * num_ents;
4232 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4235 /* Helper function to either create a callback or link to a previously
4236 * defined spritegroup. */
4237 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4239 if (HasBit(groupid, 15)) {
4240 assert(CallbackResultSpriteGroup::CanAllocateItem());
4241 return new CallbackResultSpriteGroup(groupid);
4244 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4245 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4246 return NULL;
4249 return _cur.spritegroups[groupid];
4253 * Helper function to either create a callback or a result sprite group.
4254 * @param feature GrfSpecFeature to define spritegroup for.
4255 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4256 * @param type Type of the currently being parsed Action2. (only for debug output)
4257 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4258 * @return Created spritegroup.
4260 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4262 if (HasBit(spriteid, 15)) {
4263 assert(CallbackResultSpriteGroup::CanAllocateItem());
4264 return new CallbackResultSpriteGroup(spriteid);
4267 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4268 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4269 return NULL;
4272 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4273 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4275 /* Ensure that the sprites are loeded */
4276 assert(spriteset_start + num_sprites <= _cur.spriteid);
4278 assert(ResultSpriteGroup::CanAllocateItem());
4279 return new ResultSpriteGroup(spriteset_start, num_sprites);
4282 /* Action 0x02 */
4283 static void NewSpriteGroup(ByteReader *buf)
4285 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4287 * B feature see action 1
4288 * B set-id ID of this particular definition
4289 * B type/num-entries
4290 * if 80 or greater, this is a randomized or variational
4291 * list definition, see below
4292 * otherwise it specifies a number of entries, the exact
4293 * meaning depends on the feature
4294 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4295 SpriteGroup *act_group = NULL;
4297 uint8 feature = buf->ReadByte();
4298 uint8 setid = buf->ReadByte();
4299 uint8 type = buf->ReadByte();
4301 /* Sprite Groups are created here but they are allocated from a pool, so
4302 * we do not need to delete anything if there is an exception from the
4303 * ByteReader. */
4305 switch (type) {
4306 /* Deterministic Sprite Group */
4307 case 0x81: // Self scope, byte
4308 case 0x82: // Parent scope, byte
4309 case 0x85: // Self scope, word
4310 case 0x86: // Parent scope, word
4311 case 0x89: // Self scope, dword
4312 case 0x8A: // Parent scope, dword
4314 byte varadjust;
4315 byte varsize;
4317 assert(DeterministicSpriteGroup::CanAllocateItem());
4318 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4319 act_group = group;
4320 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4322 switch (GB(type, 2, 2)) {
4323 default: NOT_REACHED();
4324 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4325 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4326 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4329 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4330 adjusts.Clear();
4332 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4333 * from the outset, so we shall have to keep reallocing. */
4334 do {
4335 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4337 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4338 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4339 adjust->variable = buf->ReadByte();
4340 if (adjust->variable == 0x7E) {
4341 /* Link subroutine group */
4342 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4343 } else {
4344 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4347 varadjust = buf->ReadByte();
4348 adjust->shift_num = GB(varadjust, 0, 5);
4349 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4350 adjust->and_mask = buf->ReadVarSize(varsize);
4352 if (adjust->type != DSGA_TYPE_NONE) {
4353 adjust->add_val = buf->ReadVarSize(varsize);
4354 adjust->divmod_val = buf->ReadVarSize(varsize);
4355 } else {
4356 adjust->add_val = 0;
4357 adjust->divmod_val = 0;
4360 /* Continue reading var adjusts while bit 5 is set. */
4361 } while (HasBit(varadjust, 5));
4363 group->num_adjusts = adjusts.Length();
4364 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4365 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4367 group->num_ranges = buf->ReadByte();
4368 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4370 for (uint i = 0; i < group->num_ranges; i++) {
4371 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4372 group->ranges[i].low = buf->ReadVarSize(varsize);
4373 group->ranges[i].high = buf->ReadVarSize(varsize);
4376 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4377 break;
4380 /* Randomized Sprite Group */
4381 case 0x80: // Self scope
4382 case 0x83: // Parent scope
4383 case 0x84: // Relative scope
4385 assert(RandomizedSpriteGroup::CanAllocateItem());
4386 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4387 act_group = group;
4388 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4390 if (HasBit(type, 2)) {
4391 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4392 group->count = buf->ReadByte();
4395 uint8 triggers = buf->ReadByte();
4396 group->triggers = GB(triggers, 0, 7);
4397 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4398 group->lowest_randbit = buf->ReadByte();
4399 group->num_groups = buf->ReadByte();
4400 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4402 for (uint i = 0; i < group->num_groups; i++) {
4403 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4406 break;
4409 /* Neither a variable or randomized sprite group... must be a real group */
4410 default:
4412 switch (feature) {
4413 case GSF_TRAINS:
4414 case GSF_ROADVEHICLES:
4415 case GSF_SHIPS:
4416 case GSF_AIRCRAFT:
4417 case GSF_STATIONS:
4418 case GSF_CANALS:
4419 case GSF_CARGOS:
4420 case GSF_AIRPORTS:
4421 case GSF_RAILTYPES:
4423 byte num_loaded = type;
4424 byte num_loading = buf->ReadByte();
4426 if (!_cur.HasValidSpriteSets(feature)) {
4427 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4428 return;
4431 assert(RealSpriteGroup::CanAllocateItem());
4432 RealSpriteGroup *group = new RealSpriteGroup();
4433 act_group = group;
4435 group->num_loaded = num_loaded;
4436 group->num_loading = num_loading;
4437 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4438 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4440 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4441 setid, num_loaded, num_loading);
4443 for (uint i = 0; i < num_loaded; i++) {
4444 uint16 spriteid = buf->ReadWord();
4445 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4446 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4449 for (uint i = 0; i < num_loading; i++) {
4450 uint16 spriteid = buf->ReadWord();
4451 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4452 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4455 break;
4458 case GSF_HOUSES:
4459 case GSF_AIRPORTTILES:
4460 case GSF_OBJECTS:
4461 case GSF_INDUSTRYTILES: {
4462 byte num_building_sprites = max((uint8)1, type);
4464 assert(TileLayoutSpriteGroup::CanAllocateItem());
4465 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4466 act_group = group;
4468 /* On error, bail out immediately. Temporary GRF data was already freed */
4469 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4470 break;
4473 case GSF_INDUSTRIES: {
4474 if (type > 1) {
4475 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4476 break;
4479 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4480 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4481 act_group = group;
4482 group->version = type;
4483 if (type == 0) {
4484 for (uint i = 0; i < 3; i++) {
4485 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4487 for (uint i = 0; i < 2; i++) {
4488 group->add_output[i] = buf->ReadWord(); // unsigned
4490 group->again = buf->ReadByte();
4491 } else {
4492 for (uint i = 0; i < 3; i++) {
4493 group->subtract_input[i] = buf->ReadByte();
4495 for (uint i = 0; i < 2; i++) {
4496 group->add_output[i] = buf->ReadByte();
4498 group->again = buf->ReadByte();
4500 break;
4503 /* Loading of Tile Layout and Production Callback groups would happen here */
4504 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4509 _cur.spritegroups[setid] = act_group;
4512 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4514 if (feature == GSF_OBJECTS) {
4515 switch (ctype) {
4516 case 0: return 0;
4517 case 0xFF: return CT_PURCHASE_OBJECT;
4518 default:
4519 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4520 return CT_INVALID;
4523 /* Special cargo types for purchase list and stations */
4524 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4525 if (ctype == 0xFF) return CT_PURCHASE;
4527 if (_cur.grffile->cargo_max == 0) {
4528 /* No cargo table, so use bitnum values */
4529 if (ctype >= 32) {
4530 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4531 return CT_INVALID;
4534 const CargoSpec *cs;
4535 FOR_ALL_CARGOSPECS(cs) {
4536 if (cs->bitnum == ctype) {
4537 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4538 return cs->Index();
4542 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4543 return CT_INVALID;
4546 /* Check if the cargo type is out of bounds of the cargo translation table */
4547 if (ctype >= _cur.grffile->cargo_max) {
4548 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_max - 1);
4549 return CT_INVALID;
4552 /* Look up the cargo label from the translation table */
4553 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4554 if (cl == 0) {
4555 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4556 return CT_INVALID;
4559 ctype = GetCargoIDByLabel(cl);
4560 if (ctype == CT_INVALID) {
4561 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));
4562 return CT_INVALID;
4565 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);
4566 return ctype;
4570 static bool IsValidGroupID(uint16 groupid, const char *function)
4572 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4573 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4574 return false;
4577 return true;
4580 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4582 static EngineID *last_engines;
4583 static uint last_engines_count;
4584 bool wagover = false;
4586 /* Test for 'wagon override' flag */
4587 if (HasBit(idcount, 7)) {
4588 wagover = true;
4589 /* Strip off the flag */
4590 idcount = GB(idcount, 0, 7);
4592 if (last_engines_count == 0) {
4593 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4594 return;
4597 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4598 last_engines_count, idcount);
4599 } else {
4600 if (last_engines_count != idcount) {
4601 last_engines = ReallocT(last_engines, idcount);
4602 last_engines_count = idcount;
4606 EngineID *engines = AllocaM(EngineID, idcount);
4607 for (uint i = 0; i < idcount; i++) {
4608 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4609 if (e == NULL) {
4610 /* No engine could be allocated?!? Deal with it. Okay,
4611 * this might look bad. Also make sure this NewGRF
4612 * gets disabled, as a half loaded one is bad. */
4613 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4614 return;
4617 engines[i] = e->index;
4618 if (!wagover) last_engines[i] = engines[i];
4621 uint8 cidcount = buf->ReadByte();
4622 for (uint c = 0; c < cidcount; c++) {
4623 uint8 ctype = buf->ReadByte();
4624 uint16 groupid = buf->ReadWord();
4625 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4627 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4629 ctype = TranslateCargo(feature, ctype);
4630 if (ctype == CT_INVALID) continue;
4632 for (uint i = 0; i < idcount; i++) {
4633 EngineID engine = engines[i];
4635 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4637 if (wagover) {
4638 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4639 } else {
4640 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4645 uint16 groupid = buf->ReadWord();
4646 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
4648 grfmsg(8, "-- Default group id 0x%04X", groupid);
4650 for (uint i = 0; i < idcount; i++) {
4651 EngineID engine = engines[i];
4653 if (wagover) {
4654 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4655 } else {
4656 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4657 SetEngineGRF(engine, _cur.grffile);
4663 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4665 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
4666 for (uint i = 0; i < idcount; i++) {
4667 cfs[i] = (CanalFeature)buf->ReadByte();
4670 uint8 cidcount = buf->ReadByte();
4671 buf->Skip(cidcount * 3);
4673 uint16 groupid = buf->ReadWord();
4674 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
4676 for (uint i = 0; i < idcount; i++) {
4677 CanalFeature cf = cfs[i];
4679 if (cf >= CF_END) {
4680 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
4681 continue;
4684 _water_feature[cf].grffile = _cur.grffile;
4685 _water_feature[cf].group = _cur.spritegroups[groupid];
4690 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
4692 uint8 *stations = AllocaM(uint8, idcount);
4693 for (uint i = 0; i < idcount; i++) {
4694 stations[i] = buf->ReadByte();
4697 uint8 cidcount = buf->ReadByte();
4698 for (uint c = 0; c < cidcount; c++) {
4699 uint8 ctype = buf->ReadByte();
4700 uint16 groupid = buf->ReadWord();
4701 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
4703 ctype = TranslateCargo(GSF_STATIONS, ctype);
4704 if (ctype == CT_INVALID) continue;
4706 for (uint i = 0; i < idcount; i++) {
4707 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
4709 if (statspec == NULL) {
4710 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
4711 continue;
4714 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
4718 uint16 groupid = buf->ReadWord();
4719 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
4721 for (uint i = 0; i < idcount; i++) {
4722 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
4724 if (statspec == NULL) {
4725 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
4726 continue;
4729 if (statspec->grf_prop.grffile != NULL) {
4730 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
4731 continue;
4734 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
4735 statspec->grf_prop.grffile = _cur.grffile;
4736 statspec->grf_prop.local_id = stations[i];
4737 StationClass::Assign(statspec);
4742 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
4744 uint8 *houses = AllocaM(uint8, idcount);
4745 for (uint i = 0; i < idcount; i++) {
4746 houses[i] = buf->ReadByte();
4749 /* Skip the cargo type section, we only care about the default group */
4750 uint8 cidcount = buf->ReadByte();
4751 buf->Skip(cidcount * 3);
4753 uint16 groupid = buf->ReadWord();
4754 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
4756 if (_cur.grffile->housespec == NULL) {
4757 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
4758 return;
4761 for (uint i = 0; i < idcount; i++) {
4762 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
4764 if (hs == NULL) {
4765 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
4766 continue;
4769 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
4773 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
4775 uint8 *industries = AllocaM(uint8, idcount);
4776 for (uint i = 0; i < idcount; i++) {
4777 industries[i] = buf->ReadByte();
4780 /* Skip the cargo type section, we only care about the default group */
4781 uint8 cidcount = buf->ReadByte();
4782 buf->Skip(cidcount * 3);
4784 uint16 groupid = buf->ReadWord();
4785 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
4787 if (_cur.grffile->industryspec == NULL) {
4788 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
4789 return;
4792 for (uint i = 0; i < idcount; i++) {
4793 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
4795 if (indsp == NULL) {
4796 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
4797 continue;
4800 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
4804 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
4806 uint8 *indtiles = AllocaM(uint8, idcount);
4807 for (uint i = 0; i < idcount; i++) {
4808 indtiles[i] = buf->ReadByte();
4811 /* Skip the cargo type section, we only care about the default group */
4812 uint8 cidcount = buf->ReadByte();
4813 buf->Skip(cidcount * 3);
4815 uint16 groupid = buf->ReadWord();
4816 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
4818 if (_cur.grffile->indtspec == NULL) {
4819 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
4820 return;
4823 for (uint i = 0; i < idcount; i++) {
4824 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
4826 if (indtsp == NULL) {
4827 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
4828 continue;
4831 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
4835 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
4837 CargoID *cargos = AllocaM(CargoID, idcount);
4838 for (uint i = 0; i < idcount; i++) {
4839 cargos[i] = buf->ReadByte();
4842 /* Skip the cargo type section, we only care about the default group */
4843 uint8 cidcount = buf->ReadByte();
4844 buf->Skip(cidcount * 3);
4846 uint16 groupid = buf->ReadWord();
4847 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
4849 for (uint i = 0; i < idcount; i++) {
4850 CargoID cid = cargos[i];
4852 if (cid >= NUM_CARGO) {
4853 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
4854 continue;
4857 CargoSpec *cs = CargoSpec::Get(cid);
4858 cs->grffile = _cur.grffile;
4859 cs->group = _cur.spritegroups[groupid];
4863 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
4865 if (_cur.grffile->objectspec == NULL) {
4866 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
4867 return;
4870 uint8 *objects = AllocaM(uint8, idcount);
4871 for (uint i = 0; i < idcount; i++) {
4872 objects[i] = buf->ReadByte();
4875 uint8 cidcount = buf->ReadByte();
4876 for (uint c = 0; c < cidcount; c++) {
4877 uint8 ctype = buf->ReadByte();
4878 uint16 groupid = buf->ReadWord();
4879 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
4881 ctype = TranslateCargo(GSF_OBJECTS, ctype);
4882 if (ctype == CT_INVALID) continue;
4884 for (uint i = 0; i < idcount; i++) {
4885 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
4887 if (spec == NULL) {
4888 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
4889 continue;
4892 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
4896 uint16 groupid = buf->ReadWord();
4897 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
4899 for (uint i = 0; i < idcount; i++) {
4900 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
4902 if (spec == NULL) {
4903 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
4904 continue;
4907 if (spec->grf_prop.grffile != NULL) {
4908 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
4909 continue;
4912 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
4913 spec->grf_prop.grffile = _cur.grffile;
4914 spec->grf_prop.local_id = objects[i];
4918 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
4920 uint8 *railtypes = AllocaM(uint8, idcount);
4921 for (uint i = 0; i < idcount; i++) {
4922 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
4925 uint8 cidcount = buf->ReadByte();
4926 for (uint c = 0; c < cidcount; c++) {
4927 uint8 ctype = buf->ReadByte();
4928 uint16 groupid = buf->ReadWord();
4929 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
4931 if (ctype >= RTSG_END) continue;
4933 extern RailtypeInfo _railtypes[RAILTYPE_END];
4934 for (uint i = 0; i < idcount; i++) {
4935 if (railtypes[i] != INVALID_RAILTYPE) {
4936 RailtypeInfo *rti = &_railtypes[railtypes[i]];
4938 rti->grffile[ctype] = _cur.grffile;
4939 rti->group[ctype] = _cur.spritegroups[groupid];
4944 /* Railtypes do not use the default group. */
4945 buf->ReadWord();
4948 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
4950 uint8 *airports = AllocaM(uint8, idcount);
4951 for (uint i = 0; i < idcount; i++) {
4952 airports[i] = buf->ReadByte();
4955 /* Skip the cargo type section, we only care about the default group */
4956 uint8 cidcount = buf->ReadByte();
4957 buf->Skip(cidcount * 3);
4959 uint16 groupid = buf->ReadWord();
4960 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
4962 if (_cur.grffile->airportspec == NULL) {
4963 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
4964 return;
4967 for (uint i = 0; i < idcount; i++) {
4968 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
4970 if (as == NULL) {
4971 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
4972 continue;
4975 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
4979 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
4981 uint8 *airptiles = AllocaM(uint8, idcount);
4982 for (uint i = 0; i < idcount; i++) {
4983 airptiles[i] = buf->ReadByte();
4986 /* Skip the cargo type section, we only care about the default group */
4987 uint8 cidcount = buf->ReadByte();
4988 buf->Skip(cidcount * 3);
4990 uint16 groupid = buf->ReadWord();
4991 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
4993 if (_cur.grffile->airtspec == NULL) {
4994 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
4995 return;
4998 for (uint i = 0; i < idcount; i++) {
4999 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5001 if (airtsp == NULL) {
5002 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5003 continue;
5006 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5011 /* Action 0x03 */
5012 static void FeatureMapSpriteGroup(ByteReader *buf)
5014 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5015 * id-list := [<id>] [id-list]
5016 * cargo-list := <cargo-type> <cid> [cargo-list]
5018 * B feature see action 0
5019 * B n-id bits 0-6: how many IDs this definition applies to
5020 * bit 7: if set, this is a wagon override definition (see below)
5021 * B ids the IDs for which this definition applies
5022 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5023 * can be zero, in that case the def-cid is used always
5024 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5025 * W cid cargo ID (sprite group ID) for this type of cargo
5026 * W def-cid default cargo ID (sprite group ID) */
5028 uint8 feature = buf->ReadByte();
5029 uint8 idcount = buf->ReadByte();
5031 /* If idcount is zero, this is a feature callback */
5032 if (idcount == 0) {
5033 /* Skip number of cargo ids? */
5034 buf->ReadByte();
5035 uint16 groupid = buf->ReadWord();
5036 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5038 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5040 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5041 return;
5044 /* Mark the feature as used by the grf (generic callbacks do not count) */
5045 SetBit(_cur.grffile->grf_features, feature);
5047 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5049 switch (feature) {
5050 case GSF_TRAINS:
5051 case GSF_ROADVEHICLES:
5052 case GSF_SHIPS:
5053 case GSF_AIRCRAFT:
5054 VehicleMapSpriteGroup(buf, feature, idcount);
5055 return;
5057 case GSF_CANALS:
5058 CanalMapSpriteGroup(buf, idcount);
5059 return;
5061 case GSF_STATIONS:
5062 StationMapSpriteGroup(buf, idcount);
5063 return;
5065 case GSF_HOUSES:
5066 TownHouseMapSpriteGroup(buf, idcount);
5067 return;
5069 case GSF_INDUSTRIES:
5070 IndustryMapSpriteGroup(buf, idcount);
5071 return;
5073 case GSF_INDUSTRYTILES:
5074 IndustrytileMapSpriteGroup(buf, idcount);
5075 return;
5077 case GSF_CARGOS:
5078 CargoMapSpriteGroup(buf, idcount);
5079 return;
5081 case GSF_AIRPORTS:
5082 AirportMapSpriteGroup(buf, idcount);
5083 return;
5085 case GSF_OBJECTS:
5086 ObjectMapSpriteGroup(buf, idcount);
5087 break;
5089 case GSF_RAILTYPES:
5090 RailTypeMapSpriteGroup(buf, idcount);
5091 break;
5093 case GSF_AIRPORTTILES:
5094 AirportTileMapSpriteGroup(buf, idcount);
5095 return;
5097 default:
5098 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5099 return;
5103 /* Action 0x04 */
5104 static void FeatureNewName(ByteReader *buf)
5106 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5108 * B veh-type see action 0 (as 00..07, + 0A
5109 * But IF veh-type = 48, then generic text
5110 * B language-id If bit 6 is set, This is the extended language scheme,
5111 * with up to 64 language.
5112 * Otherwise, it is a mapping where set bits have meaning
5113 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5114 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5115 * B num-veh number of vehicles which are getting a new name
5116 * B/W offset number of the first vehicle that gets a new name
5117 * Byte : ID of vehicle to change
5118 * Word : ID of string to change/add
5119 * S data new texts, each of them zero-terminated, after
5120 * which the next name begins. */
5122 bool new_scheme = _cur.grffile->grf_version >= 7;
5124 uint8 feature = buf->ReadByte();
5125 uint8 lang = buf->ReadByte();
5126 uint8 num = buf->ReadByte();
5127 bool generic = HasBit(lang, 7);
5128 uint16 id;
5129 if (generic) {
5130 id = buf->ReadWord();
5131 } else if (feature <= GSF_AIRCRAFT) {
5132 id = buf->ReadExtendedByte();
5133 } else {
5134 id = buf->ReadByte();
5137 ClrBit(lang, 7);
5139 uint16 endid = id + num;
5141 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5142 id, endid, feature, lang);
5144 for (; id < endid && buf->HasData(); id++) {
5145 const char *name = buf->ReadString();
5146 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5148 switch (feature) {
5149 case GSF_TRAINS:
5150 case GSF_ROADVEHICLES:
5151 case GSF_SHIPS:
5152 case GSF_AIRCRAFT:
5153 if (!generic) {
5154 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5155 if (e == NULL) break;
5156 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, false, new_scheme, name, e->info.string_id);
5157 e->info.string_id = string;
5158 } else {
5159 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5161 break;
5163 case GSF_INDUSTRIES: {
5164 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5165 break;
5168 case GSF_HOUSES:
5169 default:
5170 switch (GB(id, 8, 8)) {
5171 case 0xC4: // Station class name
5172 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5173 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5174 } else {
5175 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5176 StationClass::SetName(cls_id, AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED));
5178 break;
5180 case 0xC5: // Station name
5181 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5182 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5183 } else {
5184 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5186 break;
5188 case 0xC7: // Airporttile name
5189 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5190 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5191 } else {
5192 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5194 break;
5196 case 0xC9: // House name
5197 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5198 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5199 } else {
5200 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5202 break;
5204 case 0xD0:
5205 case 0xD1:
5206 case 0xD2:
5207 case 0xD3:
5208 case 0xDC:
5209 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5210 break;
5212 default:
5213 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5214 break;
5216 break;
5222 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5223 * @param num The number of sprites to load.
5224 * @param offset Offset from the base.
5225 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5226 * @param name Used for error warnings.
5227 * @return The number of sprites that is going to be skipped.
5229 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5232 if (offset >= max_sprites) {
5233 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5234 uint orig_num = num;
5235 num = 0;
5236 return orig_num;
5239 if (offset + num > max_sprites) {
5240 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5241 uint orig_num = num;
5242 num = max(max_sprites - offset, 0);
5243 return orig_num - num;
5246 return 0;
5250 /** The type of action 5 type. */
5251 enum Action5BlockType {
5252 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5253 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5254 A5BLOCK_INVALID, ///< unknown/not-implemented type
5256 /** Information about a single action 5 type. */
5257 struct Action5Type {
5258 Action5BlockType block_type; ///< How is this Action5 type processed?
5259 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5260 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5261 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5262 const char *name; ///< Name for error messages.
5265 /** The information about action 5 types. */
5266 static const Action5Type _action5_types[] = {
5267 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5268 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5269 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5270 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5271 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5272 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5273 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
5274 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5275 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5276 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5277 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5278 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5279 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5280 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5281 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5282 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5283 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5284 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5285 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5286 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5287 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5288 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5289 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5290 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5293 /* Action 0x05 */
5294 static void GraphicsNew(ByteReader *buf)
5296 /* <05> <graphics-type> <num-sprites> <other data...>
5298 * B graphics-type What set of graphics the sprites define.
5299 * E num-sprites How many sprites are in this set?
5300 * V other data Graphics type specific data. Currently unused. */
5301 /* TODO */
5303 uint8 type = buf->ReadByte();
5304 uint16 num = buf->ReadExtendedByte();
5305 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5306 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5308 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
5309 /* Special not-TTDP-compatible case used in openttd.grf
5310 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5311 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5312 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++); // SLOPE_STEEP_S
5313 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++); // SLOPE_STEEP_W
5314 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++); // SLOPE_WSE
5315 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++); // SLOPE_STEEP_N
5316 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++); // SLOPE_NWS
5317 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++); // SLOPE_ENW
5318 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++); // SLOPE_SEN
5319 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++); // SLOPE_STEEP_E
5320 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++); // SLOPE_EW
5321 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++); // SLOPE_NS
5322 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5323 return;
5326 /* Supported type? */
5327 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5328 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5329 _cur.skip_sprites = num;
5330 return;
5333 const Action5Type *action5_type = &_action5_types[type];
5335 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5336 * except for the long version of the shore type:
5337 * Ignore offset if not allowed */
5338 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5339 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5340 offset = 0;
5343 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5344 * This does not make sense, if <offset> is allowed */
5345 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5346 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);
5347 _cur.skip_sprites = num;
5348 return;
5351 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5352 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5353 SpriteID replace = action5_type->sprite_base + offset;
5355 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5356 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);
5358 for (; num > 0; num--) {
5359 _cur.nfo_line++;
5360 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line);
5363 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5365 _cur.skip_sprites = skip_num;
5368 /* Action 0x05 (SKIP) */
5369 static void SkipAct5(ByteReader *buf)
5371 /* Ignore type byte */
5372 buf->ReadByte();
5374 /* Skip the sprites of this action */
5375 _cur.skip_sprites = buf->ReadExtendedByte();
5377 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5381 * Check whether we are (obviously) missing some of the extra
5382 * (Action 0x05) sprites that we like to use.
5383 * When missing sprites are found a warning will be shown.
5385 void CheckForMissingSprites()
5387 /* Don't break out quickly, but allow to check the other
5388 * sprites as well, so we can give the best information. */
5389 bool missing = false;
5390 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
5391 const Action5Type *type = &_action5_types[i];
5392 if (type->block_type == A5BLOCK_INVALID) continue;
5394 for (uint j = 0; j < type->max_sprites; j++) {
5395 if (!SpriteExists(type->sprite_base + j)) {
5396 DEBUG(grf, 0, "%s sprites are missing", type->name);
5397 missing = true;
5398 /* No need to log more of the same. */
5399 break;
5404 if (missing) {
5405 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
5410 * Reads a variable common to VarAction2 and Action7/9/D.
5412 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5413 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5415 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5416 * @param value returns the value of the variable.
5417 * @return true iff the variable is known and the value is returned in 'value'.
5419 bool GetGlobalVariable(byte param, uint32 *value)
5421 switch (param) {
5422 case 0x00: // current date
5423 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5424 return true;
5426 case 0x01: // current year
5427 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5428 return true;
5430 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)
5431 YearMonthDay ymd;
5432 ConvertDateToYMD(_date, &ymd);
5433 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5434 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5435 return true;
5438 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5439 *value = _settings_game.game_creation.landscape;
5440 return true;
5442 case 0x06: // road traffic side, bit 4 clear=left, set=right
5443 *value = _settings_game.vehicle.road_side << 4;
5444 return true;
5446 case 0x09: // date fraction
5447 *value = _date_fract * 885;
5448 return true;
5450 case 0x0A: // animation counter
5451 *value = _tick_counter;
5452 return true;
5454 case 0x0B: { // TTDPatch version
5455 uint major = 2;
5456 uint minor = 6;
5457 uint revision = 1; // special case: 2.0.1 is 2.0.10
5458 uint build = 1382;
5459 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5460 return true;
5463 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5464 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5465 return true;
5467 case 0x0E: // Y-offset for train sprites
5468 *value = _cur.grffile->traininfo_vehicle_pitch;
5469 return true;
5471 case 0x0F: // Rail track type cost factors
5472 *value = 0;
5473 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5474 if (_settings_game.vehicle.disable_elrails) {
5475 /* skip elrail multiplier - disabled */
5476 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5477 } else {
5478 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5479 /* Skip monorail multiplier - no space in result */
5481 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5482 return true;
5484 case 0x11: // current rail tool type
5485 *value = 0; // constant fake value to avoid desync
5486 return true;
5488 case 0x12: // Game mode
5489 *value = _game_mode;
5490 return true;
5492 /* case 0x13: // Tile refresh offset to left not implemented */
5493 /* case 0x14: // Tile refresh offset to right not implemented */
5494 /* case 0x15: // Tile refresh offset upwards not implemented */
5495 /* case 0x16: // Tile refresh offset downwards not implemented */
5496 /* case 0x17: // temperate snow line not implemented */
5498 case 0x1A: // Always -1
5499 *value = UINT_MAX;
5500 return true;
5502 case 0x1B: // Display options
5503 *value = 0x3F; // constant fake value to avoid desync
5504 return true;
5506 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5507 *value = 1;
5508 return true;
5510 case 0x1E: // Miscellaneous GRF features
5511 *value = _misc_grf_features;
5513 /* Add the local flags */
5514 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5515 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5516 return true;
5518 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5520 case 0x20: // snow line height
5521 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
5522 return true;
5524 case 0x21: // OpenTTD version
5525 *value = _openttd_newgrf_version;
5526 return true;
5528 case 0x22: // difficulty level
5529 *value = _settings_game.difficulty.diff_level;
5530 return true;
5532 case 0x23: // long format date
5533 *value = _date;
5534 return true;
5536 case 0x24: // long format year
5537 *value = _cur_year;
5538 return true;
5540 default: return false;
5544 static uint32 GetParamVal(byte param, uint32 *cond_val)
5546 /* First handle variable common with VarAction2 */
5547 uint32 value;
5548 if (GetGlobalVariable(param - 0x80, &value)) return value;
5550 /* Non-common variable */
5551 switch (param) {
5552 case 0x84: { // GRF loading stage
5553 uint32 res = 0;
5555 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5556 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5557 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5558 return res;
5561 case 0x85: // TTDPatch flags, only for bit tests
5562 if (cond_val == NULL) {
5563 /* Supported in Action 0x07 and 0x09, not 0x0D */
5564 return 0;
5565 } else {
5566 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5567 *cond_val %= 0x20;
5568 return param_val;
5571 case 0x88: // GRF ID check
5572 return 0;
5574 /* case 0x99: Global ID offest not implemented */
5576 default:
5577 /* GRF Parameter */
5578 if (param < 0x80) return _cur.grffile->GetParam(param);
5580 /* In-game variable. */
5581 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5582 return UINT_MAX;
5586 /* Action 0x06 */
5587 static void CfgApply(ByteReader *buf)
5589 /* <06> <param-num> <param-size> <offset> ... <FF>
5591 * B param-num Number of parameter to substitute (First = "zero")
5592 * Ignored if that parameter was not specified in newgrf.cfg
5593 * B param-size How many bytes to replace. If larger than 4, the
5594 * bytes of the following parameter are used. In that
5595 * case, nothing is applied unless *all* parameters
5596 * were specified.
5597 * B offset Offset into data from beginning of next sprite
5598 * to place where parameter is to be stored. */
5600 /* Preload the next sprite */
5601 size_t pos = FioGetPos();
5602 uint16 num = FioReadWord();
5603 uint8 type = FioReadByte();
5604 byte *preload_sprite = NULL;
5606 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5607 if (type == 0xFF) {
5608 preload_sprite = MallocT<byte>(num);
5609 FioReadBlock(preload_sprite, num);
5612 /* Reset the file position to the start of the next sprite */
5613 FioSeekTo(pos, SEEK_SET);
5615 if (type != 0xFF) {
5616 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5617 free(preload_sprite);
5618 return;
5621 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5622 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5623 if (it != _grf_line_to_action6_sprite_override.end()) {
5624 free(preload_sprite);
5625 preload_sprite = _grf_line_to_action6_sprite_override[location];
5626 } else {
5627 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5630 /* Now perform the Action 0x06 on our data. */
5632 for (;;) {
5633 uint i;
5634 uint param_num;
5635 uint param_size;
5636 uint offset;
5637 bool add_value;
5639 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5640 param_num = buf->ReadByte();
5641 if (param_num == 0xFF) break;
5643 /* Get the size of the parameter to use. If the size covers multiple
5644 * double words, sequential parameter values are used. */
5645 param_size = buf->ReadByte();
5647 /* Bit 7 of param_size indicates we should add to the original value
5648 * instead of replacing it. */
5649 add_value = HasBit(param_size, 7);
5650 param_size = GB(param_size, 0, 7);
5652 /* Where to apply the data to within the pseudo sprite data. */
5653 offset = buf->ReadExtendedByte();
5655 /* If the parameter is a GRF parameter (not an internal variable) check
5656 * if it (and all further sequential parameters) has been defined. */
5657 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5658 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5659 break;
5662 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5664 bool carry = false;
5665 for (i = 0; i < param_size && offset + i < num; i++) {
5666 uint32 value = GetParamVal(param_num + i / 4, NULL);
5667 /* Reset carry flag for each iteration of the variable (only really
5668 * matters if param_size is greater than 4) */
5669 if (i % 4 == 0) carry = false;
5671 if (add_value) {
5672 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5673 preload_sprite[offset + i] = GB(new_value, 0, 8);
5674 /* Check if the addition overflowed */
5675 carry = new_value >= 256;
5676 } else {
5677 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
5684 * Disable a static NewGRF when it is influencing another (non-static)
5685 * NewGRF as this could cause desyncs.
5687 * We could just tell the NewGRF querying that the file doesn't exist,
5688 * but that might give unwanted results. Disabling the NewGRF gives the
5689 * best result as no NewGRF author can complain about that.
5690 * @param c The NewGRF to disable.
5692 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
5694 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
5695 error->data = strdup(_cur.grfconfig->GetName());
5698 /* Action 0x07
5699 * Action 0x09 */
5700 static void SkipIf(ByteReader *buf)
5702 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
5704 * B param-num
5705 * B param-size
5706 * B condition-type
5707 * V value
5708 * B num-sprites */
5709 /* TODO: More params. More condition types. */
5710 uint32 cond_val = 0;
5711 uint32 mask = 0;
5712 bool result;
5714 uint8 param = buf->ReadByte();
5715 uint8 paramsize = buf->ReadByte();
5716 uint8 condtype = buf->ReadByte();
5718 if (condtype < 2) {
5719 /* Always 1 for bit tests, the given value should be ignored. */
5720 paramsize = 1;
5723 switch (paramsize) {
5724 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
5725 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
5726 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
5727 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
5728 default: break;
5731 if (param < 0x80 && _cur.grffile->param_end <= param) {
5732 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
5733 return;
5736 uint32 param_val = GetParamVal(param, &cond_val);
5738 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
5741 * Parameter (variable in specs) 0x88 can only have GRF ID checking
5742 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
5743 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
5744 * So, when the condition type is one of those, the specific variable
5745 * 0x88 code is skipped, so the "general" code for the cargo
5746 * availability conditions kicks in.
5748 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
5749 /* GRF ID checks */
5751 GRFConfig *c = GetGRFConfig(cond_val, mask);
5753 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
5754 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
5755 c = NULL;
5758 if (condtype != 10 && c == NULL) {
5759 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
5760 return;
5763 switch (condtype) {
5764 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
5765 case 0x06: // Is GRFID active?
5766 result = c->status == GCS_ACTIVATED;
5767 break;
5769 case 0x07: // Is GRFID non-active?
5770 result = c->status != GCS_ACTIVATED;
5771 break;
5773 case 0x08: // GRFID is not but will be active?
5774 result = c->status == GCS_INITIALISED;
5775 break;
5777 case 0x09: // GRFID is or will be active?
5778 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
5779 break;
5781 case 0x0A: // GRFID is not nor will be active
5782 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
5783 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
5784 break;
5786 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
5788 } else {
5789 /* Parameter or variable tests */
5790 switch (condtype) {
5791 case 0x00: result = !!(param_val & (1 << cond_val));
5792 break;
5793 case 0x01: result = !(param_val & (1 << cond_val));
5794 break;
5795 case 0x02: result = (param_val & mask) == cond_val;
5796 break;
5797 case 0x03: result = (param_val & mask) != cond_val;
5798 break;
5799 case 0x04: result = (param_val & mask) < cond_val;
5800 break;
5801 case 0x05: result = (param_val & mask) > cond_val;
5802 break;
5803 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
5804 break;
5805 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
5806 break;
5807 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
5808 break;
5809 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
5810 break;
5812 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
5816 if (!result) {
5817 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
5818 return;
5821 uint8 numsprites = buf->ReadByte();
5823 /* numsprites can be a GOTO label if it has been defined in the GRF
5824 * file. The jump will always be the first matching label that follows
5825 * the current nfo_line. If no matching label is found, the first matching
5826 * label in the file is used. */
5827 GRFLabel *choice = NULL;
5828 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
5829 if (label->label != numsprites) continue;
5831 /* Remember a goto before the current line */
5832 if (choice == NULL) choice = label;
5833 /* If we find a label here, this is definitely good */
5834 if (label->nfo_line > _cur.nfo_line) {
5835 choice = label;
5836 break;
5840 if (choice != NULL) {
5841 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
5842 FioSeekTo(choice->pos, SEEK_SET);
5843 _cur.nfo_line = choice->nfo_line;
5844 return;
5847 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
5848 _cur.skip_sprites = numsprites;
5849 if (_cur.skip_sprites == 0) {
5850 /* Zero means there are no sprites to skip, so
5851 * we use -1 to indicate that all further
5852 * sprites should be skipped. */
5853 _cur.skip_sprites = -1;
5855 /* If an action 8 hasn't been encountered yet, disable the grf. */
5856 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
5857 DisableGrf();
5863 /* Action 0x08 (GLS_FILESCAN) */
5864 static void ScanInfo(ByteReader *buf)
5866 uint8 grf_version = buf->ReadByte();
5867 uint32 grfid = buf->ReadDWord();
5868 const char *name = buf->ReadString();
5870 _cur.grfconfig->ident.grfid = grfid;
5872 if (grf_version < 2 || grf_version > 7) {
5873 SetBit(_cur.grfconfig->flags, GCF_INVALID);
5874 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);
5877 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
5878 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
5880 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
5882 if (buf->HasData()) {
5883 const char *info = buf->ReadString();
5884 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
5887 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
5888 _cur.skip_sprites = -1;
5891 /* Action 0x08 */
5892 static void GRFInfo(ByteReader *buf)
5894 /* <08> <version> <grf-id> <name> <info>
5896 * B version newgrf version, currently 06
5897 * 4*B grf-id globally unique ID of this .grf file
5898 * S name name of this .grf set
5899 * S info string describing the set, and e.g. author and copyright */
5901 uint8 version = buf->ReadByte();
5902 uint32 grfid = buf->ReadDWord();
5903 const char *name = buf->ReadString();
5905 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
5906 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
5907 return;
5910 if (_cur.grffile->grfid != grfid) {
5911 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));
5912 _cur.grffile->grfid = grfid;
5915 _cur.grffile->grf_version = version;
5916 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
5918 /* Do swap the GRFID for displaying purposes since people expect that */
5919 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);
5922 /* Action 0x0A */
5923 static void SpriteReplace(ByteReader *buf)
5925 /* <0A> <num-sets> <set1> [<set2> ...]
5926 * <set>: <num-sprites> <first-sprite>
5928 * B num-sets How many sets of sprites to replace.
5929 * Each set:
5930 * B num-sprites How many sprites are in this set
5931 * W first-sprite First sprite number to replace */
5933 uint8 num_sets = buf->ReadByte();
5935 for (uint i = 0; i < num_sets; i++) {
5936 uint8 num_sprites = buf->ReadByte();
5937 uint16 first_sprite = buf->ReadWord();
5939 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
5940 i, num_sprites, first_sprite
5943 for (uint j = 0; j < num_sprites; j++) {
5944 int load_index = first_sprite + j;
5945 _cur.nfo_line++;
5946 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line); // XXX
5948 /* Shore sprites now located at different addresses.
5949 * So detect when the old ones get replaced. */
5950 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
5951 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
5957 /* Action 0x0A (SKIP) */
5958 static void SkipActA(ByteReader *buf)
5960 uint8 num_sets = buf->ReadByte();
5962 for (uint i = 0; i < num_sets; i++) {
5963 /* Skip the sprites this replaces */
5964 _cur.skip_sprites += buf->ReadByte();
5965 /* But ignore where they go */
5966 buf->ReadWord();
5969 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
5972 /* Action 0x0B */
5973 static void GRFLoadError(ByteReader *buf)
5975 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
5977 * B severity 00: notice, contine loading grf file
5978 * 01: warning, continue loading grf file
5979 * 02: error, but continue loading grf file, and attempt
5980 * loading grf again when loading or starting next game
5981 * 03: error, abort loading and prevent loading again in
5982 * the future (only when restarting the patch)
5983 * B language-id see action 4, use 1F for built-in error messages
5984 * B message-id message to show, see below
5985 * S message for custom messages (message-id FF), text of the message
5986 * not present for built-in messages.
5987 * V data additional data for built-in (or custom) messages
5988 * B parnum parameter numbers to be shown in the message (maximum of 2) */
5990 static const StringID msgstr[] = {
5991 STR_NEWGRF_ERROR_VERSION_NUMBER,
5992 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
5993 STR_NEWGRF_ERROR_UNSET_SWITCH,
5994 STR_NEWGRF_ERROR_INVALID_PARAMETER,
5995 STR_NEWGRF_ERROR_LOAD_BEFORE,
5996 STR_NEWGRF_ERROR_LOAD_AFTER,
5997 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6000 static const StringID sevstr[] = {
6001 STR_NEWGRF_ERROR_MSG_INFO,
6002 STR_NEWGRF_ERROR_MSG_WARNING,
6003 STR_NEWGRF_ERROR_MSG_ERROR,
6004 STR_NEWGRF_ERROR_MSG_FATAL
6007 /* For now we can only show one message per newgrf file. */
6008 if (_cur.grfconfig->error != NULL) return;
6010 byte severity = buf->ReadByte();
6011 byte lang = buf->ReadByte();
6012 byte message_id = buf->ReadByte();
6014 /* Skip the error if it isn't valid for the current language. */
6015 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6017 /* Skip the error until the activation stage unless bit 7 of the severity
6018 * is set. */
6019 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6020 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6021 return;
6023 ClrBit(severity, 7);
6025 if (severity >= lengthof(sevstr)) {
6026 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6027 severity = 2;
6028 } else if (severity == 3) {
6029 /* This is a fatal error, so make sure the GRF is deactivated and no
6030 * more of it gets loaded. */
6031 DisableGrf();
6034 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6035 grfmsg(7, "GRFLoadError: Invalid message id.");
6036 return;
6039 if (buf->Remaining() <= 1) {
6040 grfmsg(7, "GRFLoadError: No message data supplied.");
6041 return;
6044 GRFError *error = new GRFError(sevstr[severity]);
6046 if (message_id == 0xFF) {
6047 /* This is a custom error message. */
6048 if (buf->HasData()) {
6049 const char *message = buf->ReadString();
6051 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message);
6052 } else {
6053 grfmsg(7, "GRFLoadError: No custom message supplied.");
6054 error->custom_message = strdup("");
6056 } else {
6057 error->message = msgstr[message_id];
6060 if (buf->HasData()) {
6061 const char *data = buf->ReadString();
6063 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6064 } else {
6065 grfmsg(7, "GRFLoadError: No message data supplied.");
6066 error->data = strdup("");
6069 /* Only two parameter numbers can be used in the string. */
6070 uint i = 0;
6071 for (; i < 2 && buf->HasData(); i++) {
6072 uint param_number = buf->ReadByte();
6073 error->param_value[i] = _cur.grffile->GetParam(param_number);
6075 error->num_params = i;
6077 _cur.grfconfig->error = error;
6080 /* Action 0x0C */
6081 static void GRFComment(ByteReader *buf)
6083 /* <0C> [<ignored...>]
6085 * V ignored Anything following the 0C is ignored */
6087 if (!buf->HasData()) return;
6089 const char *text = buf->ReadString();
6090 grfmsg(2, "GRFComment: %s", text);
6093 /* Action 0x0D (GLS_SAFETYSCAN) */
6094 static void SafeParamSet(ByteReader *buf)
6096 uint8 target = buf->ReadByte();
6098 /* Only writing GRF parameters is considered safe */
6099 if (target < 0x80) return;
6101 /* GRM could be unsafe, but as here it can only happen after other GRFs
6102 * are loaded, it should be okay. If the GRF tried to use the slots it
6103 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6104 * sprites is considered safe. */
6106 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6108 /* Skip remainder of GRF */
6109 _cur.skip_sprites = -1;
6113 static uint32 GetPatchVariable(uint8 param)
6115 switch (param) {
6116 /* start year - 1920 */
6117 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6119 /* freight trains weight factor */
6120 case 0x0E: return _settings_game.vehicle.freight_trains;
6122 /* empty wagon speed increase */
6123 case 0x0F: return 0;
6125 /* plane speed factor; our patch option is reversed from TTDPatch's,
6126 * the following is good for 1x, 2x and 4x (most common?) and...
6127 * well not really for 3x. */
6128 case 0x10:
6129 switch (_settings_game.vehicle.plane_speed) {
6130 default:
6131 case 4: return 1;
6132 case 3: return 2;
6133 case 2: return 2;
6134 case 1: return 4;
6138 /* 2CC colourmap base sprite */
6139 case 0x11: return SPR_2CCMAP_BASE;
6141 /* map size: format = -MABXYSS
6142 * M : the type of map
6143 * bit 0 : set : squared map. Bit 1 is now not relevant
6144 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6145 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6146 * clear : X is the bigger edge.
6147 * A : minimum edge(log2) of the map
6148 * B : maximum edge(log2) of the map
6149 * XY : edges(log2) of each side of the map.
6150 * SS : combination of both X and Y, thus giving the size(log2) of the map
6152 case 0x13: {
6153 byte map_bits = 0;
6154 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6155 byte log_Y = MapLogY() - 6;
6156 byte max_edge = max(log_X, log_Y);
6158 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6159 SetBit(map_bits, 0);
6160 } else {
6161 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6164 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6165 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6168 default:
6169 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6170 return 0;
6175 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6177 uint start = 0;
6178 uint size = 0;
6180 if (op == 6) {
6181 /* Return GRFID of set that reserved ID */
6182 return grm[_cur.grffile->GetParam(target)];
6185 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6186 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6188 for (uint i = start; i < num_ids; i++) {
6189 if (grm[i] == 0) {
6190 size++;
6191 } else {
6192 if (op == 2 || op == 3) break;
6193 start = i + 1;
6194 size = 0;
6197 if (size == count) break;
6200 if (size == count) {
6201 /* Got the slot... */
6202 if (op == 0 || op == 3) {
6203 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6204 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6206 return start;
6209 /* Unable to allocate */
6210 if (op != 4 && op != 5) {
6211 /* Deactivate GRF */
6212 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6213 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6214 return UINT_MAX;
6217 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6218 return UINT_MAX;
6222 /** Action 0x0D: Set parameter */
6223 static void ParamSet(ByteReader *buf)
6225 /* <0D> <target> <operation> <source1> <source2> [<data>]
6227 * B target parameter number where result is stored
6228 * B operation operation to perform, see below
6229 * B source1 first source operand
6230 * B source2 second source operand
6231 * D data data to use in the calculation, not necessary
6232 * if both source1 and source2 refer to actual parameters
6234 * Operations
6235 * 00 Set parameter equal to source1
6236 * 01 Addition, source1 + source2
6237 * 02 Subtraction, source1 - source2
6238 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6239 * 04 Signed multiplication, source1 * source2 (both signed)
6240 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6241 * signed quantity; left shift if positive and right shift if
6242 * negative, source1 is unsigned)
6243 * 06 Signed bit shift, source1 by source2
6244 * (source2 like in 05, and source1 as well)
6247 uint8 target = buf->ReadByte();
6248 uint8 oper = buf->ReadByte();
6249 uint32 src1 = buf->ReadByte();
6250 uint32 src2 = buf->ReadByte();
6252 uint32 data = 0;
6253 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6255 /* You can add 80 to the operation to make it apply only if the target
6256 * is not defined yet. In this respect, a parameter is taken to be
6257 * defined if any of the following applies:
6258 * - it has been set to any value in the newgrf(w).cfg parameter list
6259 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6260 * an earlier action D */
6261 if (HasBit(oper, 7)) {
6262 if (target < 0x80 && target < _cur.grffile->param_end) {
6263 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6264 return;
6267 oper = GB(oper, 0, 7);
6270 if (src2 == 0xFE) {
6271 if (GB(data, 0, 8) == 0xFF) {
6272 if (data == 0x0000FFFF) {
6273 /* Patch variables */
6274 src1 = GetPatchVariable(src1);
6275 } else {
6276 /* GRF Resource Management */
6277 uint8 op = src1;
6278 uint8 feature = GB(data, 8, 8);
6279 uint16 count = GB(data, 16, 16);
6281 if (_cur.stage == GLS_RESERVE) {
6282 if (feature == 0x08) {
6283 /* General sprites */
6284 if (op == 0) {
6285 /* Check if the allocated sprites will fit below the original sprite limit */
6286 if (_cur.spriteid + count >= 16384) {
6287 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6288 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6289 return;
6292 /* Reserve space at the current sprite ID */
6293 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6294 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6295 _cur.spriteid += count;
6298 /* Ignore GRM result during reservation */
6299 src1 = 0;
6300 } else if (_cur.stage == GLS_ACTIVATION) {
6301 switch (feature) {
6302 case 0x00: // Trains
6303 case 0x01: // Road Vehicles
6304 case 0x02: // Ships
6305 case 0x03: // Aircraft
6306 if (!_settings_game.vehicle.dynamic_engines) {
6307 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6308 if (_cur.skip_sprites == -1) return;
6309 } else {
6310 /* GRM does not apply for dynamic engine allocation. */
6311 switch (op) {
6312 case 2:
6313 case 3:
6314 src1 = _cur.grffile->GetParam(target);
6315 break;
6317 default:
6318 src1 = 0;
6319 break;
6322 break;
6324 case 0x08: // General sprites
6325 switch (op) {
6326 case 0:
6327 /* Return space reserved during reservation stage */
6328 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6329 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6330 break;
6332 case 1:
6333 src1 = _cur.spriteid;
6334 break;
6336 default:
6337 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6338 return;
6340 break;
6342 case 0x0B: // Cargo
6343 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6344 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
6345 if (_cur.skip_sprites == -1) return;
6346 break;
6348 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6350 } else {
6351 /* Ignore GRM during initialization */
6352 src1 = 0;
6355 } else {
6356 /* Read another GRF File's parameter */
6357 const GRFFile *file = GetFileByGRFID(data);
6358 GRFConfig *c = GetGRFConfig(data);
6359 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6360 /* Disable the read GRF if it is a static NewGRF. */
6361 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6362 src1 = 0;
6363 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
6364 src1 = 0;
6365 } else if (src1 == 0xFE) {
6366 src1 = c->version;
6367 } else {
6368 src1 = file->GetParam(src1);
6371 } else {
6372 /* The source1 and source2 operands refer to the grf parameter number
6373 * like in action 6 and 7. In addition, they can refer to the special
6374 * variables available in action 7, or they can be FF to use the value
6375 * of <data>. If referring to parameters that are undefined, a value
6376 * of 0 is used instead. */
6377 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6378 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6381 /* TODO: You can access the parameters of another GRF file by using
6382 * source2=FE, source1=the other GRF's parameter number and data=GRF
6383 * ID. This is only valid with operation 00 (set). If the GRF ID
6384 * cannot be found, a value of 0 is used for the parameter value
6385 * instead. */
6387 uint32 res;
6388 switch (oper) {
6389 case 0x00:
6390 res = src1;
6391 break;
6393 case 0x01:
6394 res = src1 + src2;
6395 break;
6397 case 0x02:
6398 res = src1 - src2;
6399 break;
6401 case 0x03:
6402 res = src1 * src2;
6403 break;
6405 case 0x04:
6406 res = (int32)src1 * (int32)src2;
6407 break;
6409 case 0x05:
6410 if ((int32)src2 < 0) {
6411 res = src1 >> -(int32)src2;
6412 } else {
6413 res = src1 << src2;
6415 break;
6417 case 0x06:
6418 if ((int32)src2 < 0) {
6419 res = (int32)src1 >> -(int32)src2;
6420 } else {
6421 res = (int32)src1 << src2;
6423 break;
6425 case 0x07: // Bitwise AND
6426 res = src1 & src2;
6427 break;
6429 case 0x08: // Bitwise OR
6430 res = src1 | src2;
6431 break;
6433 case 0x09: // Unsigned division
6434 if (src2 == 0) {
6435 res = src1;
6436 } else {
6437 res = src1 / src2;
6439 break;
6441 case 0x0A: // Signed divison
6442 if (src2 == 0) {
6443 res = src1;
6444 } else {
6445 res = (int32)src1 / (int32)src2;
6447 break;
6449 case 0x0B: // Unsigned modulo
6450 if (src2 == 0) {
6451 res = src1;
6452 } else {
6453 res = src1 % src2;
6455 break;
6457 case 0x0C: // Signed modulo
6458 if (src2 == 0) {
6459 res = src1;
6460 } else {
6461 res = (int32)src1 % (int32)src2;
6463 break;
6465 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6468 switch (target) {
6469 case 0x8E: // Y-Offset for train sprites
6470 _cur.grffile->traininfo_vehicle_pitch = res;
6471 break;
6473 case 0x8F: { // Rail track type cost factors
6474 extern RailtypeInfo _railtypes[RAILTYPE_END];
6475 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6476 if (_settings_game.vehicle.disable_elrails) {
6477 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6478 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6479 } else {
6480 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6481 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6483 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6484 break;
6487 /* @todo implement */
6488 case 0x93: // Tile refresh offset to left
6489 case 0x94: // Tile refresh offset to right
6490 case 0x95: // Tile refresh offset upwards
6491 case 0x96: // Tile refresh offset downwards
6492 case 0x97: // Snow line height
6493 case 0x99: // Global ID offset
6494 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6495 break;
6497 case 0x9E: // Miscellaneous GRF features
6498 _misc_grf_features = res;
6500 /* Set train list engine width */
6501 _cur.grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6503 /* Remove the local flags from the global flags */
6504 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
6505 break;
6507 case 0x9F: // locale-dependent settings
6508 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6509 break;
6511 default:
6512 if (target < 0x80) {
6513 _cur.grffile->param[target] = res;
6514 /* param is zeroed by default */
6515 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6516 } else {
6517 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6519 break;
6523 /* Action 0x0E (GLS_SAFETYSCAN) */
6524 static void SafeGRFInhibit(ByteReader *buf)
6526 /* <0E> <num> <grfids...>
6528 * B num Number of GRFIDs that follow
6529 * D grfids GRFIDs of the files to deactivate */
6531 uint8 num = buf->ReadByte();
6533 for (uint i = 0; i < num; i++) {
6534 uint32 grfid = buf->ReadDWord();
6536 /* GRF is unsafe it if tries to deactivate other GRFs */
6537 if (grfid != _cur.grfconfig->ident.grfid) {
6538 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6540 /* Skip remainder of GRF */
6541 _cur.skip_sprites = -1;
6543 return;
6548 /* Action 0x0E */
6549 static void GRFInhibit(ByteReader *buf)
6551 /* <0E> <num> <grfids...>
6553 * B num Number of GRFIDs that follow
6554 * D grfids GRFIDs of the files to deactivate */
6556 uint8 num = buf->ReadByte();
6558 for (uint i = 0; i < num; i++) {
6559 uint32 grfid = buf->ReadDWord();
6560 GRFConfig *file = GetGRFConfig(grfid);
6562 /* Unset activation flag */
6563 if (file != NULL && file != _cur.grfconfig) {
6564 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6565 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6566 error->data = strdup(_cur.grfconfig->GetName());
6571 /** Action 0x0F - Define Town names */
6572 static void FeatureTownName(ByteReader *buf)
6574 /* <0F> <id> <style-name> <num-parts> <parts>
6576 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6577 * V style-name Name of the style (only for final definition)
6578 * B num-parts Number of parts in this definition
6579 * V parts The parts */
6581 uint32 grfid = _cur.grffile->grfid;
6583 GRFTownName *townname = AddGRFTownName(grfid);
6585 byte id = buf->ReadByte();
6586 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6588 if (HasBit(id, 7)) {
6589 /* Final definition */
6590 ClrBit(id, 7);
6591 bool new_scheme = _cur.grffile->grf_version >= 7;
6593 byte lang = buf->ReadByte();
6595 byte nb_gen = townname->nb_gen;
6596 do {
6597 ClrBit(lang, 7);
6599 const char *name = buf->ReadString();
6601 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6602 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6603 free(lang_name);
6605 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6607 lang = buf->ReadByte();
6608 } while (lang != 0);
6609 townname->id[nb_gen] = id;
6610 townname->nb_gen++;
6613 byte nb = buf->ReadByte();
6614 grfmsg(6, "FeatureTownName: %u parts", nb);
6616 townname->nbparts[id] = nb;
6617 townname->partlist[id] = CallocT<NamePartList>(nb);
6619 for (int i = 0; i < nb; i++) {
6620 byte nbtext = buf->ReadByte();
6621 townname->partlist[id][i].bitstart = buf->ReadByte();
6622 townname->partlist[id][i].bitcount = buf->ReadByte();
6623 townname->partlist[id][i].maxprob = 0;
6624 townname->partlist[id][i].partcount = nbtext;
6625 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6626 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);
6628 for (int j = 0; j < nbtext; j++) {
6629 byte prob = buf->ReadByte();
6631 if (HasBit(prob, 7)) {
6632 byte ref_id = buf->ReadByte();
6634 if (townname->nbparts[ref_id] == 0) {
6635 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6636 DelGRFTownName(grfid);
6637 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6638 return;
6641 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6642 townname->partlist[id][i].parts[j].data.id = ref_id;
6643 } else {
6644 const char *text = buf->ReadString();
6645 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6646 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6648 townname->partlist[id][i].parts[j].prob = prob;
6649 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6651 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6655 /** Action 0x10 - Define goto label */
6656 static void DefineGotoLabel(ByteReader *buf)
6658 /* <10> <label> [<comment>]
6660 * B label The label to define
6661 * V comment Optional comment - ignored */
6663 byte nfo_label = buf->ReadByte();
6665 GRFLabel *label = MallocT<GRFLabel>(1);
6666 label->label = nfo_label;
6667 label->nfo_line = _cur.nfo_line;
6668 label->pos = FioGetPos();
6669 label->next = NULL;
6671 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6672 if (_cur.grffile->label == NULL) {
6673 _cur.grffile->label = label;
6674 } else {
6675 /* Attach the label to the end of the list */
6676 GRFLabel *l;
6677 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
6678 l->next = label;
6681 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
6684 /* Action 0x11 */
6685 static void GRFSound(ByteReader *buf)
6687 /* <11> <num>
6689 * W num Number of sound files that follow */
6691 uint16 num = buf->ReadWord();
6693 _cur.data_blocks = num;
6694 _cur.data_type = GDT_SOUND;
6696 if (_cur.grffile->sound_offset == 0) {
6697 _cur.grffile->sound_offset = GetNumSounds();
6698 _cur.grffile->num_sounds = num;
6702 /* Action 0x11 (SKIP) */
6703 static void SkipAct11(ByteReader *buf)
6705 /* <11> <num>
6707 * W num Number of sound files that follow */
6709 _cur.skip_sprites = buf->ReadWord();
6711 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
6714 static void ImportGRFSound(ByteReader *buf)
6716 const GRFFile *file;
6717 SoundEntry *sound = AllocateSound();
6718 uint32 grfid = buf->ReadDWord();
6719 SoundID sound_id = buf->ReadWord();
6721 file = GetFileByGRFID(grfid);
6722 if (file == NULL || file->sound_offset == 0) {
6723 grfmsg(1, "ImportGRFSound: Source file not available");
6724 return;
6727 if (sound_id >= file->num_sounds) {
6728 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
6729 return;
6732 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
6734 *sound = *GetSound(file->sound_offset + sound_id);
6736 /* Reset volume and priority, which TTDPatch doesn't copy */
6737 sound->volume = 128;
6738 sound->priority = 0;
6741 /* 'Action 0xFE' */
6742 static void GRFImportBlock(ByteReader *buf)
6744 if (_cur.data_blocks == 0) {
6745 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
6746 return;
6749 _cur.data_blocks--;
6751 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
6752 * importing sounds, so this is probably all wrong... */
6753 if (buf->ReadByte() != _cur.data_type) {
6754 grfmsg(1, "GRFImportBlock: Import type mismatch");
6757 switch (_cur.data_type) {
6758 case GDT_SOUND: ImportGRFSound(buf); break;
6759 default: NOT_REACHED();
6763 static void LoadGRFSound(ByteReader *buf)
6765 /* Allocate a sound entry. This is done even if the data is not loaded
6766 * so that the indices used elsewhere are still correct. */
6767 SoundEntry *sound = AllocateSound();
6769 if (buf->ReadDWord() != BSWAP32('RIFF')) {
6770 grfmsg(1, "LoadGRFSound: Missing RIFF header");
6771 return;
6774 uint32 total_size = buf->ReadDWord();
6775 if (total_size > buf->Remaining()) {
6776 grfmsg(1, "LoadGRFSound: RIFF was truncated");
6777 return;
6780 if (buf->ReadDWord() != BSWAP32('WAVE')) {
6781 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
6782 return;
6785 while (total_size >= 8) {
6786 uint32 tag = buf->ReadDWord();
6787 uint32 size = buf->ReadDWord();
6788 total_size -= 8;
6789 if (total_size < size) {
6790 grfmsg(1, "LoadGRFSound: Invalid RIFF");
6791 return;
6793 total_size -= size;
6795 switch (tag) {
6796 case ' tmf': // 'fmt '
6797 /* Audio format, must be 1 (PCM) */
6798 if (size < 16 || buf->ReadWord() != 1) {
6799 grfmsg(1, "LoadGRFSound: Invalid audio format");
6800 return;
6802 sound->channels = buf->ReadWord();
6803 sound->rate = buf->ReadDWord();
6804 buf->ReadDWord();
6805 buf->ReadWord();
6806 sound->bits_per_sample = buf->ReadWord();
6808 /* The rest will be skipped */
6809 size -= 16;
6810 break;
6812 case 'atad': // 'data'
6813 sound->file_size = size;
6814 sound->file_offset = FioGetPos() - buf->Remaining();
6815 sound->file_slot = _cur.file_index;
6817 /* Set default volume and priority */
6818 sound->volume = 0x80;
6819 sound->priority = 0;
6821 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
6822 return; // the fmt chunk has to appear before data, so we are finished
6824 default:
6825 /* Skip unknown chunks */
6826 break;
6829 /* Skip rest of chunk */
6830 for (; size > 0; size--) buf->ReadByte();
6833 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
6835 /* Clear everything that was read */
6836 MemSetT(sound, 0);
6839 /** Action 0x12 */
6840 static void LoadFontGlyph(ByteReader *buf)
6842 /* <12> <num_def> <font_size> <num_char> <base_char>
6844 * B num_def Number of definitions
6845 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
6846 * B num_char Number of consecutive glyphs
6847 * W base_char First character index */
6849 uint8 num_def = buf->ReadByte();
6851 for (uint i = 0; i < num_def; i++) {
6852 FontSize size = (FontSize)buf->ReadByte();
6853 uint8 num_char = buf->ReadByte();
6854 uint16 base_char = buf->ReadWord();
6856 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
6858 for (uint c = 0; c < num_char; c++) {
6859 SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
6860 _cur.nfo_line++;
6861 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
6866 /** Action 0x12 (SKIP) */
6867 static void SkipAct12(ByteReader *buf)
6869 /* <12> <num_def> <font_size> <num_char> <base_char>
6871 * B num_def Number of definitions
6872 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
6873 * B num_char Number of consecutive glyphs
6874 * W base_char First character index */
6876 uint8 num_def = buf->ReadByte();
6878 for (uint i = 0; i < num_def; i++) {
6879 /* Ignore 'size' byte */
6880 buf->ReadByte();
6882 /* Sum up number of characters */
6883 _cur.skip_sprites += buf->ReadByte();
6885 /* Ignore 'base_char' word */
6886 buf->ReadWord();
6889 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
6892 /** Action 0x13 */
6893 static void TranslateGRFStrings(ByteReader *buf)
6895 /* <13> <grfid> <num-ent> <offset> <text...>
6897 * 4*B grfid The GRFID of the file whose texts are to be translated
6898 * B num-ent Number of strings
6899 * W offset First text ID
6900 * S text... Zero-terminated strings */
6902 uint32 grfid = buf->ReadDWord();
6903 const GRFConfig *c = GetGRFConfig(grfid);
6904 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
6905 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
6906 return;
6909 if (c->status == GCS_INITIALISED) {
6910 /* If the file is not active but will be activated later, give an error
6911 * and disable this file. */
6912 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
6914 char tmp[256];
6915 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
6916 error->data = strdup(tmp);
6918 return;
6921 byte num_strings = buf->ReadByte();
6922 uint16 first_id = buf->ReadWord();
6924 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
6925 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
6926 return;
6929 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
6930 const char *string = buf->ReadString();
6932 if (StrEmpty(string)) {
6933 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
6934 continue;
6937 /* Since no language id is supplied this string has to be added as a
6938 * generic string, thus the language id of 0x7F. For this to work
6939 * new_scheme has to be true as well. A language id of 0x7F will be
6940 * overridden by a non-generic id, so this will not change anything if
6941 * a string has been provided specifically for this language. */
6942 AddGRFString(grfid, first_id + i, 0x7F, true, true, string, STR_UNDEFINED);
6946 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
6947 static bool ChangeGRFName(byte langid, const char *str)
6949 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
6950 return true;
6953 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
6954 static bool ChangeGRFDescription(byte langid, const char *str)
6956 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
6957 return true;
6960 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
6961 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
6963 if (len != 1) {
6964 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
6965 buf->Skip(len);
6966 } else {
6967 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
6969 return true;
6972 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
6973 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
6975 if (len != 1) {
6976 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
6977 buf->Skip(len);
6978 } else {
6979 char data = buf->ReadByte();
6980 GRFPalette pal = GRFP_GRF_UNSET;
6981 switch (data) {
6982 case '*':
6983 case 'A': pal = GRFP_GRF_ANY; break;
6984 case 'W': pal = GRFP_GRF_WINDOWS; break;
6985 case 'D': pal = GRFP_GRF_DOS; break;
6986 default:
6987 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
6988 break;
6990 if (pal != GRFP_GRF_UNSET) {
6991 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
6992 _cur.grfconfig->palette |= pal;
6995 return true;
6998 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
6999 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7001 if (len != 1) {
7002 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7003 buf->Skip(len);
7004 } else {
7005 char data = buf->ReadByte();
7006 GRFPalette pal = GRFP_BLT_UNSET;
7007 switch (data) {
7008 case '8': pal = GRFP_BLT_UNSET; break;
7009 case '3': pal = GRFP_BLT_32BPP; break;
7010 default:
7011 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7012 return true;
7014 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7015 _cur.grfconfig->palette |= pal;
7017 return true;
7020 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7021 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7023 if (len != 4) {
7024 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7025 buf->Skip(len);
7026 } else {
7027 /* Set min_loadable_version as well (default to minimal compatibility) */
7028 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7030 return true;
7033 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7034 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7036 if (len != 4) {
7037 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7038 buf->Skip(len);
7039 } else {
7040 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7041 if (_cur.grfconfig->version == 0) {
7042 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7043 _cur.grfconfig->min_loadable_version = 0;
7045 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7046 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7047 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7050 return true;
7053 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7055 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7056 static bool ChangeGRFParamName(byte langid, const char *str)
7058 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7059 return true;
7062 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7063 static bool ChangeGRFParamDescription(byte langid, const char *str)
7065 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7066 return true;
7069 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7070 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7072 if (len != 1) {
7073 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7074 buf->Skip(len);
7075 } else {
7076 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7077 if (type < PTYPE_END) {
7078 _cur_parameter->type = type;
7079 } else {
7080 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7083 return true;
7086 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7087 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7089 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7090 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7091 buf->Skip(len);
7092 } else if (len != 8) {
7093 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7094 buf->Skip(len);
7095 } else {
7096 _cur_parameter->min_value = buf->ReadDWord();
7097 _cur_parameter->max_value = buf->ReadDWord();
7099 return true;
7102 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7103 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7105 if (len < 1 || len > 3) {
7106 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7107 buf->Skip(len);
7108 } else {
7109 byte param_nr = buf->ReadByte();
7110 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7111 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7112 buf->Skip(len - 1);
7113 } else {
7114 _cur_parameter->param_nr = param_nr;
7115 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7116 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7120 return true;
7123 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7124 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7126 if (len != 4) {
7127 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7128 buf->Skip(len);
7129 } else {
7130 _cur_parameter->def_value = buf->ReadDWord();
7132 _cur.grfconfig->has_param_defaults = true;
7133 return true;
7136 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7137 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7138 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7141 * Data structure to store the allowed id/type combinations for action 14. The
7142 * data can be represented as a tree with 3 types of nodes:
7143 * 1. Branch nodes (identified by 'C' for choice).
7144 * 2. Binary leaf nodes (identified by 'B').
7145 * 3. Text leaf nodes (identified by 'T').
7147 struct AllowedSubtags {
7148 /** Create empty subtags object used to identify the end of a list. */
7149 AllowedSubtags() :
7150 id(0),
7151 type(0)
7155 * Create a binary leaf node.
7156 * @param id The id for this node.
7157 * @param handler The callback function to call.
7159 AllowedSubtags(uint32 id, DataHandler handler) :
7160 id(id),
7161 type('B')
7163 this->handler.data = handler;
7167 * Create a text leaf node.
7168 * @param id The id for this node.
7169 * @param handler The callback function to call.
7171 AllowedSubtags(uint32 id, TextHandler handler) :
7172 id(id),
7173 type('T')
7175 this->handler.text = handler;
7179 * Create a branch node with a callback handler
7180 * @param id The id for this node.
7181 * @param handler The callback function to call.
7183 AllowedSubtags(uint32 id, BranchHandler handler) :
7184 id(id),
7185 type('C')
7187 this->handler.call_handler = true;
7188 this->handler.u.branch = handler;
7192 * Create a branch node with a list of sub-nodes.
7193 * @param id The id for this node.
7194 * @param subtags Array with all valid subtags.
7196 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7197 id(id),
7198 type('C')
7200 this->handler.call_handler = false;
7201 this->handler.u.subtags = subtags;
7204 uint32 id; ///< The identifier for this node
7205 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7206 union {
7207 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7208 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7209 struct {
7210 union {
7211 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7212 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7213 } u;
7214 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7216 } handler;
7219 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7220 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7223 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7224 * of some parameter values (type uint/enum) or the names of some bits
7225 * (type bitmask). In both cases the format is the same:
7226 * Each subnode should be a text node with the value/bit number as id.
7228 static bool ChangeGRFParamValueNames(ByteReader *buf)
7230 byte type = buf->ReadByte();
7231 while (type != 0) {
7232 uint32 id = buf->ReadDWord();
7233 if (type != 'T' || id > _cur_parameter->max_value) {
7234 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7235 if (!SkipUnknownInfo(buf, type)) return false;
7236 type = buf->ReadByte();
7237 continue;
7240 byte langid = buf->ReadByte();
7241 const char *name_string = buf->ReadString();
7243 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7244 if (val_name != _cur_parameter->value_names.End()) {
7245 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7246 } else {
7247 GRFText *list = NULL;
7248 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7249 _cur_parameter->value_names.Insert(id, list);
7252 type = buf->ReadByte();
7254 return true;
7257 /** Action14 parameter tags */
7258 AllowedSubtags _tags_parameters[] = {
7259 AllowedSubtags('NAME', ChangeGRFParamName),
7260 AllowedSubtags('DESC', ChangeGRFParamDescription),
7261 AllowedSubtags('TYPE', ChangeGRFParamType),
7262 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7263 AllowedSubtags('MASK', ChangeGRFParamMask),
7264 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7265 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7266 AllowedSubtags()
7270 * Callback function for 'INFO'->'PARA' to set extra information about the
7271 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7272 * the parameter number as id. The first parameter has id 0. The maximum
7273 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7275 static bool HandleParameterInfo(ByteReader *buf)
7277 byte type = buf->ReadByte();
7278 while (type != 0) {
7279 uint32 id = buf->ReadDWord();
7280 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7281 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7282 if (!SkipUnknownInfo(buf, type)) return false;
7283 type = buf->ReadByte();
7284 continue;
7287 if (id >= _cur.grfconfig->param_info.Length()) {
7288 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7289 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7290 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7292 if (_cur.grfconfig->param_info[id] == NULL) {
7293 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7295 _cur_parameter = _cur.grfconfig->param_info[id];
7296 /* Read all parameter-data and process each node. */
7297 if (!HandleNodes(buf, _tags_parameters)) return false;
7298 type = buf->ReadByte();
7300 return true;
7303 /** Action14 tags for the INFO node */
7304 AllowedSubtags _tags_info[] = {
7305 AllowedSubtags('NAME', ChangeGRFName),
7306 AllowedSubtags('DESC', ChangeGRFDescription),
7307 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7308 AllowedSubtags('PALS', ChangeGRFPalette),
7309 AllowedSubtags('BLTR', ChangeGRFBlitter),
7310 AllowedSubtags('VRSN', ChangeGRFVersion),
7311 AllowedSubtags('MINV', ChangeGRFMinVersion),
7312 AllowedSubtags('PARA', HandleParameterInfo),
7313 AllowedSubtags()
7316 /** Action14 root tags */
7317 AllowedSubtags _tags_root[] = {
7318 AllowedSubtags('INFO', _tags_info),
7319 AllowedSubtags()
7324 * Try to skip the current node and all subnodes (if it's a branch node).
7325 * @param buf Buffer.
7326 * @param type The node type to skip.
7327 * @return True if we could skip the node, false if an error occured.
7329 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7331 /* type and id are already read */
7332 switch (type) {
7333 case 'C': {
7334 byte new_type = buf->ReadByte();
7335 while (new_type != 0) {
7336 buf->ReadDWord(); // skip the id
7337 if (!SkipUnknownInfo(buf, new_type)) return false;
7338 new_type = buf->ReadByte();
7340 break;
7343 case 'T':
7344 buf->ReadByte(); // lang
7345 buf->ReadString(); // actual text
7346 break;
7348 case 'B': {
7349 uint16 size = buf->ReadWord();
7350 buf->Skip(size);
7351 break;
7354 default:
7355 return false;
7358 return true;
7362 * Handle the nodes of an Action14
7363 * @param type Type of node.
7364 * @param id ID.
7365 * @param buf Buffer.
7366 * @param subtags Allowed subtags.
7367 * @return Whether all tags could be handled.
7369 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7371 uint i = 0;
7372 AllowedSubtags *tag;
7373 while ((tag = &subtags[i++])->type != 0) {
7374 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7375 switch (type) {
7376 default: NOT_REACHED();
7378 case 'T': {
7379 byte langid = buf->ReadByte();
7380 return tag->handler.text(langid, buf->ReadString());
7383 case 'B': {
7384 size_t len = buf->ReadWord();
7385 if (buf->Remaining() < len) return false;
7386 return tag->handler.data(len, buf);
7389 case 'C': {
7390 if (tag->handler.call_handler) {
7391 return tag->handler.u.branch(buf);
7393 return HandleNodes(buf, tag->handler.u.subtags);
7397 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7398 return SkipUnknownInfo(buf, type);
7402 * Handle the contents of a 'C' choice of an Action14
7403 * @param buf Buffer.
7404 * @param subtags List of subtags.
7405 * @return Whether the nodes could all be handled.
7407 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7409 byte type = buf->ReadByte();
7410 while (type != 0) {
7411 uint32 id = buf->ReadDWord();
7412 if (!HandleNode(type, id, buf, subtags)) return false;
7413 type = buf->ReadByte();
7415 return true;
7419 * Handle Action 0x14
7420 * @param buf Buffer.
7422 static void StaticGRFInfo(ByteReader *buf)
7424 /* <14> <type> <id> <text/data...> */
7425 HandleNodes(buf, _tags_root);
7428 /** 'Action 0xFF' */
7429 static void GRFDataBlock(ByteReader *buf)
7431 /* <FF> <name_len> <name> '\0' <data> */
7433 if (_cur.data_blocks == 0) {
7434 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
7435 return;
7438 uint8 name_len = buf->ReadByte();
7439 const char *name = reinterpret_cast<const char *>(buf->Data());
7440 buf->Skip(name_len);
7442 /* Test string termination */
7443 if (buf->ReadByte() != 0) {
7444 grfmsg(2, "GRFDataBlock: Name not properly terminated");
7445 return;
7448 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
7450 _cur.data_blocks--;
7452 switch (_cur.data_type) {
7453 case GDT_SOUND: LoadGRFSound(buf); break;
7454 default: NOT_REACHED();
7459 * Set the current NewGRF as unsafe for static use
7460 * @param buf Unused.
7461 * @note Used during safety scan on unsafe actions.
7463 static void GRFUnsafe(ByteReader *buf)
7465 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7467 /* Skip remainder of GRF */
7468 _cur.skip_sprites = -1;
7472 /** Initialize the TTDPatch flags */
7473 static void InitializeGRFSpecial()
7475 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7476 | (1 << 0x0D) // newairports
7477 | (1 << 0x0E) // largestations
7478 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7479 | (0 << 0x10) // loadtime
7480 | (1 << 0x12) // presignals
7481 | (1 << 0x13) // extpresignals
7482 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7483 | (1 << 0x1B) // multihead
7484 | (1 << 0x1D) // lowmemory
7485 | (1 << 0x1E); // generalfixes
7487 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7488 | (1 << 0x08) // mammothtrains
7489 | (1 << 0x09) // trainrefit
7490 | (0 << 0x0B) // subsidiaries
7491 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7492 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7493 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7494 | (1 << 0x14) // bridgespeedlimits
7495 | (1 << 0x16) // eternalgame
7496 | (1 << 0x17) // newtrains
7497 | (1 << 0x18) // newrvs
7498 | (1 << 0x19) // newships
7499 | (1 << 0x1A) // newplanes
7500 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B) // signalsontrafficside
7501 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7503 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7504 | (1 << 0x03) // semaphores
7505 | (1 << 0x0A) // newobjects
7506 | (0 << 0x0B) // enhancedgui
7507 | (0 << 0x0C) // newagerating
7508 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7509 | (1 << 0x0E) // fullloadany
7510 | (1 << 0x0F) // planespeed
7511 | (0 << 0x10) // moreindustriesperclimate - obsolete
7512 | (0 << 0x11) // moretoylandfeatures
7513 | (1 << 0x12) // newstations
7514 | (1 << 0x13) // tracktypecostdiff
7515 | (1 << 0x14) // manualconvert
7516 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7517 | (1 << 0x16) // canals
7518 | (1 << 0x17) // newstartyear
7519 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7520 | (1 << 0x19) // newhouses
7521 | (1 << 0x1A) // newbridges
7522 | (1 << 0x1B) // newtownnames
7523 | (1 << 0x1C) // moreanimation
7524 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7525 | (1 << 0x1E) // newshistory
7526 | (0 << 0x1F); // custombridgeheads
7528 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7529 | (1 << 0x01) // windowsnap
7530 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7531 | (1 << 0x03) // pathbasedsignalling
7532 | (0 << 0x04) // aichoosechance
7533 | (1 << 0x05) // resolutionwidth
7534 | (1 << 0x06) // resolutionheight
7535 | (1 << 0x07) // newindustries
7536 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7537 | (0 << 0x09) // townroadbranchprob
7538 | (0 << 0x0A) // tempsnowline
7539 | (1 << 0x0B) // newcargo
7540 | (1 << 0x0C) // enhancemultiplayer
7541 | (1 << 0x0D) // onewayroads
7542 | (1 << 0x0E) // irregularstations
7543 | (1 << 0x0F) // statistics
7544 | (1 << 0x10) // newsounds
7545 | (1 << 0x11) // autoreplace
7546 | (1 << 0x12) // autoslope
7547 | (0 << 0x13) // followvehicle
7548 | (1 << 0x14) // trams
7549 | (0 << 0x15) // enhancetunnels
7550 | (1 << 0x16) // shortrvs
7551 | (1 << 0x17) // articulatedrvs
7552 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7553 | (1 << 0x1E) // variablerunningcosts
7554 | (1 << 0x1F); // any switch is on
7557 /** Reset and clear all NewGRF stations */
7558 static void ResetCustomStations()
7560 const GRFFile * const *end = _grf_files.End();
7561 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7562 StationSpec **&stations = (*file)->stations;
7563 if (stations == NULL) continue;
7564 for (uint i = 0; i < MAX_STATIONS; i++) {
7565 if (stations[i] == NULL) continue;
7566 StationSpec *statspec = stations[i];
7568 delete[] statspec->renderdata;
7570 /* Release platforms and layouts */
7571 if (!statspec->copied_layouts) {
7572 for (uint l = 0; l < statspec->lengths; l++) {
7573 for (uint p = 0; p < statspec->platforms[l]; p++) {
7574 free(statspec->layouts[l][p]);
7576 free(statspec->layouts[l]);
7578 free(statspec->layouts);
7579 free(statspec->platforms);
7582 /* Release this station */
7583 free(statspec);
7586 /* Free and reset the station data */
7587 free(stations);
7588 stations = NULL;
7592 /** Reset and clear all NewGRF houses */
7593 static void ResetCustomHouses()
7595 const GRFFile * const *end = _grf_files.End();
7596 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7597 HouseSpec **&housespec = (*file)->housespec;
7598 if (housespec == NULL) continue;
7599 for (uint i = 0; i < HOUSE_MAX; i++) {
7600 free(housespec[i]);
7603 free(housespec);
7604 housespec = NULL;
7608 /** Reset and clear all NewGRF airports */
7609 static void ResetCustomAirports()
7611 const GRFFile * const *end = _grf_files.End();
7612 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7613 AirportSpec **aslist = (*file)->airportspec;
7614 if (aslist != NULL) {
7615 for (uint i = 0; i < NUM_AIRPORTS; i++) {
7616 AirportSpec *as = aslist[i];
7618 if (as != NULL) {
7619 /* We need to remove the tiles layouts */
7620 for (int j = 0; j < as->num_table; j++) {
7621 /* remove the individual layouts */
7622 free((void*)as->table[j]);
7624 free((void*)as->table);
7625 free((void*)as->depot_table);
7627 free(as);
7630 free(aslist);
7631 (*file)->airportspec = NULL;
7634 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7635 if (airporttilespec != NULL) {
7636 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
7637 free(airporttilespec[i]);
7639 free(airporttilespec);
7640 airporttilespec = NULL;
7645 /** Reset and clear all NewGRF industries */
7646 static void ResetCustomIndustries()
7648 const GRFFile * const *end = _grf_files.End();
7649 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7650 IndustrySpec **&industryspec = (*file)->industryspec;
7651 IndustryTileSpec **&indtspec = (*file)->indtspec;
7653 /* We are verifiying both tiles and industries specs loaded from the grf file
7654 * First, let's deal with industryspec */
7655 if (industryspec != NULL) {
7656 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
7657 IndustrySpec *ind = industryspec[i];
7658 if (ind == NULL) continue;
7660 /* We need to remove the sounds array */
7661 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7662 free((void*)ind->random_sounds);
7665 /* We need to remove the tiles layouts */
7666 CleanIndustryTileTable(ind);
7668 free(ind);
7671 free(industryspec);
7672 industryspec = NULL;
7675 if (indtspec == NULL) continue;
7676 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
7677 free(indtspec[i]);
7680 free(indtspec);
7681 indtspec = NULL;
7685 /** Reset and clear all NewObjects */
7686 static void ResetCustomObjects()
7688 const GRFFile * const *end = _grf_files.End();
7689 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7690 ObjectSpec **&objectspec = (*file)->objectspec;
7691 if (objectspec == NULL) continue;
7692 for (uint i = 0; i < NUM_OBJECTS; i++) {
7693 free(objectspec[i]);
7696 free(objectspec);
7697 objectspec = NULL;
7701 /** Reset and clear all NewGRFs */
7702 static void ResetNewGRF()
7704 const GRFFile * const *end = _grf_files.End();
7705 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7706 GRFFile *f = *file;
7707 free(f->filename);
7708 free(f->cargo_list);
7709 free(f->railtype_list);
7710 delete [] f->language_map;
7711 free(f);
7714 _grf_files.Clear();
7715 _cur.grffile = NULL;
7718 /** Clear all NewGRF errors */
7719 static void ResetNewGRFErrors()
7721 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
7722 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
7723 delete c->error;
7724 c->error = NULL;
7730 * Reset all NewGRF loaded data
7731 * TODO
7733 void ResetNewGRFData()
7735 CleanUpStrings();
7736 CleanUpGRFTownNames();
7738 /* Copy/reset original engine info data */
7739 SetupEngines();
7741 /* Copy/reset original bridge info data */
7742 ResetBridges();
7744 /* Reset rail type information */
7745 ResetRailTypes();
7747 /* Allocate temporary refit/cargo class data */
7748 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
7750 /* Fill rail type label temporary data for default trains */
7751 Engine *e;
7752 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
7753 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
7756 /* Reset GRM reservations */
7757 memset(&_grm_engines, 0, sizeof(_grm_engines));
7758 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
7760 /* Reset generic feature callback lists */
7761 ResetGenericCallbacks();
7763 /* Reset price base data */
7764 ResetPriceBaseMultipliers();
7766 /* Reset the curencies array */
7767 ResetCurrencies();
7769 /* Reset the house array */
7770 ResetCustomHouses();
7771 ResetHouses();
7773 /* Reset the industries structures*/
7774 ResetCustomIndustries();
7775 ResetIndustries();
7777 /* Reset the objects. */
7778 ObjectClass::Reset();
7779 ResetCustomObjects();
7780 ResetObjects();
7782 /* Reset station classes */
7783 StationClass::Reset();
7784 ResetCustomStations();
7786 /* Reset airport-related structures */
7787 AirportClass::Reset();
7788 ResetCustomAirports();
7789 AirportSpec::ResetAirports();
7790 AirportTileSpec::ResetAirportTiles();
7792 /* Reset canal sprite groups and flags */
7793 memset(_water_feature, 0, sizeof(_water_feature));
7795 /* Reset the snowline table. */
7796 ClearSnowLine();
7798 /* Reset NewGRF files */
7799 ResetNewGRF();
7801 /* Reset NewGRF errors. */
7802 ResetNewGRFErrors();
7804 /* Set up the default cargo types */
7805 SetupCargoForClimate(_settings_game.game_creation.landscape);
7807 /* Reset misc GRF features and train list display variables */
7808 _misc_grf_features = 0;
7810 _loaded_newgrf_features.has_2CC = false;
7811 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
7812 _loaded_newgrf_features.has_newhouses = false;
7813 _loaded_newgrf_features.has_newindustries = false;
7814 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
7816 /* Clear all GRF overrides */
7817 _grf_id_overrides.clear();
7819 InitializeSoundPool();
7820 _spritegroup_pool.CleanPool();
7824 * Reset NewGRF data which is stored persistently in savegames.
7826 void ResetPersistentNewGRFData()
7828 /* Reset override managers */
7829 _engine_mngr.ResetToDefaultMapping();
7830 _house_mngr.ResetMapping();
7831 _industry_mngr.ResetMapping();
7832 _industile_mngr.ResetMapping();
7833 _airport_mngr.ResetMapping();
7834 _airporttile_mngr.ResetMapping();
7838 * Construct the Cargo Mapping
7839 * @note This is the reverse of a cargo translation table
7841 static void BuildCargoTranslationMap()
7843 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
7845 for (CargoID c = 0; c < NUM_CARGO; c++) {
7846 const CargoSpec *cs = CargoSpec::Get(c);
7847 if (!cs->IsValid()) continue;
7849 if (_cur.grffile->cargo_max == 0) {
7850 /* Default translation table, so just a straight mapping to bitnum */
7851 _cur.grffile->cargo_map[c] = cs->bitnum;
7852 } else {
7853 /* Check the translation table for this cargo's label */
7854 for (uint i = 0; i < _cur.grffile->cargo_max; i++) {
7855 if (cs->label == _cur.grffile->cargo_list[i]) {
7856 _cur.grffile->cargo_map[c] = i;
7857 break;
7865 * Prepare loading a NewGRF file with its config
7866 * @param config The NewGRF configuration struct with name, id, parameters and alike.
7868 static void InitNewGRFFile(const GRFConfig *config)
7870 GRFFile *newfile = GetFileByFilename(config->filename);
7871 if (newfile != NULL) {
7872 /* We already loaded it once. */
7873 _cur.grffile = newfile;
7874 return;
7877 newfile = CallocT<GRFFile>(1);
7879 newfile->filename = strdup(config->filename);
7880 newfile->grfid = config->ident.grfid;
7882 /* Initialise local settings to defaults */
7883 newfile->traininfo_vehicle_pitch = 0;
7884 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
7886 /* Mark price_base_multipliers as 'not set' */
7887 for (Price i = PR_BEGIN; i < PR_END; i++) {
7888 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
7891 /* Initialise rail type map with default rail types */
7892 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
7893 newfile->railtype_map[0] = RAILTYPE_RAIL;
7894 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
7895 newfile->railtype_map[2] = RAILTYPE_MONO;
7896 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
7898 /* Copy the initial parameter list
7899 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
7900 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
7901 memset(newfile->param, 0, sizeof(newfile->param));
7903 assert(config->num_params <= lengthof(config->param));
7904 newfile->param_end = config->num_params;
7905 if (newfile->param_end > 0) {
7906 MemCpyT(newfile->param, config->param, newfile->param_end);
7909 *_grf_files.Append() = _cur.grffile = newfile;
7914 * List of what cargo labels are refittable for the given the vehicle-type.
7915 * Only currently active labels are applied.
7917 static const CargoLabel _default_refitmasks_rail[] = {
7918 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
7919 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
7920 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
7921 'PLST', 'FZDR',
7922 0 };
7924 static const CargoLabel _default_refitmasks_road[] = {
7925 0 };
7927 static const CargoLabel _default_refitmasks_ships[] = {
7928 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
7929 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
7930 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
7931 'PLST', 'FZDR',
7932 0 };
7934 static const CargoLabel _default_refitmasks_aircraft[] = {
7935 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
7936 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
7937 0 };
7939 static const CargoLabel * const _default_refitmasks[] = {
7940 _default_refitmasks_rail,
7941 _default_refitmasks_road,
7942 _default_refitmasks_ships,
7943 _default_refitmasks_aircraft,
7948 * Precalculate refit masks from cargo classes for all vehicles.
7950 static void CalculateRefitMasks()
7952 Engine *e;
7954 FOR_ALL_ENGINES(e) {
7955 EngineID engine = e->index;
7956 EngineInfo *ei = &e->info;
7957 uint32 mask = 0;
7958 uint32 not_mask = 0;
7959 uint32 xor_mask = 0;
7961 /* Did the newgrf specify any refitting? If not, use defaults. */
7962 if (_gted[engine].refitmask_valid) {
7963 if (ei->refit_mask != 0) {
7964 const GRFFile *file = _gted[engine].refitmask_grf;
7965 if (file == NULL) file = e->grf_prop.grffile;
7966 if (file != NULL && file->cargo_max != 0) {
7967 /* Apply cargo translation table to the refit mask */
7968 uint num_cargo = min(32, file->cargo_max);
7969 for (uint i = 0; i < num_cargo; i++) {
7970 if (!HasBit(ei->refit_mask, i)) continue;
7972 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
7973 if (c == CT_INVALID) continue;
7975 SetBit(xor_mask, c);
7977 } else {
7978 /* No cargo table, so use the cargo bitnum values */
7979 const CargoSpec *cs;
7980 FOR_ALL_CARGOSPECS(cs) {
7981 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
7986 if (_gted[engine].cargo_allowed != 0) {
7987 /* Build up the list of cargo types from the set cargo classes. */
7988 const CargoSpec *cs;
7989 FOR_ALL_CARGOSPECS(cs) {
7990 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
7991 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
7994 } else {
7995 /* Don't apply default refit mask to wagons nor engines with no capacity */
7996 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
7997 const CargoLabel *cl = _default_refitmasks[e->type];
7998 for (uint i = 0;; i++) {
7999 if (cl[i] == 0) break;
8001 CargoID cargo = GetCargoIDByLabel(cl[i]);
8002 if (cargo == CT_INVALID) continue;
8004 SetBit(xor_mask, cargo);
8009 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8011 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8012 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8013 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8014 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8016 /* Clear refit_mask for not refittable ships */
8017 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
8021 /** Set to use the correct action0 properties for each canal feature */
8022 static void FinaliseCanals()
8024 for (uint i = 0; i < CF_END; i++) {
8025 if (_water_feature[i].grffile != NULL) {
8026 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8027 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8032 /** Check for invalid engines */
8033 static void FinaliseEngineArray()
8035 Engine *e;
8037 FOR_ALL_ENGINES(e) {
8038 if (e->grf_prop.grffile == NULL) {
8039 const EngineIDMapping &eid = _engine_mngr[e->index];
8040 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8041 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8045 /* When the train does not set property 27 (misc flags), but it
8046 * is overridden by a NewGRF graphically we want to disable the
8047 * flipping possibility. */
8048 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->grf_prop.grffile != NULL && is_custom_sprite(e->u.rail.image_index)) {
8049 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8052 /* Skip wagons, there livery is defined via the engine */
8053 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8054 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8055 SetBit(_loaded_newgrf_features.used_liveries, ls);
8056 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8058 if (e->type == VEH_TRAIN) {
8059 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8060 switch (ls) {
8061 case LS_STEAM:
8062 case LS_DIESEL:
8063 case LS_ELECTRIC:
8064 case LS_MONORAIL:
8065 case LS_MAGLEV:
8066 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8067 break;
8069 case LS_DMU:
8070 case LS_EMU:
8071 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8072 break;
8074 default: NOT_REACHED();
8081 /** Check for invalid cargos */
8082 static void FinaliseCargoArray()
8084 for (CargoID c = 0; c < NUM_CARGO; c++) {
8085 CargoSpec *cs = CargoSpec::Get(c);
8086 if (!cs->IsValid()) {
8087 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8088 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8089 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8095 * Check if a given housespec is valid and disable it if it's not.
8096 * The housespecs that follow it are used to check the validity of
8097 * multitile houses.
8098 * @param hs The housespec to check.
8099 * @param next1 The housespec that follows \c hs.
8100 * @param next2 The housespec that follows \c next1.
8101 * @param next3 The housespec that follows \c next2.
8102 * @param filename The filename of the newgrf this house was defined in.
8103 * @return Whether the given housespec is valid.
8105 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8107 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8108 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8109 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8110 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8111 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8112 hs->enabled = false;
8113 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);
8114 return false;
8117 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8118 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8119 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8120 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8121 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8122 hs->enabled = false;
8123 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);
8124 return false;
8127 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8128 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8129 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8130 hs->enabled = false;
8131 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);
8132 return false;
8135 /* Make sure that additional parts of multitile houses are not available. */
8136 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8137 hs->enabled = false;
8138 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);
8139 return false;
8142 return true;
8146 * Make sure there is at least one house available in the year 0 for the given
8147 * climate / housezone combination.
8148 * @param bitmask The climate and housezone to check for. Exactly one climate
8149 * bit and one housezone bit should be set.
8151 static void EnsureEarlyHouse(HouseZones bitmask)
8153 Year min_year = MAX_YEAR;
8155 for (int i = 0; i < HOUSE_MAX; i++) {
8156 HouseSpec *hs = HouseSpec::Get(i);
8157 if (hs == NULL || !hs->enabled) continue;
8158 if ((hs->building_availability & bitmask) != bitmask) continue;
8159 if (hs->min_year < min_year) min_year = hs->min_year;
8162 if (min_year == 0) return;
8164 for (int i = 0; i < HOUSE_MAX; i++) {
8165 HouseSpec *hs = HouseSpec::Get(i);
8166 if (hs == NULL || !hs->enabled) continue;
8167 if ((hs->building_availability & bitmask) != bitmask) continue;
8168 if (hs->min_year == min_year) hs->min_year = 0;
8173 * Add all new houses to the house array. House properties can be set at any
8174 * time in the GRF file, so we can only add a house spec to the house array
8175 * after the file has finished loading. We also need to check the dates, due to
8176 * the TTDPatch behaviour described below that we need to emulate.
8178 static void FinaliseHouseArray()
8180 /* If there are no houses with start dates before 1930, then all houses
8181 * with start dates of 1930 have them reset to 0. This is in order to be
8182 * compatible with TTDPatch, where if no houses have start dates before
8183 * 1930 and the date is before 1930, the game pretends that this is 1930.
8184 * If there have been any houses defined with start dates before 1930 then
8185 * the dates are left alone.
8186 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8187 * minimum introduction date to 0.
8189 const GRFFile * const *end = _grf_files.End();
8190 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8191 HouseSpec **&housespec = (*file)->housespec;
8192 if (housespec == NULL) continue;
8194 for (int i = 0; i < HOUSE_MAX; i++) {
8195 HouseSpec *hs = housespec[i];
8197 if (hs == NULL) continue;
8199 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
8200 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
8201 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
8203 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8205 _house_mngr.SetEntitySpec(hs);
8209 for (int i = 0; i < HOUSE_MAX; i++) {
8210 HouseSpec *hs = HouseSpec::Get(i);
8211 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
8212 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
8213 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
8215 /* We need to check all houses again to we are sure that multitile houses
8216 * did get consecutive IDs and none of the parts are missing. */
8217 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8218 /* GetHouseNorthPart checks 3 houses that are directly before
8219 * it in the house pool. If any of those houses have multi-tile
8220 * flags set it assumes it's part of a multitile house. Since
8221 * we can have invalid houses in the pool marked as disabled, we
8222 * don't want to have them influencing valid tiles. As such set
8223 * building_flags to zero here to make sure any house following
8224 * this one in the pool is properly handled as 1x1 house. */
8225 hs->building_flags = TILE_NO_FLAG;
8229 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8230 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8231 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8232 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8233 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8234 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8236 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8237 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8238 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8239 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8240 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8241 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8246 * Add all new industries to the industry array. Industry properties can be set at any
8247 * time in the GRF file, so we can only add a industry spec to the industry array
8248 * after the file has finished loading.
8250 static void FinaliseIndustriesArray()
8252 const GRFFile * const *end = _grf_files.End();
8253 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8254 IndustrySpec **&industryspec = (*file)->industryspec;
8255 IndustryTileSpec **&indtspec = (*file)->indtspec;
8256 if (industryspec != NULL) {
8257 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
8258 IndustrySpec *indsp = industryspec[i];
8260 if (indsp != NULL && indsp->enabled) {
8261 StringID strid;
8262 /* process the conversion of text at the end, so to be sure everything will be fine
8263 * and available. Check if it does not return undefind marker, which is a very good sign of a
8264 * substitute industry who has not changed the string been examined, thus using it as such */
8265 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8266 if (strid != STR_UNDEFINED) indsp->name = strid;
8268 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8269 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8271 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8272 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8274 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8275 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8277 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8278 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8280 if (indsp->station_name != STR_NULL) {
8281 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8282 * station's name. Don't want to lose the value, therefore, do not process. */
8283 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8284 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8287 _industry_mngr.SetEntitySpec(indsp);
8288 _loaded_newgrf_features.has_newindustries = true;
8293 if (indtspec != NULL) {
8294 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
8295 IndustryTileSpec *indtsp = indtspec[i];
8296 if (indtsp != NULL) {
8297 _industile_mngr.SetEntitySpec(indtsp);
8303 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8304 IndustrySpec *indsp = &_industry_specs[j];
8305 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8306 for (uint i = 0; i < 3; i++) {
8307 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8310 if (!indsp->enabled) {
8311 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8317 * Add all new objects to the object array. Object properties can be set at any
8318 * time in the GRF file, so we can only add an object spec to the object array
8319 * after the file has finished loading.
8321 static void FinaliseObjectsArray()
8323 const GRFFile * const *end = _grf_files.End();
8324 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8325 ObjectSpec **&objectspec = (*file)->objectspec;
8326 if (objectspec != NULL) {
8327 for (int i = 0; i < NUM_OBJECTS; i++) {
8328 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8329 _object_mngr.SetEntitySpec(objectspec[i]);
8337 * Add all new airports to the airport array. Airport properties can be set at any
8338 * time in the GRF file, so we can only add a airport spec to the airport array
8339 * after the file has finished loading.
8341 static void FinaliseAirportsArray()
8343 const GRFFile * const *end = _grf_files.End();
8344 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8345 AirportSpec **&airportspec = (*file)->airportspec;
8346 if (airportspec != NULL) {
8347 for (int i = 0; i < NUM_AIRPORTS; i++) {
8348 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8349 _airport_mngr.SetEntitySpec(airportspec[i]);
8354 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8355 if (airporttilespec != NULL) {
8356 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
8357 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8358 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8365 /* Here we perform initial decoding of some special sprites (as are they
8366 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8367 * partial implementation yet).
8368 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8369 * a crafted invalid GRF file. We should tell that to the user somehow, or
8370 * better make this more robust in the future. */
8371 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8373 /* XXX: There is a difference between staged loading in TTDPatch and
8374 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8375 * during stage 1, whilst action 3 is carried out during stage 2 (to
8376 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8377 * IDs are valid only within a given set (action 1) block, and may be
8378 * overwritten after action 3 associates them. But overwriting happens
8379 * in an earlier stage than associating, so... We just process actions
8380 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8381 * --pasky
8382 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8383 * is not in memory and scanning the file every time would be too expensive.
8384 * In other stages we skip action 0x10 since it's already dealt with. */
8385 static const SpecialSpriteHandler handlers[][GLS_END] = {
8386 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8387 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8388 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8389 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8390 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8391 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8392 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8393 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8394 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8395 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8396 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8397 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8398 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8399 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8400 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8401 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8402 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8403 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
8404 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8405 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8406 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8409 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8411 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8412 if (it == _grf_line_to_action6_sprite_override.end()) {
8413 /* No preloaded sprite to work with; read the
8414 * pseudo sprite content. */
8415 FioReadBlock(buf, num);
8416 } else {
8417 /* Use the preloaded sprite data. */
8418 buf = _grf_line_to_action6_sprite_override[location];
8419 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8421 /* Skip the real (original) content of this action. */
8422 FioSeekTo(num, SEEK_CUR);
8425 ByteReader br(buf, buf + num);
8426 ByteReader *bufp = &br;
8428 try {
8429 byte action = bufp->ReadByte();
8431 if (action == 0xFF) {
8432 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
8433 GRFDataBlock(bufp);
8434 } else if (action == 0xFE) {
8435 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
8436 GRFImportBlock(bufp);
8437 } else if (action >= lengthof(handlers)) {
8438 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8439 } else if (handlers[action][stage] == NULL) {
8440 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8441 } else {
8442 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8443 handlers[action][stage](bufp);
8445 } catch (...) {
8446 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8447 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8453 * Load a particular NewGRF.
8454 * @param config The configuration of the to be loaded NewGRF.
8455 * @param file_index The Fio index of the first NewGRF to load.
8456 * @param stage The loading stage of the NewGRF.
8457 * @param subdir The sub directory to find the NewGRF in.
8459 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8461 const char *filename = config->filename;
8462 uint16 num;
8464 /* A .grf file is activated only if it was active when the game was
8465 * started. If a game is loaded, only its active .grfs will be
8466 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8467 * considered active if its action 8 has been processed, i.e. its
8468 * action 8 hasn't been skipped using an action 7.
8470 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8471 * carried out. All others are ignored, because they only need to be
8472 * processed once at initialization. */
8473 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8474 _cur.grffile = GetFileByFilename(filename);
8475 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8476 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8477 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8478 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
8481 if (file_index > LAST_GRF_SLOT) {
8482 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
8483 config->status = GCS_DISABLED;
8484 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8485 return;
8488 FioOpenFile(file_index, filename, subdir);
8489 _cur.file_index = file_index; // XXX
8490 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8492 _cur.grfconfig = config;
8494 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8496 /* Skip the first sprite; we don't care about how many sprites this
8497 * does contain; newest TTDPatches and George's longvehicles don't
8498 * neither, apparently. */
8499 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
8500 FioReadDword();
8501 } else {
8502 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8503 return;
8506 _cur.ClearDataForNextFile();
8508 ReusableBuffer<byte> buf;
8510 while ((num = FioReadWord()) != 0) {
8511 byte type = FioReadByte();
8512 _cur.nfo_line++;
8514 if (type == 0xFF) {
8515 if (_cur.skip_sprites == 0) {
8516 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8518 /* Stop all processing if we are to skip the remaining sprites */
8519 if (_cur.skip_sprites == -1) break;
8521 continue;
8522 } else {
8523 FioSkipBytes(num);
8525 } else {
8526 if (_cur.skip_sprites == 0) {
8527 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8528 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8529 break;
8532 FioSkipBytes(7);
8533 SkipSpriteData(type, num - 8);
8536 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8541 * Relocates the old shore sprites at new positions.
8543 * 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)
8544 * 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)
8545 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8547 static void ActivateOldShore()
8549 /* Use default graphics, if no shore sprites were loaded.
8550 * Should not happen, as openttd(w/d).grf includes some. */
8551 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8553 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8554 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8555 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8556 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8557 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8558 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8559 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8560 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8561 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8564 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8565 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8566 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8567 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8568 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8569 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8570 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
8571 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
8572 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
8574 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8575 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8576 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
8577 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
8582 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8584 static void FinalisePriceBaseMultipliers()
8586 extern const PriceBaseSpec _price_base_specs[];
8587 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8588 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8590 /* Evaluate grf overrides */
8591 int num_grfs = _grf_files.Length();
8592 int *grf_overrides = AllocaM(int, num_grfs);
8593 for (int i = 0; i < num_grfs; i++) {
8594 grf_overrides[i] = -1;
8596 GRFFile *source = _grf_files[i];
8597 uint32 override = _grf_id_overrides[source->grfid];
8598 if (override == 0) continue;
8600 GRFFile *dest = GetFileByGRFID(override);
8601 if (dest == NULL) continue;
8603 grf_overrides[i] = _grf_files.FindIndex(dest);
8604 assert(grf_overrides[i] >= 0);
8607 /* Override features and price base multipliers of earlier loaded grfs */
8608 for (int i = 0; i < num_grfs; i++) {
8609 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
8610 GRFFile *source = _grf_files[i];
8611 GRFFile *dest = _grf_files[grf_overrides[i]];
8613 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8614 source->grf_features |= features;
8615 dest->grf_features |= features;
8617 for (Price p = PR_BEGIN; p < PR_END; p++) {
8618 /* No price defined -> nothing to do */
8619 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
8620 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
8621 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8625 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
8626 for (int i = num_grfs - 1; i >= 0; i--) {
8627 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
8628 GRFFile *source = _grf_files[i];
8629 GRFFile *dest = _grf_files[grf_overrides[i]];
8631 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8632 source->grf_features |= features;
8633 dest->grf_features |= features;
8635 for (Price p = PR_BEGIN; p < PR_END; p++) {
8636 /* Already a price defined -> nothing to do */
8637 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
8638 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
8639 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8643 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
8644 for (int i = 0; i < num_grfs; i++) {
8645 if (grf_overrides[i] < 0) continue;
8646 GRFFile *source = _grf_files[i];
8647 GRFFile *dest = _grf_files[grf_overrides[i]];
8649 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8650 source->grf_features |= features;
8651 dest->grf_features |= features;
8653 for (Price p = PR_BEGIN; p < PR_END; p++) {
8654 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
8655 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
8656 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
8658 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
8662 /* Apply fallback prices */
8663 const GRFFile * const *end = _grf_files.End();
8664 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8665 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
8666 for (Price p = PR_BEGIN; p < PR_END; p++) {
8667 Price fallback_price = _price_base_specs[p].fallback_price;
8668 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
8669 /* No price multiplier has been set.
8670 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
8671 price_base_multipliers[p] = price_base_multipliers[fallback_price];
8676 /* Decide local/global scope of price base multipliers */
8677 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8678 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
8679 for (Price p = PR_BEGIN; p < PR_END; p++) {
8680 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
8681 /* No multiplier was set; set it to a neutral value */
8682 price_base_multipliers[p] = 0;
8683 } else {
8684 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
8685 /* The grf does not define any objects of the feature,
8686 * so it must be a difficulty setting. Apply it globally */
8687 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
8688 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
8689 price_base_multipliers[p] = 0;
8690 } else {
8691 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
8698 void InitDepotWindowBlockSizes();
8700 extern void InitGRFTownGeneratorNames();
8702 /** Finish loading NewGRFs and execute needed post-processing */
8703 static void AfterLoadGRFs()
8705 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
8706 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
8708 _string_to_grf_mapping.clear();
8710 /* Free the action 6 override sprites. */
8711 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
8712 free((*it).second);
8714 _grf_line_to_action6_sprite_override.clear();
8716 /* Polish cargos */
8717 FinaliseCargoArray();
8719 /* Pre-calculate all refit masks after loading GRF files. */
8720 CalculateRefitMasks();
8722 /* Polish engines */
8723 FinaliseEngineArray();
8725 /* Set the actually used Canal properties */
8726 FinaliseCanals();
8728 /* Set the block size in the depot windows based on vehicle sprite sizes */
8729 InitDepotWindowBlockSizes();
8731 /* Add all new houses to the house array. */
8732 FinaliseHouseArray();
8734 /* Add all new industries to the industry array. */
8735 FinaliseIndustriesArray();
8737 /* Add all new objects to the object array. */
8738 FinaliseObjectsArray();
8740 InitializeSortedCargoSpecs();
8742 /* Sort the list of industry types. */
8743 SortIndustryTypes();
8745 /* Create dynamic list of industry legends for smallmap_gui.cpp */
8746 BuildIndustriesLegend();
8748 /* Add all new airports to the airports array. */
8749 FinaliseAirportsArray();
8750 BindAirportSpecs();
8752 /* Update the townname generators list */
8753 InitGRFTownGeneratorNames();
8755 /* Run all queued vehicle list order changes */
8756 CommitVehicleListOrderChanges();
8758 /* Load old shore sprites in new position, if they were replaced by ActionA */
8759 ActivateOldShore();
8761 /* Set up custom rail types */
8762 InitRailTypes();
8764 Engine *e;
8765 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
8766 if (_gted[e->index].rv_max_speed != 0) {
8767 /* Set RV maximum speed from the mph/0.8 unit value */
8768 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
8772 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8773 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
8774 if (railtype == INVALID_RAILTYPE) {
8775 /* Rail type is not available, so disable this engine */
8776 e->info.climates = 0;
8777 } else {
8778 e->u.rail.railtype = railtype;
8782 SetYearEngineAgingStops();
8784 FinalisePriceBaseMultipliers();
8786 /* Deallocate temporary loading data */
8787 free(_gted);
8788 _grm_sprites.clear();
8792 * Load all the NewGRFs.
8793 * @param load_index The offset for the first sprite to add.
8794 * @param file_index The Fio index of the first NewGRF to load.
8796 void LoadNewGRF(uint load_index, uint file_index)
8798 /* In case of networking we need to "sync" the start values
8799 * so all NewGRFs are loaded equally. For this we use the
8800 * start date of the game and we set the counters, etc. to
8801 * 0 so they're the same too. */
8802 Date date = _date;
8803 Year year = _cur_year;
8804 DateFract date_fract = _date_fract;
8805 uint16 tick_counter = _tick_counter;
8806 byte display_opt = _display_opt;
8808 if (_networking) {
8809 _cur_year = _settings_game.game_creation.starting_year;
8810 _date = ConvertYMDToDate(_cur_year, 0, 1);
8811 _date_fract = 0;
8812 _tick_counter = 0;
8813 _display_opt = 0;
8816 InitializeGRFSpecial();
8818 ResetNewGRFData();
8821 * Reset the status of all files, so we can 'retry' to load them.
8822 * This is needed when one for example rearranges the NewGRFs in-game
8823 * and a previously disabled NewGRF becomes useable. If it would not
8824 * be reset, the NewGRF would remain disabled even though it should
8825 * have been enabled.
8827 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8828 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
8831 _cur.spriteid = load_index;
8833 /* Load newgrf sprites
8834 * in each loading stage, (try to) open each file specified in the config
8835 * and load information from it. */
8836 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
8837 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
8838 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
8839 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8840 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
8843 uint slot = file_index;
8845 _cur.stage = stage;
8846 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8847 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
8848 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
8850 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
8851 if (!FioCheckFileExists(c->filename, subdir)) {
8852 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
8853 c->status = GCS_NOT_FOUND;
8854 continue;
8857 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
8858 LoadNewGRFFile(c, slot++, stage, subdir);
8859 if (stage == GLS_RESERVE) {
8860 SetBit(c->flags, GCF_RESERVED);
8861 } else if (stage == GLS_ACTIVATION) {
8862 ClrBit(c->flags, GCF_RESERVED);
8863 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
8864 ClearTemporaryNewGRFData(_cur.grffile);
8865 BuildCargoTranslationMap();
8866 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
8867 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
8868 /* We're not going to activate this, so free whatever data we allocated */
8869 ClearTemporaryNewGRFData(_cur.grffile);
8874 /* Pseudo sprite processing is finished; free temporary stuff */
8875 _cur.ClearDataForNextFile();
8877 /* Call any functions that should be run after GRFs have been loaded. */
8878 AfterLoadGRFs();
8880 /* Now revert back to the original situation */
8881 _cur_year = year;
8882 _date = date;
8883 _date_fract = date_fract;
8884 _tick_counter = tick_counter;
8885 _display_opt = display_opt;
8889 * Check for grf miscelaneous bits
8890 * @param bit The bit to check.
8891 * @return Whether the bit is set.
8893 bool HasGrfMiscBit(GrfMiscBit bit)
8895 return HasBit(_misc_grf_features, bit);