(svn r28004) -Update from Eints:
[openttd.git] / src / newgrf.cpp
blobd06d1c40a58a712ff454f4f7d4e93033e63060de
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>
15 #include <algorithm>
17 #include "debug.h"
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
21 #include "bridge.h"
22 #include "town.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
26 #include "currency.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
39 #include "rev.h"
40 #include "fios.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
45 #include <map>
46 #include "smallmap_gui.h"
47 #include "genworld.h"
48 #include "error.h"
49 #include "vehicle_func.h"
50 #include "language.h"
51 #include "vehicle_base.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 #include "safeguards.h"
58 /* TTDPatch extended GRF format codec
59 * (c) Petr Baudis 2004 (GPL'd)
60 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
62 * Contains portions of documentation by TTDPatch team.
63 * Thanks especially to Josef Drexler for the documentation as well as a lot
64 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
65 * served as subject to the initial testing of this codec. */
67 /** List of all loaded GRF files */
68 static SmallVector<GRFFile *, 16> _grf_files;
70 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
71 byte _misc_grf_features = 0;
73 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
74 static uint32 _ttdpatch_flags[8];
76 /** Indicates which are the newgrf features currently loaded ingame */
77 GRFLoadedFeatures _loaded_newgrf_features;
79 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
81 /** Temporary data during loading of GRFs */
82 struct GrfProcessingState {
83 private:
84 /** Definition of a single Action1 spriteset */
85 struct SpriteSet {
86 SpriteID sprite; ///< SpriteID of the first sprite of the set.
87 uint num_sprites; ///< Number of sprites in the set.
90 /** Currently referenceable spritesets */
91 std::map<uint, SpriteSet> spritesets[GSF_END];
93 public:
94 /* Global state */
95 GrfLoadingStage stage; ///< Current loading stage
96 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
98 /* Local state in the file */
99 uint file_index; ///< File index of currently processed GRF file.
100 GRFFile *grffile; ///< Currently processed GRF file.
101 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
102 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
103 byte grf_container_ver; ///< Container format of the current GRF file.
105 /* Kind of return values when processing certain actions */
106 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
108 /* Currently referenceable spritegroups */
109 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
111 /** Clear temporary data before processing the next file in the current loading stage */
112 void ClearDataForNextFile()
114 this->nfo_line = 0;
115 this->skip_sprites = 0;
117 for (uint i = 0; i < GSF_END; i++) {
118 this->spritesets[i].clear();
121 memset(this->spritegroups, 0, sizeof(this->spritegroups));
125 * Records new spritesets.
126 * @param feature GrfSpecFeature the set is defined for.
127 * @param first_sprite SpriteID of the first sprite in the set.
128 * @param first_set First spriteset to define.
129 * @param numsets Number of sets to define.
130 * @param numents Number of sprites per set to define.
132 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
134 assert(feature < GSF_END);
135 for (uint i = 0; i < numsets; i++) {
136 SpriteSet &set = this->spritesets[feature][first_set + i];
137 set.sprite = first_sprite + i * numents;
138 set.num_sprites = numents;
143 * Check whether there are any valid spritesets for a feature.
144 * @param feature GrfSpecFeature to check.
145 * @return true if there are any valid sets.
146 * @note Spritesets with zero sprites are valid to allow callback-failures.
148 bool HasValidSpriteSets(byte feature) const
150 assert(feature < GSF_END);
151 return !this->spritesets[feature].empty();
155 * Check whether a specific set is defined.
156 * @param feature GrfSpecFeature to check.
157 * @param set Set to check.
158 * @return true if the set is valid.
159 * @note Spritesets with zero sprites are valid to allow callback-failures.
161 bool IsValidSpriteSet(byte feature, uint set) const
163 assert(feature < GSF_END);
164 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
168 * Returns the first sprite of a spriteset.
169 * @param feature GrfSpecFeature to query.
170 * @param set Set to query.
171 * @return First sprite of the set.
173 SpriteID GetSprite(byte feature, uint set) const
175 assert(IsValidSpriteSet(feature, set));
176 return this->spritesets[feature].find(set)->second.sprite;
180 * Returns the number of sprites in a spriteset
181 * @param feature GrfSpecFeature to query.
182 * @param set Set to query.
183 * @return Number of sprites in the set.
185 uint GetNumEnts(byte feature, uint set) const
187 assert(IsValidSpriteSet(feature, set));
188 return this->spritesets[feature].find(set)->second.num_sprites;
192 static GrfProcessingState _cur;
196 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
197 * @param <T> The type of vehicle.
198 * @param image_index The image index to check.
199 * @return True iff the image index is valid, or 0xFD (use new graphics).
201 template <VehicleType T>
202 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
204 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
207 class OTTDByteReaderSignal { };
209 /** Class to read from a NewGRF file */
210 class ByteReader {
211 protected:
212 byte *data;
213 byte *end;
215 public:
216 ByteReader(byte *data, byte *end) : data(data), end(end) { }
218 inline byte ReadByte()
220 if (data < end) return *(data)++;
221 throw OTTDByteReaderSignal();
224 uint16 ReadWord()
226 uint16 val = ReadByte();
227 return val | (ReadByte() << 8);
230 uint16 ReadExtendedByte()
232 uint16 val = ReadByte();
233 return val == 0xFF ? ReadWord() : val;
236 uint32 ReadDWord()
238 uint32 val = ReadWord();
239 return val | (ReadWord() << 16);
242 uint32 ReadVarSize(byte size)
244 switch (size) {
245 case 1: return ReadByte();
246 case 2: return ReadWord();
247 case 4: return ReadDWord();
248 default:
249 NOT_REACHED();
250 return 0;
254 const char *ReadString()
256 char *string = reinterpret_cast<char *>(data);
257 size_t string_length = ttd_strnlen(string, Remaining());
259 if (string_length == Remaining()) {
260 /* String was not NUL terminated, so make sure it is now. */
261 string[string_length - 1] = '\0';
262 grfmsg(7, "String was not terminated with a zero byte.");
263 } else {
264 /* Increase the string length to include the NUL byte. */
265 string_length++;
267 Skip(string_length);
269 return string;
272 inline size_t Remaining() const
274 return end - data;
277 inline bool HasData(size_t count = 1) const
279 return data + count <= end;
282 inline byte *Data()
284 return data;
287 inline void Skip(size_t len)
289 data += len;
290 /* It is valid to move the buffer to exactly the end of the data,
291 * as there may not be any more data read. */
292 if (data > end) throw OTTDByteReaderSignal();
296 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
298 static const uint NUM_STATIONS_PER_GRF = 255; ///< Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on.
300 /** Temporary engine data used when loading only */
301 struct GRFTempEngineData {
302 /** Summary state of refittability properties */
303 enum Refittability {
304 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
305 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
306 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
309 uint16 cargo_allowed;
310 uint16 cargo_disallowed;
311 RailTypeLabel railtypelabel;
312 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
313 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
314 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
315 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
316 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
317 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
320 * Update the summary refittability on setting a refittability property.
321 * @param non_empty true if the GRF sets the vehicle to be refittable.
323 void UpdateRefittability(bool non_empty)
325 if (non_empty) {
326 this->refittability = NONEMPTY;
327 } else if (this->refittability == UNSET) {
328 this->refittability = EMPTY;
333 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
336 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
337 * GRM for vehicles is only used if dynamic engine allocation is disabled,
338 * so 256 is the number of original engines. */
339 static uint32 _grm_engines[256];
341 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
342 static uint32 _grm_cargoes[NUM_CARGO * 2];
344 struct GRFLocation {
345 uint32 grfid;
346 uint32 nfoline;
348 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
350 bool operator<(const GRFLocation &other) const
352 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
355 bool operator == (const GRFLocation &other) const
357 return this->grfid == other.grfid && this->nfoline == other.nfoline;
361 static std::map<GRFLocation, SpriteID> _grm_sprites;
362 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
366 * DEBUG() function dedicated to newGRF debugging messages
367 * Function is essentially the same as DEBUG(grf, severity, ...) with the
368 * addition of file:line information when parsing grf files.
369 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
370 * loading/parsing grf files, not for runtime debug messages as there
371 * is no file information available during that time.
372 * @param severity debugging severity level, see debug.h
373 * @param str message in printf() format
375 void CDECL grfmsg(int severity, const char *str, ...)
377 char buf[1024];
378 va_list va;
380 va_start(va, str);
381 vseprintf(buf, lastof(buf), str, va);
382 va_end(va);
384 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
388 * Obtain a NewGRF file by its grfID
389 * @param grfid The grfID to obtain the file for
390 * @return The file.
392 static GRFFile *GetFileByGRFID(uint32 grfid)
394 const GRFFile * const *end = _grf_files.End();
395 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
396 if ((*file)->grfid == grfid) return *file;
398 return NULL;
402 * Obtain a NewGRF file by its filename
403 * @param filename The filename to obtain the file for.
404 * @return The file.
406 static GRFFile *GetFileByFilename(const char *filename)
408 const GRFFile * const *end = _grf_files.End();
409 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
410 if (strcmp((*file)->filename, filename) == 0) return *file;
412 return NULL;
415 /** Reset all NewGRFData that was used only while processing data */
416 static void ClearTemporaryNewGRFData(GRFFile *gf)
418 /* Clear the GOTO labels used for GRF processing */
419 for (GRFLabel *l = gf->label; l != NULL;) {
420 GRFLabel *l2 = l->next;
421 free(l);
422 l = l2;
424 gf->label = NULL;
428 * Disable a GRF
429 * @param message Error message or STR_NULL.
430 * @param config GRFConfig to disable, NULL for current.
431 * @return Error message of the GRF for further customisation.
433 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
435 GRFFile *file;
436 if (config != NULL) {
437 file = GetFileByGRFID(config->ident.grfid);
438 } else {
439 config = _cur.grfconfig;
440 file = _cur.grffile;
443 config->status = GCS_DISABLED;
444 if (file != NULL) ClearTemporaryNewGRFData(file);
445 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
447 if (message != STR_NULL) {
448 delete config->error;
449 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
450 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
453 return config->error;
457 * Information for mapping static StringIDs.
459 struct StringIDMapping {
460 uint32 grfid; ///< Source NewGRF.
461 StringID source; ///< Source StringID (GRF local).
462 StringID *target; ///< Destination for mapping result.
464 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
465 static StringIDMappingVector _string_to_grf_mapping;
468 * Record a static StringID for getting translated later.
469 * @param source Source StringID (GRF local).
470 * @param target Destination for the mapping result.
472 static void AddStringForMapping(StringID source, StringID *target)
474 *target = STR_UNDEFINED;
475 StringIDMapping *item = _string_to_grf_mapping.Append();
476 item->grfid = _cur.grffile->grfid;
477 item->source = source;
478 item->target = target;
482 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
483 * string IDs, but only for the ones we are aware off; the rest
484 * like likely unused and will show a warning.
485 * @param str the string ID to convert
486 * @return the converted string ID
488 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
490 /* StringID table for TextIDs 0x4E->0x6D */
491 static const StringID units_volume[] = {
492 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
493 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
496 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
497 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
499 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
502 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506 assert_compile(stringend - stringid == end - begin); \
507 if (str >= begin && str <= end) return str + (stringid - begin)
509 /* We have some changes in our cargo strings, resulting in some missing. */
510 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
511 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
512 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
513 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
515 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
517 /* Map building names according to our lang file changes. There are several
518 * ranges of house ids, all of which need to be remapped to allow newgrfs
519 * to use original house names. */
520 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
521 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
522 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
524 /* Same thing for industries */
525 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
526 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
527 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
528 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
529 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
531 switch (str) {
532 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
533 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
534 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
536 #undef TEXTID_TO_STRINGID
538 if (str == STR_NULL) return STR_EMPTY;
540 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
542 return STR_EMPTY;
546 * Used when setting an object's property to map to the GRF's strings
547 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
548 * @param grfid Id of the grf file.
549 * @param str StringID that we want to have the equivalent in OoenTTD.
550 * @return The properly adjusted StringID.
552 StringID MapGRFStringID(uint32 grfid, StringID str)
554 if (IsInsideMM(str, 0xD800, 0xE000)) {
555 /* General text provided by NewGRF.
556 * In the specs this is called the 0xDCxx range (misc presistent texts),
557 * but we meanwhile extended the range to 0xD800-0xDFFF.
558 * Note: We are not involved in the "persistent" business, since we do not store
559 * any NewGRF strings in savegames. */
560 return GetGRFStringID(grfid, str);
561 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
562 /* Callback text provided by NewGRF.
563 * In the specs this is called the 0xD0xx range (misc graphics texts).
564 * These texts can be returned by various callbacks.
566 * Due to how TTDP implements the GRF-local- to global-textid translation
567 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568 * We do not care about that difference and just mask out the 0x400 bit.
570 str &= ~0x400;
571 return GetGRFStringID(grfid, str);
572 } else {
573 /* The NewGRF wants to include/reference an original TTD string.
574 * Try our best to find an equivalent one. */
575 return TTDPStringIDToOTTDStringIDMapping(str);
579 static std::map<uint32, uint32> _grf_id_overrides;
582 * Set the override for a NewGRF
583 * @param source_grfid The grfID which wants to override another NewGRF.
584 * @param target_grfid The grfID which is being overridden.
586 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
588 _grf_id_overrides[source_grfid] = target_grfid;
589 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
593 * Returns the engine associated to a certain internal_id, resp. allocates it.
594 * @param file NewGRF that wants to change the engine.
595 * @param type Vehicle type.
596 * @param internal_id Engine ID inside the NewGRF.
597 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
598 * @return The requested engine.
600 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
602 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603 * them use the same engine slots. */
604 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
605 if (_settings_game.vehicle.dynamic_engines) {
606 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607 scope_grfid = file->grfid;
608 uint32 override = _grf_id_overrides[file->grfid];
609 if (override != 0) {
610 scope_grfid = override;
611 const GRFFile *grf_match = GetFileByGRFID(override);
612 if (grf_match == NULL) {
613 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
614 } else {
615 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
619 /* Check if the engine is registered in the override manager */
620 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
621 if (engine != INVALID_ENGINE) {
622 Engine *e = Engine::Get(engine);
623 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
624 return e;
628 /* Check if there is an unreserved slot */
629 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
630 if (engine != INVALID_ENGINE) {
631 Engine *e = Engine::Get(engine);
633 if (e->grf_prop.grffile == NULL) {
634 e->grf_prop.grffile = file;
635 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
638 /* Reserve the engine slot */
639 if (!static_access) {
640 EngineIDMapping *eid = _engine_mngr.Get(engine);
641 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
644 return e;
647 if (static_access) return NULL;
649 if (!Engine::CanAllocateItem()) {
650 grfmsg(0, "Can't allocate any more engines");
651 return NULL;
654 size_t engine_pool_size = Engine::GetPoolSize();
656 /* ... it's not, so create a new one based off an existing engine */
657 Engine *e = new Engine(type, internal_id);
658 e->grf_prop.grffile = file;
660 /* Reserve the engine slot */
661 assert(_engine_mngr.Length() == e->index);
662 EngineIDMapping *eid = _engine_mngr.Append();
663 eid->type = type;
664 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
665 eid->internal_id = internal_id;
666 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
668 if (engine_pool_size != Engine::GetPoolSize()) {
669 /* Resize temporary engine data ... */
670 _gted = ReallocT(_gted, Engine::GetPoolSize());
672 /* and blank the new block. */
673 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
674 memset(_gted + engine_pool_size, 0, len);
676 if (type == VEH_TRAIN) {
677 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
680 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
682 return e;
686 * Return the ID of a new engine
687 * @param file The NewGRF file providing the engine.
688 * @param type The Vehicle type.
689 * @param internal_id NewGRF-internal ID of the engine.
690 * @return The new EngineID.
691 * @note depending on the dynamic_engine setting and a possible override
692 * property the grfID may be unique or overwriting or partially re-defining
693 * properties of an existing engine.
695 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
697 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
698 if (_settings_game.vehicle.dynamic_engines) {
699 scope_grfid = file->grfid;
700 uint32 override = _grf_id_overrides[file->grfid];
701 if (override != 0) scope_grfid = override;
704 return _engine_mngr.GetID(type, internal_id, scope_grfid);
708 * Map the colour modifiers of TTDPatch to those that Open is using.
709 * @param grf_sprite Pointer to the structure been modified.
711 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
713 if (HasBit(grf_sprite->pal, 14)) {
714 ClrBit(grf_sprite->pal, 14);
715 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
718 if (HasBit(grf_sprite->sprite, 14)) {
719 ClrBit(grf_sprite->sprite, 14);
720 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
723 if (HasBit(grf_sprite->sprite, 15)) {
724 ClrBit(grf_sprite->sprite, 15);
725 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
730 * Read a sprite and a palette from the GRF and convert them into a format
731 * suitable to OpenTTD.
732 * @param buf Input stream.
733 * @param read_flags Whether to read TileLayoutFlags.
734 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
735 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
736 * @param feature GrfSpecFeature to use spritesets from.
737 * @param [out] grf_sprite Read sprite and palette.
738 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
739 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
740 * @return Read TileLayoutFlags.
742 static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
744 grf_sprite->sprite = buf->ReadWord();
745 grf_sprite->pal = buf->ReadWord();
746 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
748 MapSpriteMappingRecolour(grf_sprite);
750 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
751 ClrBit(grf_sprite->pal, 15);
752 if (custom_sprite) {
753 /* Use sprite from Action 1 */
754 uint index = GB(grf_sprite->sprite, 0, 14);
755 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
756 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757 grf_sprite->sprite = SPR_IMG_QUERY;
758 grf_sprite->pal = PAL_NONE;
759 } else {
760 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
761 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
762 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
763 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
765 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
766 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
768 return flags;
771 if (flags & TLF_CUSTOM_PALETTE) {
772 /* Use palette from Action 1 */
773 uint index = GB(grf_sprite->pal, 0, 14);
774 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
775 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776 grf_sprite->pal = PAL_NONE;
777 } else {
778 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
779 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
780 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
781 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
783 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
784 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
786 return flags;
789 return flags;
793 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
794 * @param buf Input stream.
795 * @param flags TileLayoutFlags to process.
796 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
797 * @param dts Sprite layout to insert data into.
798 * @param index Sprite index to process; 0 for ground sprite.
800 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
802 if (!(flags & TLF_DRAWING_FLAGS)) return;
804 if (dts->registers == NULL) dts->AllocateRegisters();
805 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
806 regs.flags = flags & TLF_DRAWING_FLAGS;
808 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
809 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
810 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
812 if (is_parent) {
813 if (flags & TLF_BB_XY_OFFSET) {
814 regs.delta.parent[0] = buf->ReadByte();
815 regs.delta.parent[1] = buf->ReadByte();
817 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
818 } else {
819 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
820 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
823 if (flags & TLF_SPRITE_VAR10) {
824 regs.sprite_var10 = buf->ReadByte();
825 if (regs.sprite_var10 > TLR_MAX_VAR10) {
826 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
828 return;
832 if (flags & TLF_PALETTE_VAR10) {
833 regs.palette_var10 = buf->ReadByte();
834 if (regs.palette_var10 > TLR_MAX_VAR10) {
835 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
837 return;
843 * Read a spritelayout from the GRF.
844 * @param buf Input
845 * @param num_building_sprites Number of building sprites to read
846 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
847 * @param feature GrfSpecFeature to use spritesets from.
848 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
849 * @param no_z_position Whether bounding boxes have no Z offset
850 * @param dts Layout container to output into
851 * @return True on error (GRF was disabled).
853 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
855 bool has_flags = HasBit(num_building_sprites, 6);
856 ClrBit(num_building_sprites, 6);
857 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
858 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
859 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
861 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
862 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
863 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
866 /* Groundsprite */
867 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
868 if (_cur.skip_sprites < 0) return true;
870 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
871 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
873 return true;
876 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
877 if (_cur.skip_sprites < 0) return true;
879 for (uint i = 0; i < num_building_sprites; i++) {
880 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
882 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
883 if (_cur.skip_sprites < 0) return true;
885 if (flags & ~valid_flags) {
886 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
888 return true;
891 seq->delta_x = buf->ReadByte();
892 seq->delta_y = buf->ReadByte();
894 if (!no_z_position) seq->delta_z = buf->ReadByte();
896 if (seq->IsParentSprite()) {
897 seq->size_x = buf->ReadByte();
898 seq->size_y = buf->ReadByte();
899 seq->size_z = buf->ReadByte();
902 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
903 if (_cur.skip_sprites < 0) return true;
906 /* Check if the number of sprites per spriteset is consistent */
907 bool is_consistent = true;
908 dts->consistent_max_offset = 0;
909 for (uint i = 0; i < num_building_sprites + 1; i++) {
910 if (max_sprite_offset[i] > 0) {
911 if (dts->consistent_max_offset == 0) {
912 dts->consistent_max_offset = max_sprite_offset[i];
913 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
914 is_consistent = false;
915 break;
918 if (max_palette_offset[i] > 0) {
919 if (dts->consistent_max_offset == 0) {
920 dts->consistent_max_offset = max_palette_offset[i];
921 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
922 is_consistent = false;
923 break;
928 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
931 if (!is_consistent || dts->registers != NULL) {
932 dts->consistent_max_offset = 0;
933 if (dts->registers == NULL) dts->AllocateRegisters();
935 for (uint i = 0; i < num_building_sprites + 1; i++) {
936 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
937 regs.max_sprite_offset = max_sprite_offset[i];
938 regs.max_palette_offset = max_palette_offset[i];
942 return false;
946 * Translate the refit mask.
948 static uint32 TranslateRefitMask(uint32 refit_mask)
950 uint32 result = 0;
951 uint8 bit;
952 FOR_EACH_SET_BIT(bit, refit_mask) {
953 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
954 if (cargo != CT_INVALID) SetBit(result, cargo);
956 return result;
960 * Converts TTD(P) Base Price pointers into the enum used by OTTD
961 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
962 * @param base_pointer TTD(P) Base Price Pointer
963 * @param error_location Function name for grf error messages
964 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
966 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
968 /* Special value for 'none' */
969 if (base_pointer == 0) {
970 *index = INVALID_PRICE;
971 return;
974 static const uint32 start = 0x4B34; ///< Position of first base price
975 static const uint32 size = 6; ///< Size of each base price record
977 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
979 return;
982 *index = (Price)((base_pointer - start) / size);
985 /** Possible return values for the FeatureChangeInfo functions */
986 enum ChangeInfoResult {
987 CIR_SUCCESS, ///< Variable was parsed and read
988 CIR_DISABLED, ///< GRF was disabled due to error
989 CIR_UNHANDLED, ///< Variable was parsed but unread
990 CIR_UNKNOWN, ///< Variable is unknown
991 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
994 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
997 * Define properties common to all vehicles
998 * @param ei Engine info.
999 * @param prop The property to change.
1000 * @param buf The property value.
1001 * @return ChangeInfoResult.
1003 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1005 switch (prop) {
1006 case 0x00: // Introduction date
1007 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1008 break;
1010 case 0x02: // Decay speed
1011 ei->decay_speed = buf->ReadByte();
1012 break;
1014 case 0x03: // Vehicle life
1015 ei->lifelength = buf->ReadByte();
1016 break;
1018 case 0x04: // Model life
1019 ei->base_life = buf->ReadByte();
1020 break;
1022 case 0x06: // Climates available
1023 ei->climates = buf->ReadByte();
1024 break;
1026 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1027 /* Amount of cargo loaded during a vehicle's "loading tick" */
1028 ei->load_amount = buf->ReadByte();
1029 break;
1031 default:
1032 return CIR_UNKNOWN;
1035 return CIR_SUCCESS;
1039 * Define properties for rail vehicles
1040 * @param engine :ocal ID of the first vehicle.
1041 * @param numinfo Number of subsequent IDs to change the property for.
1042 * @param prop The property to change.
1043 * @param buf The property value.
1044 * @return ChangeInfoResult.
1046 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1048 ChangeInfoResult ret = CIR_SUCCESS;
1050 for (int i = 0; i < numinfo; i++) {
1051 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1052 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1054 EngineInfo *ei = &e->info;
1055 RailVehicleInfo *rvi = &e->u.rail;
1057 switch (prop) {
1058 case 0x05: { // Track type
1059 uint8 tracktype = buf->ReadByte();
1061 if (tracktype < _cur.grffile->railtype_list.Length()) {
1062 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1063 break;
1066 switch (tracktype) {
1067 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1068 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1069 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1070 default:
1071 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1072 break;
1074 break;
1077 case 0x08: // AI passenger service
1078 /* Tells the AI that this engine is designed for
1079 * passenger services and shouldn't be used for freight. */
1080 rvi->ai_passenger_only = buf->ReadByte();
1081 break;
1083 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084 uint16 speed = buf->ReadWord();
1085 if (speed == 0xFFFF) speed = 0;
1087 rvi->max_speed = speed;
1088 break;
1091 case PROP_TRAIN_POWER: // 0x0B Power
1092 rvi->power = buf->ReadWord();
1094 /* Set engine / wagon state based on power */
1095 if (rvi->power != 0) {
1096 if (rvi->railveh_type == RAILVEH_WAGON) {
1097 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1099 } else {
1100 rvi->railveh_type = RAILVEH_WAGON;
1102 break;
1104 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1105 rvi->running_cost = buf->ReadByte();
1106 break;
1108 case 0x0E: // Running cost base
1109 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1110 break;
1112 case 0x12: { // Sprite ID
1113 uint8 spriteid = buf->ReadByte();
1114 uint8 orig_spriteid = spriteid;
1116 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117 * as an array index, so we need it to be half the original value. */
1118 if (spriteid < 0xFD) spriteid >>= 1;
1120 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121 rvi->image_index = spriteid;
1122 } else {
1123 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124 rvi->image_index = 0;
1126 break;
1129 case 0x13: { // Dual-headed
1130 uint8 dual = buf->ReadByte();
1132 if (dual != 0) {
1133 rvi->railveh_type = RAILVEH_MULTIHEAD;
1134 } else {
1135 rvi->railveh_type = rvi->power == 0 ?
1136 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1138 break;
1141 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1142 rvi->capacity = buf->ReadByte();
1143 break;
1145 case 0x15: { // Cargo type
1146 _gted[e->index].defaultcargo_grf = _cur.grffile;
1147 uint8 ctype = buf->ReadByte();
1149 if (ctype == 0xFF) {
1150 /* 0xFF is specified as 'use first refittable' */
1151 ei->cargo_type = CT_INVALID;
1152 } else if (_cur.grffile->grf_version >= 8) {
1153 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1155 } else if (ctype < NUM_CARGO) {
1156 /* Use untranslated cargo. */
1157 ei->cargo_type = ctype;
1158 } else {
1159 ei->cargo_type = CT_INVALID;
1160 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1162 break;
1165 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1166 SB(rvi->weight, 0, 8, buf->ReadByte());
1167 break;
1169 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1170 rvi->cost_factor = buf->ReadByte();
1171 break;
1173 case 0x18: // AI rank
1174 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1175 buf->ReadByte();
1176 break;
1178 case 0x19: { // Engine traction type
1179 /* What do the individual numbers mean?
1180 * 0x00 .. 0x07: Steam
1181 * 0x08 .. 0x27: Diesel
1182 * 0x28 .. 0x31: Electric
1183 * 0x32 .. 0x37: Monorail
1184 * 0x38 .. 0x41: Maglev
1186 uint8 traction = buf->ReadByte();
1187 EngineClass engclass;
1189 if (traction <= 0x07) {
1190 engclass = EC_STEAM;
1191 } else if (traction <= 0x27) {
1192 engclass = EC_DIESEL;
1193 } else if (traction <= 0x31) {
1194 engclass = EC_ELECTRIC;
1195 } else if (traction <= 0x37) {
1196 engclass = EC_MONORAIL;
1197 } else if (traction <= 0x41) {
1198 engclass = EC_MAGLEV;
1199 } else {
1200 break;
1203 if (_cur.grffile->railtype_list.Length() == 0) {
1204 /* Use traction type to select between normal and electrified
1205 * rail only when no translation list is in place. */
1206 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1207 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1210 rvi->engclass = engclass;
1211 break;
1214 case 0x1A: // Alter purchase list sort order
1215 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1216 break;
1218 case 0x1B: // Powered wagons power bonus
1219 rvi->pow_wag_power = buf->ReadWord();
1220 break;
1222 case 0x1C: // Refit cost
1223 ei->refit_cost = buf->ReadByte();
1224 break;
1226 case 0x1D: { // Refit cargo
1227 uint32 mask = buf->ReadDWord();
1228 _gted[e->index].UpdateRefittability(mask != 0);
1229 ei->refit_mask = TranslateRefitMask(mask);
1230 _gted[e->index].defaultcargo_grf = _cur.grffile;
1231 break;
1234 case 0x1E: // Callback
1235 ei->callback_mask = buf->ReadByte();
1236 break;
1238 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1239 rvi->tractive_effort = buf->ReadByte();
1240 break;
1242 case 0x20: // Air drag
1243 rvi->air_drag = buf->ReadByte();
1244 break;
1246 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1247 rvi->shorten_factor = buf->ReadByte();
1248 break;
1250 case 0x22: // Visual effect
1251 rvi->visual_effect = buf->ReadByte();
1252 /* Avoid accidentally setting visual_effect to the default value
1253 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254 if (rvi->visual_effect == VE_DEFAULT) {
1255 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1256 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1258 break;
1260 case 0x23: // Powered wagons weight bonus
1261 rvi->pow_wag_weight = buf->ReadByte();
1262 break;
1264 case 0x24: { // High byte of vehicle weight
1265 byte weight = buf->ReadByte();
1267 if (weight > 4) {
1268 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1269 } else {
1270 SB(rvi->weight, 8, 8, weight);
1272 break;
1275 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276 rvi->user_def_data = buf->ReadByte();
1277 break;
1279 case 0x26: // Retire vehicle early
1280 ei->retire_early = buf->ReadByte();
1281 break;
1283 case 0x27: // Miscellaneous flags
1284 ei->misc_flags = buf->ReadByte();
1285 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1286 _gted[e->index].prop27_set = true;
1287 break;
1289 case 0x28: // Cargo classes allowed
1290 _gted[e->index].cargo_allowed = buf->ReadWord();
1291 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1292 _gted[e->index].defaultcargo_grf = _cur.grffile;
1293 break;
1295 case 0x29: // Cargo classes disallowed
1296 _gted[e->index].cargo_disallowed = buf->ReadWord();
1297 _gted[e->index].UpdateRefittability(false);
1298 break;
1300 case 0x2A: // Long format introduction date (days since year 0)
1301 ei->base_intro = buf->ReadDWord();
1302 break;
1304 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1305 ei->cargo_age_period = buf->ReadWord();
1306 break;
1308 case 0x2C: // CTT refit include list
1309 case 0x2D: { // CTT refit exclude list
1310 uint8 count = buf->ReadByte();
1311 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1312 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1313 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1314 ctt = 0;
1315 while (count--) {
1316 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1317 if (ctype == CT_INVALID) continue;
1318 SetBit(ctt, ctype);
1320 break;
1323 default:
1324 ret = CommonVehicleChangeInfo(ei, prop, buf);
1325 break;
1329 return ret;
1333 * Define properties for road vehicles
1334 * @param engine Local ID of the first vehicle.
1335 * @param numinfo Number of subsequent IDs to change the property for.
1336 * @param prop The property to change.
1337 * @param buf The property value.
1338 * @return ChangeInfoResult.
1340 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1342 ChangeInfoResult ret = CIR_SUCCESS;
1344 for (int i = 0; i < numinfo; i++) {
1345 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1346 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1348 EngineInfo *ei = &e->info;
1349 RoadVehicleInfo *rvi = &e->u.road;
1351 switch (prop) {
1352 case 0x08: // Speed (1 unit is 0.5 kmh)
1353 rvi->max_speed = buf->ReadByte();
1354 break;
1356 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1357 rvi->running_cost = buf->ReadByte();
1358 break;
1360 case 0x0A: // Running cost base
1361 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1362 break;
1364 case 0x0E: { // Sprite ID
1365 uint8 spriteid = buf->ReadByte();
1366 uint8 orig_spriteid = spriteid;
1368 /* cars have different custom id in the GRF file */
1369 if (spriteid == 0xFF) spriteid = 0xFD;
1371 if (spriteid < 0xFD) spriteid >>= 1;
1373 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1374 rvi->image_index = spriteid;
1375 } else {
1376 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1377 rvi->image_index = 0;
1379 break;
1382 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1383 rvi->capacity = buf->ReadByte();
1384 break;
1386 case 0x10: { // Cargo type
1387 _gted[e->index].defaultcargo_grf = _cur.grffile;
1388 uint8 ctype = buf->ReadByte();
1390 if (ctype == 0xFF) {
1391 /* 0xFF is specified as 'use first refittable' */
1392 ei->cargo_type = CT_INVALID;
1393 } else if (_cur.grffile->grf_version >= 8) {
1394 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1395 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1396 } else if (ctype < NUM_CARGO) {
1397 /* Use untranslated cargo. */
1398 ei->cargo_type = ctype;
1399 } else {
1400 ei->cargo_type = CT_INVALID;
1401 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1403 break;
1406 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1407 rvi->cost_factor = buf->ReadByte();
1408 break;
1410 case 0x12: // SFX
1411 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1412 break;
1414 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1415 rvi->power = buf->ReadByte();
1416 break;
1418 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1419 rvi->weight = buf->ReadByte();
1420 break;
1422 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1423 _gted[e->index].rv_max_speed = buf->ReadByte();
1424 break;
1426 case 0x16: { // Cargoes available for refitting
1427 uint32 mask = buf->ReadDWord();
1428 _gted[e->index].UpdateRefittability(mask != 0);
1429 ei->refit_mask = TranslateRefitMask(mask);
1430 _gted[e->index].defaultcargo_grf = _cur.grffile;
1431 break;
1434 case 0x17: // Callback mask
1435 ei->callback_mask = buf->ReadByte();
1436 break;
1438 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1439 rvi->tractive_effort = buf->ReadByte();
1440 break;
1442 case 0x19: // Air drag
1443 rvi->air_drag = buf->ReadByte();
1444 break;
1446 case 0x1A: // Refit cost
1447 ei->refit_cost = buf->ReadByte();
1448 break;
1450 case 0x1B: // Retire vehicle early
1451 ei->retire_early = buf->ReadByte();
1452 break;
1454 case 0x1C: // Miscellaneous flags
1455 ei->misc_flags = buf->ReadByte();
1456 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1457 break;
1459 case 0x1D: // Cargo classes allowed
1460 _gted[e->index].cargo_allowed = buf->ReadWord();
1461 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1462 _gted[e->index].defaultcargo_grf = _cur.grffile;
1463 break;
1465 case 0x1E: // Cargo classes disallowed
1466 _gted[e->index].cargo_disallowed = buf->ReadWord();
1467 _gted[e->index].UpdateRefittability(false);
1468 break;
1470 case 0x1F: // Long format introduction date (days since year 0)
1471 ei->base_intro = buf->ReadDWord();
1472 break;
1474 case 0x20: // Alter purchase list sort order
1475 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1476 break;
1478 case 0x21: // Visual effect
1479 rvi->visual_effect = buf->ReadByte();
1480 /* Avoid accidentally setting visual_effect to the default value
1481 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1482 if (rvi->visual_effect == VE_DEFAULT) {
1483 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1484 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1486 break;
1488 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1489 ei->cargo_age_period = buf->ReadWord();
1490 break;
1492 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1493 rvi->shorten_factor = buf->ReadByte();
1494 break;
1496 case 0x24: // CTT refit include list
1497 case 0x25: { // CTT refit exclude list
1498 uint8 count = buf->ReadByte();
1499 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1500 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1501 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1502 ctt = 0;
1503 while (count--) {
1504 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1505 if (ctype == CT_INVALID) continue;
1506 SetBit(ctt, ctype);
1508 break;
1511 default:
1512 ret = CommonVehicleChangeInfo(ei, prop, buf);
1513 break;
1517 return ret;
1521 * Define properties for ships
1522 * @param engine Local ID of the first vehicle.
1523 * @param numinfo Number of subsequent IDs to change the property for.
1524 * @param prop The property to change.
1525 * @param buf The property value.
1526 * @return ChangeInfoResult.
1528 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1530 ChangeInfoResult ret = CIR_SUCCESS;
1532 for (int i = 0; i < numinfo; i++) {
1533 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1534 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1536 EngineInfo *ei = &e->info;
1537 ShipVehicleInfo *svi = &e->u.ship;
1539 switch (prop) {
1540 case 0x08: { // Sprite ID
1541 uint8 spriteid = buf->ReadByte();
1542 uint8 orig_spriteid = spriteid;
1544 /* ships have different custom id in the GRF file */
1545 if (spriteid == 0xFF) spriteid = 0xFD;
1547 if (spriteid < 0xFD) spriteid >>= 1;
1549 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1550 svi->image_index = spriteid;
1551 } else {
1552 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1553 svi->image_index = 0;
1555 break;
1558 case 0x09: // Refittable
1559 svi->old_refittable = (buf->ReadByte() != 0);
1560 break;
1562 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1563 svi->cost_factor = buf->ReadByte();
1564 break;
1566 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1567 svi->max_speed = buf->ReadByte();
1568 break;
1570 case 0x0C: { // Cargo type
1571 _gted[e->index].defaultcargo_grf = _cur.grffile;
1572 uint8 ctype = buf->ReadByte();
1574 if (ctype == 0xFF) {
1575 /* 0xFF is specified as 'use first refittable' */
1576 ei->cargo_type = CT_INVALID;
1577 } else if (_cur.grffile->grf_version >= 8) {
1578 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1579 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1580 } else if (ctype < NUM_CARGO) {
1581 /* Use untranslated cargo. */
1582 ei->cargo_type = ctype;
1583 } else {
1584 ei->cargo_type = CT_INVALID;
1585 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1587 break;
1590 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1591 svi->capacity = buf->ReadWord();
1592 break;
1594 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1595 svi->running_cost = buf->ReadByte();
1596 break;
1598 case 0x10: // SFX
1599 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1600 break;
1602 case 0x11: { // Cargoes available for refitting
1603 uint32 mask = buf->ReadDWord();
1604 _gted[e->index].UpdateRefittability(mask != 0);
1605 ei->refit_mask = TranslateRefitMask(mask);
1606 _gted[e->index].defaultcargo_grf = _cur.grffile;
1607 break;
1610 case 0x12: // Callback mask
1611 ei->callback_mask = buf->ReadByte();
1612 break;
1614 case 0x13: // Refit cost
1615 ei->refit_cost = buf->ReadByte();
1616 break;
1618 case 0x14: // Ocean speed fraction
1619 svi->ocean_speed_frac = buf->ReadByte();
1620 break;
1622 case 0x15: // Canal speed fraction
1623 svi->canal_speed_frac = buf->ReadByte();
1624 break;
1626 case 0x16: // Retire vehicle early
1627 ei->retire_early = buf->ReadByte();
1628 break;
1630 case 0x17: // Miscellaneous flags
1631 ei->misc_flags = buf->ReadByte();
1632 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1633 break;
1635 case 0x18: // Cargo classes allowed
1636 _gted[e->index].cargo_allowed = buf->ReadWord();
1637 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1638 _gted[e->index].defaultcargo_grf = _cur.grffile;
1639 break;
1641 case 0x19: // Cargo classes disallowed
1642 _gted[e->index].cargo_disallowed = buf->ReadWord();
1643 _gted[e->index].UpdateRefittability(false);
1644 break;
1646 case 0x1A: // Long format introduction date (days since year 0)
1647 ei->base_intro = buf->ReadDWord();
1648 break;
1650 case 0x1B: // Alter purchase list sort order
1651 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1652 break;
1654 case 0x1C: // Visual effect
1655 svi->visual_effect = buf->ReadByte();
1656 /* Avoid accidentally setting visual_effect to the default value
1657 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1658 if (svi->visual_effect == VE_DEFAULT) {
1659 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1660 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1662 break;
1664 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1665 ei->cargo_age_period = buf->ReadWord();
1666 break;
1668 case 0x1E: // CTT refit include list
1669 case 0x1F: { // CTT refit exclude list
1670 uint8 count = buf->ReadByte();
1671 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1672 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1673 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1674 ctt = 0;
1675 while (count--) {
1676 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1677 if (ctype == CT_INVALID) continue;
1678 SetBit(ctt, ctype);
1680 break;
1683 default:
1684 ret = CommonVehicleChangeInfo(ei, prop, buf);
1685 break;
1689 return ret;
1693 * Define properties for aircraft
1694 * @param engine Local ID of the aircraft.
1695 * @param numinfo Number of subsequent IDs to change the property for.
1696 * @param prop The property to change.
1697 * @param buf The property value.
1698 * @return ChangeInfoResult.
1700 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1702 ChangeInfoResult ret = CIR_SUCCESS;
1704 for (int i = 0; i < numinfo; i++) {
1705 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1706 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1708 EngineInfo *ei = &e->info;
1709 AircraftVehicleInfo *avi = &e->u.air;
1711 switch (prop) {
1712 case 0x08: { // Sprite ID
1713 uint8 spriteid = buf->ReadByte();
1714 uint8 orig_spriteid = spriteid;
1716 /* aircraft have different custom id in the GRF file */
1717 if (spriteid == 0xFF) spriteid = 0xFD;
1719 if (spriteid < 0xFD) spriteid >>= 1;
1721 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1722 avi->image_index = spriteid;
1723 } else {
1724 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1725 avi->image_index = 0;
1727 break;
1730 case 0x09: // Helicopter
1731 if (buf->ReadByte() == 0) {
1732 avi->subtype = AIR_HELI;
1733 } else {
1734 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1736 break;
1738 case 0x0A: // Large
1739 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1740 break;
1742 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1743 avi->cost_factor = buf->ReadByte();
1744 break;
1746 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1747 avi->max_speed = (buf->ReadByte() * 128) / 10;
1748 break;
1750 case 0x0D: // Acceleration
1751 avi->acceleration = buf->ReadByte();
1752 break;
1754 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1755 avi->running_cost = buf->ReadByte();
1756 break;
1758 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1759 avi->passenger_capacity = buf->ReadWord();
1760 break;
1762 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1763 avi->mail_capacity = buf->ReadByte();
1764 break;
1766 case 0x12: // SFX
1767 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1768 break;
1770 case 0x13: { // Cargoes available for refitting
1771 uint32 mask = buf->ReadDWord();
1772 _gted[e->index].UpdateRefittability(mask != 0);
1773 ei->refit_mask = TranslateRefitMask(mask);
1774 _gted[e->index].defaultcargo_grf = _cur.grffile;
1775 break;
1778 case 0x14: // Callback mask
1779 ei->callback_mask = buf->ReadByte();
1780 break;
1782 case 0x15: // Refit cost
1783 ei->refit_cost = buf->ReadByte();
1784 break;
1786 case 0x16: // Retire vehicle early
1787 ei->retire_early = buf->ReadByte();
1788 break;
1790 case 0x17: // Miscellaneous flags
1791 ei->misc_flags = buf->ReadByte();
1792 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1793 break;
1795 case 0x18: // Cargo classes allowed
1796 _gted[e->index].cargo_allowed = buf->ReadWord();
1797 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1798 _gted[e->index].defaultcargo_grf = _cur.grffile;
1799 break;
1801 case 0x19: // Cargo classes disallowed
1802 _gted[e->index].cargo_disallowed = buf->ReadWord();
1803 _gted[e->index].UpdateRefittability(false);
1804 break;
1806 case 0x1A: // Long format introduction date (days since year 0)
1807 ei->base_intro = buf->ReadDWord();
1808 break;
1810 case 0x1B: // Alter purchase list sort order
1811 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1812 break;
1814 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1815 ei->cargo_age_period = buf->ReadWord();
1816 break;
1818 case 0x1D: // CTT refit include list
1819 case 0x1E: { // CTT refit exclude list
1820 uint8 count = buf->ReadByte();
1821 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1822 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1823 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1824 ctt = 0;
1825 while (count--) {
1826 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1827 if (ctype == CT_INVALID) continue;
1828 SetBit(ctt, ctype);
1830 break;
1833 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1834 avi->max_range = buf->ReadWord();
1835 break;
1837 default:
1838 ret = CommonVehicleChangeInfo(ei, prop, buf);
1839 break;
1843 return ret;
1847 * Define properties for stations
1848 * @param stdid StationID of the first station tile.
1849 * @param numinfo Number of subsequent station tiles to change the property for.
1850 * @param prop The property to change.
1851 * @param buf The property value.
1852 * @return ChangeInfoResult.
1854 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1856 ChangeInfoResult ret = CIR_SUCCESS;
1858 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1859 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1860 return CIR_INVALID_ID;
1863 /* Allocate station specs if necessary */
1864 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1866 for (int i = 0; i < numinfo; i++) {
1867 StationSpec *statspec = _cur.grffile->stations[stid + i];
1869 /* Check that the station we are modifying is defined. */
1870 if (statspec == NULL && prop != 0x08) {
1871 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1872 return CIR_INVALID_ID;
1875 switch (prop) {
1876 case 0x08: { // Class ID
1877 StationSpec **spec = &_cur.grffile->stations[stid + i];
1879 /* Property 0x08 is special; it is where the station is allocated */
1880 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1882 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1883 uint32 classid = buf->ReadDWord();
1884 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1885 break;
1888 case 0x09: // Define sprite layout
1889 statspec->tiles = buf->ReadExtendedByte();
1890 delete[] statspec->renderdata; // delete earlier loaded stuff
1891 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1893 for (uint t = 0; t < statspec->tiles; t++) {
1894 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1895 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1897 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1898 buf->Skip(4);
1899 extern const DrawTileSprites _station_display_datas_rail[8];
1900 dts->Clone(&_station_display_datas_rail[t % 8]);
1901 continue;
1904 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1905 /* On error, bail out immediately. Temporary GRF data was already freed */
1906 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1908 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1909 tmp_layout.Clear();
1910 for (;;) {
1911 /* no relative bounding box support */
1912 DrawTileSeqStruct *dtss = tmp_layout.Append();
1913 MemSetT(dtss, 0);
1915 dtss->delta_x = buf->ReadByte();
1916 if (dtss->IsTerminator()) break;
1917 dtss->delta_y = buf->ReadByte();
1918 dtss->delta_z = buf->ReadByte();
1919 dtss->size_x = buf->ReadByte();
1920 dtss->size_y = buf->ReadByte();
1921 dtss->size_z = buf->ReadByte();
1923 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1924 /* On error, bail out immediately. Temporary GRF data was already freed */
1925 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1927 dts->Clone(tmp_layout.Begin());
1929 break;
1931 case 0x0A: { // Copy sprite layout
1932 byte srcid = buf->ReadByte();
1933 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1935 if (srcstatspec == NULL) {
1936 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1937 continue;
1940 delete[] statspec->renderdata; // delete earlier loaded stuff
1942 statspec->tiles = srcstatspec->tiles;
1943 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1944 for (uint t = 0; t < statspec->tiles; t++) {
1945 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1947 break;
1950 case 0x0B: // Callback mask
1951 statspec->callback_mask = buf->ReadByte();
1952 break;
1954 case 0x0C: // Disallowed number of platforms
1955 statspec->disallowed_platforms = buf->ReadByte();
1956 break;
1958 case 0x0D: // Disallowed platform lengths
1959 statspec->disallowed_lengths = buf->ReadByte();
1960 break;
1962 case 0x0E: // Define custom layout
1963 statspec->copied_layouts = false;
1965 while (buf->HasData()) {
1966 byte length = buf->ReadByte();
1967 byte number = buf->ReadByte();
1968 StationLayout layout;
1969 uint l, p;
1971 if (length == 0 || number == 0) break;
1973 if (length > statspec->lengths) {
1974 statspec->platforms = ReallocT(statspec->platforms, length);
1975 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1977 statspec->layouts = ReallocT(statspec->layouts, length);
1978 memset(statspec->layouts + statspec->lengths, 0,
1979 (length - statspec->lengths) * sizeof(*statspec->layouts));
1981 statspec->lengths = length;
1983 l = length - 1; // index is zero-based
1985 if (number > statspec->platforms[l]) {
1986 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1987 /* We expect NULL being 0 here, but C99 guarantees that. */
1988 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1989 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1991 statspec->platforms[l] = number;
1994 p = 0;
1995 layout = MallocT<byte>(length * number);
1996 try {
1997 for (l = 0; l < length; l++) {
1998 for (p = 0; p < number; p++) {
1999 layout[l * number + p] = buf->ReadByte();
2002 } catch (...) {
2003 free(layout);
2004 throw;
2007 l--;
2008 p--;
2009 free(statspec->layouts[l][p]);
2010 statspec->layouts[l][p] = layout;
2012 break;
2014 case 0x0F: { // Copy custom layout
2015 byte srcid = buf->ReadByte();
2016 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2018 if (srcstatspec == NULL) {
2019 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2020 continue;
2023 statspec->lengths = srcstatspec->lengths;
2024 statspec->platforms = srcstatspec->platforms;
2025 statspec->layouts = srcstatspec->layouts;
2026 statspec->copied_layouts = true;
2027 break;
2030 case 0x10: // Little/lots cargo threshold
2031 statspec->cargo_threshold = buf->ReadWord();
2032 break;
2034 case 0x11: // Pylon placement
2035 statspec->pylons = buf->ReadByte();
2036 break;
2038 case 0x12: // Cargo types for random triggers
2039 statspec->cargo_triggers = buf->ReadDWord();
2040 if (_cur.grffile->grf_version >= 7) {
2041 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2043 break;
2045 case 0x13: // General flags
2046 statspec->flags = buf->ReadByte();
2047 break;
2049 case 0x14: // Overhead wire placement
2050 statspec->wires = buf->ReadByte();
2051 break;
2053 case 0x15: // Blocked tiles
2054 statspec->blocked = buf->ReadByte();
2055 break;
2057 case 0x16: // Animation info
2058 statspec->animation.frames = buf->ReadByte();
2059 statspec->animation.status = buf->ReadByte();
2060 break;
2062 case 0x17: // Animation speed
2063 statspec->animation.speed = buf->ReadByte();
2064 break;
2066 case 0x18: // Animation triggers
2067 statspec->animation.triggers = buf->ReadWord();
2068 break;
2070 case 0x1A: // Advanced sprite layout
2071 statspec->tiles = buf->ReadExtendedByte();
2072 delete[] statspec->renderdata; // delete earlier loaded stuff
2073 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2075 for (uint t = 0; t < statspec->tiles; t++) {
2076 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2077 uint num_building_sprites = buf->ReadByte();
2078 /* On error, bail out immediately. Temporary GRF data was already freed */
2079 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2081 break;
2083 default:
2084 ret = CIR_UNKNOWN;
2085 break;
2089 return ret;
2093 * Define properties for water features
2094 * @param id Type of the first water feature.
2095 * @param numinfo Number of subsequent water feature ids to change the property for.
2096 * @param prop The property to change.
2097 * @param buf The property value.
2098 * @return ChangeInfoResult.
2100 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2102 ChangeInfoResult ret = CIR_SUCCESS;
2104 if (id + numinfo > CF_END) {
2105 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2106 return CIR_INVALID_ID;
2109 for (int i = 0; i < numinfo; i++) {
2110 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2112 switch (prop) {
2113 case 0x08:
2114 cp->callback_mask = buf->ReadByte();
2115 break;
2117 case 0x09:
2118 cp->flags = buf->ReadByte();
2119 break;
2121 default:
2122 ret = CIR_UNKNOWN;
2123 break;
2127 return ret;
2131 * Define properties for bridges
2132 * @param brid BridgeID of the bridge.
2133 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2134 * @param prop The property to change.
2135 * @param buf The property value.
2136 * @return ChangeInfoResult.
2138 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2140 ChangeInfoResult ret = CIR_SUCCESS;
2142 if (brid + numinfo > MAX_BRIDGES) {
2143 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2144 return CIR_INVALID_ID;
2147 for (int i = 0; i < numinfo; i++) {
2148 BridgeSpec *bridge = &_bridge[brid + i];
2150 switch (prop) {
2151 case 0x08: { // Year of availability
2152 /* We treat '0' as always available */
2153 byte year = buf->ReadByte();
2154 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2155 break;
2158 case 0x09: // Minimum length
2159 bridge->min_length = buf->ReadByte();
2160 break;
2162 case 0x0A: // Maximum length
2163 bridge->max_length = buf->ReadByte();
2164 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2165 break;
2167 case 0x0B: // Cost factor
2168 bridge->price = buf->ReadByte();
2169 break;
2171 case 0x0C: // Maximum speed
2172 bridge->speed = buf->ReadWord();
2173 break;
2175 case 0x0D: { // Bridge sprite tables
2176 byte tableid = buf->ReadByte();
2177 byte numtables = buf->ReadByte();
2179 if (bridge->sprite_table == NULL) {
2180 /* Allocate memory for sprite table pointers and zero out */
2181 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2184 for (; numtables-- != 0; tableid++) {
2185 if (tableid >= 7) { // skip invalid data
2186 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2187 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2188 continue;
2191 if (bridge->sprite_table[tableid] == NULL) {
2192 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2195 for (byte sprite = 0; sprite < 32; sprite++) {
2196 SpriteID image = buf->ReadWord();
2197 PaletteID pal = buf->ReadWord();
2199 bridge->sprite_table[tableid][sprite].sprite = image;
2200 bridge->sprite_table[tableid][sprite].pal = pal;
2202 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2205 break;
2208 case 0x0E: // Flags; bit 0 - disable far pillars
2209 bridge->flags = buf->ReadByte();
2210 break;
2212 case 0x0F: // Long format year of availability (year since year 0)
2213 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2214 break;
2216 case 0x10: { // purchase string
2217 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2218 if (newone != STR_UNDEFINED) bridge->material = newone;
2219 break;
2222 case 0x11: // description of bridge with rails or roads
2223 case 0x12: {
2224 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2225 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2226 break;
2229 case 0x13: // 16 bits cost multiplier
2230 bridge->price = buf->ReadWord();
2231 break;
2233 default:
2234 ret = CIR_UNKNOWN;
2235 break;
2239 return ret;
2243 * Ignore a house property
2244 * @param prop Property to read.
2245 * @param buf Property value.
2246 * @return ChangeInfoResult.
2248 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2250 ChangeInfoResult ret = CIR_SUCCESS;
2252 switch (prop) {
2253 case 0x09:
2254 case 0x0B:
2255 case 0x0C:
2256 case 0x0D:
2257 case 0x0E:
2258 case 0x0F:
2259 case 0x11:
2260 case 0x14:
2261 case 0x15:
2262 case 0x16:
2263 case 0x18:
2264 case 0x19:
2265 case 0x1A:
2266 case 0x1B:
2267 case 0x1C:
2268 case 0x1D:
2269 case 0x1F:
2270 buf->ReadByte();
2271 break;
2273 case 0x0A:
2274 case 0x10:
2275 case 0x12:
2276 case 0x13:
2277 case 0x21:
2278 case 0x22:
2279 buf->ReadWord();
2280 break;
2282 case 0x1E:
2283 buf->ReadDWord();
2284 break;
2286 case 0x17:
2287 for (uint j = 0; j < 4; j++) buf->ReadByte();
2288 break;
2290 case 0x20: {
2291 byte count = buf->ReadByte();
2292 for (byte j = 0; j < count; j++) buf->ReadByte();
2293 break;
2296 default:
2297 ret = CIR_UNKNOWN;
2298 break;
2300 return ret;
2304 * Define properties for houses
2305 * @param hid HouseID of the house.
2306 * @param numinfo Number of subsequent houseIDs to change the property for.
2307 * @param prop The property to change.
2308 * @param buf The property value.
2309 * @return ChangeInfoResult.
2311 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2313 ChangeInfoResult ret = CIR_SUCCESS;
2315 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2316 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2317 return CIR_INVALID_ID;
2320 /* Allocate house specs if they haven't been allocated already. */
2321 if (_cur.grffile->housespec == NULL) {
2322 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2325 for (int i = 0; i < numinfo; i++) {
2326 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2328 if (prop != 0x08 && housespec == NULL) {
2329 /* If the house property 08 is not yet set, ignore this property */
2330 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2331 if (cir > ret) ret = cir;
2332 continue;
2335 switch (prop) {
2336 case 0x08: { // Substitute building type, and definition of a new house
2337 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2338 byte subs_id = buf->ReadByte();
2340 if (subs_id == 0xFF) {
2341 /* Instead of defining a new house, a substitute house id
2342 * of 0xFF disables the old house with the current id. */
2343 HouseSpec::Get(hid + i)->enabled = false;
2344 continue;
2345 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2346 /* The substitute id must be one of the original houses. */
2347 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2348 continue;
2351 /* Allocate space for this house. */
2352 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2354 housespec = *house;
2356 MemCpyT(housespec, HouseSpec::Get(subs_id));
2358 housespec->enabled = true;
2359 housespec->grf_prop.local_id = hid + i;
2360 housespec->grf_prop.subst_id = subs_id;
2361 housespec->grf_prop.grffile = _cur.grffile;
2362 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2363 housespec->random_colour[1] = 0x08; // for all new houses
2364 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2365 housespec->random_colour[3] = 0x06;
2367 /* Make sure that the third cargo type is valid in this
2368 * climate. This can cause problems when copying the properties
2369 * of a house that accepts food, where the new house is valid
2370 * in the temperate climate. */
2371 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2372 housespec->cargo_acceptance[2] = 0;
2375 _loaded_newgrf_features.has_newhouses = true;
2376 break;
2379 case 0x09: // Building flags
2380 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2381 break;
2383 case 0x0A: { // Availability years
2384 uint16 years = buf->ReadWord();
2385 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2386 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2387 break;
2390 case 0x0B: // Population
2391 housespec->population = buf->ReadByte();
2392 break;
2394 case 0x0C: // Mail generation multiplier
2395 housespec->mail_generation = buf->ReadByte();
2396 break;
2398 case 0x0D: // Passenger acceptance
2399 case 0x0E: // Mail acceptance
2400 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2401 break;
2403 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2404 int8 goods = buf->ReadByte();
2406 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2407 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2408 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2409 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2411 /* Make sure the cargo type is valid in this climate. */
2412 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2414 housespec->accepts_cargo[2] = cid;
2415 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2416 break;
2419 case 0x10: // Local authority rating decrease on removal
2420 housespec->remove_rating_decrease = buf->ReadWord();
2421 break;
2423 case 0x11: // Removal cost multiplier
2424 housespec->removal_cost = buf->ReadByte();
2425 break;
2427 case 0x12: // Building name ID
2428 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2429 break;
2431 case 0x13: // Building availability mask
2432 housespec->building_availability = (HouseZones)buf->ReadWord();
2433 break;
2435 case 0x14: // House callback mask
2436 housespec->callback_mask |= buf->ReadByte();
2437 break;
2439 case 0x15: { // House override byte
2440 byte override = buf->ReadByte();
2442 /* The house being overridden must be an original house. */
2443 if (override >= NEW_HOUSE_OFFSET) {
2444 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2445 continue;
2448 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2449 break;
2452 case 0x16: // Periodic refresh multiplier
2453 housespec->processing_time = min(buf->ReadByte(), 63);
2454 break;
2456 case 0x17: // Four random colours to use
2457 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2458 break;
2460 case 0x18: // Relative probability of appearing
2461 housespec->probability = buf->ReadByte();
2462 break;
2464 case 0x19: // Extra flags
2465 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2466 break;
2468 case 0x1A: // Animation frames
2469 housespec->animation.frames = buf->ReadByte();
2470 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2471 SB(housespec->animation.frames, 7, 1, 0);
2472 break;
2474 case 0x1B: // Animation speed
2475 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2476 break;
2478 case 0x1C: // Class of the building type
2479 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2480 break;
2482 case 0x1D: // Callback mask part 2
2483 housespec->callback_mask |= (buf->ReadByte() << 8);
2484 break;
2486 case 0x1E: { // Accepted cargo types
2487 uint32 cargotypes = buf->ReadDWord();
2489 /* Check if the cargo types should not be changed */
2490 if (cargotypes == 0xFFFFFFFF) break;
2492 for (uint j = 0; j < 3; j++) {
2493 /* Get the cargo number from the 'list' */
2494 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2495 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2497 if (cargo == CT_INVALID) {
2498 /* Disable acceptance of invalid cargo type */
2499 housespec->cargo_acceptance[j] = 0;
2500 } else {
2501 housespec->accepts_cargo[j] = cargo;
2504 break;
2507 case 0x1F: // Minimum life span
2508 housespec->minimum_life = buf->ReadByte();
2509 break;
2511 case 0x20: { // Cargo acceptance watch list
2512 byte count = buf->ReadByte();
2513 for (byte j = 0; j < count; j++) {
2514 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2515 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2517 break;
2520 case 0x21: // long introduction year
2521 housespec->min_year = buf->ReadWord();
2522 break;
2524 case 0x22: // long maximum year
2525 housespec->max_year = buf->ReadWord();
2526 break;
2528 default:
2529 ret = CIR_UNKNOWN;
2530 break;
2534 return ret;
2538 * Get the language map associated with a given NewGRF and language.
2539 * @param grfid The NewGRF to get the map for.
2540 * @param language_id The (NewGRF) language ID to get the map for.
2541 * @return The LanguageMap, or NULL if it couldn't be found.
2543 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2545 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2546 const GRFFile *grffile = GetFileByGRFID(grfid);
2547 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2551 * Load a cargo- or railtype-translation table.
2552 * @param gvid ID of the global variable. This is basically only checked for zerones.
2553 * @param numinfo Number of subsequent IDs to change the property for.
2554 * @param buf The property value.
2555 * @param [in,out] translation_table Storage location for the translation table.
2556 * @param name Name of the table for debug output.
2557 * @return ChangeInfoResult.
2559 template <typename T>
2560 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2562 if (gvid != 0) {
2563 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2564 return CIR_INVALID_ID;
2567 translation_table.Clear();
2568 for (int i = 0; i < numinfo; i++) {
2569 uint32 item = buf->ReadDWord();
2570 *translation_table.Append() = BSWAP32(item);
2573 return CIR_SUCCESS;
2577 * Define properties for global variables
2578 * @param gvid ID of the global variable.
2579 * @param numinfo Number of subsequent IDs to change the property for.
2580 * @param prop The property to change.
2581 * @param buf The property value.
2582 * @return ChangeInfoResult.
2584 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2586 /* Properties which are handled as a whole */
2587 switch (prop) {
2588 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2589 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2591 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2592 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2594 default:
2595 break;
2598 /* Properties which are handled per item */
2599 ChangeInfoResult ret = CIR_SUCCESS;
2600 for (int i = 0; i < numinfo; i++) {
2601 switch (prop) {
2602 case 0x08: { // Cost base factor
2603 int factor = buf->ReadByte();
2604 uint price = gvid + i;
2606 if (price < PR_END) {
2607 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2608 } else {
2609 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2611 break;
2614 case 0x0A: { // Currency display names
2615 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2616 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2618 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2619 _currency_specs[curidx].name = newone;
2621 break;
2624 case 0x0B: { // Currency multipliers
2625 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2626 uint32 rate = buf->ReadDWord();
2628 if (curidx < CURRENCY_END) {
2629 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2630 * which OTTD does not. For this reason, divide grf value by 1000,
2631 * to be compatible */
2632 _currency_specs[curidx].rate = rate / 1000;
2633 } else {
2634 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2636 break;
2639 case 0x0C: { // Currency options
2640 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2641 uint16 options = buf->ReadWord();
2643 if (curidx < CURRENCY_END) {
2644 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2645 _currency_specs[curidx].separator[1] = '\0';
2646 /* By specifying only one bit, we prevent errors,
2647 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2648 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2649 } else {
2650 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2652 break;
2655 case 0x0D: { // Currency prefix symbol
2656 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2657 uint32 tempfix = buf->ReadDWord();
2659 if (curidx < CURRENCY_END) {
2660 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2661 _currency_specs[curidx].prefix[4] = 0;
2662 } else {
2663 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2665 break;
2668 case 0x0E: { // Currency suffix symbol
2669 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2670 uint32 tempfix = buf->ReadDWord();
2672 if (curidx < CURRENCY_END) {
2673 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2674 _currency_specs[curidx].suffix[4] = 0;
2675 } else {
2676 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2678 break;
2681 case 0x0F: { // Euro introduction dates
2682 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2683 Year year_euro = buf->ReadWord();
2685 if (curidx < CURRENCY_END) {
2686 _currency_specs[curidx].to_euro = year_euro;
2687 } else {
2688 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2690 break;
2693 case 0x10: // Snow line height table
2694 if (numinfo > 1 || IsSnowLineSet()) {
2695 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2696 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2697 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2698 } else {
2699 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2701 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2702 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2703 table[i][j] = buf->ReadByte();
2704 if (_cur.grffile->grf_version >= 8) {
2705 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2706 } else {
2707 if (table[i][j] >= 128) {
2708 /* no snow */
2709 table[i][j] = 0xFF;
2710 } else {
2711 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2716 SetSnowLine(table);
2718 break;
2720 case 0x11: // GRF match for engine allocation
2721 /* This is loaded during the reservation stage, so just skip it here. */
2722 /* Each entry is 8 bytes. */
2723 buf->Skip(8);
2724 break;
2726 case 0x13: // Gender translation table
2727 case 0x14: // Case translation table
2728 case 0x15: { // Plural form translation
2729 uint curidx = gvid + i; // The current index, i.e. language.
2730 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2731 if (lang == NULL) {
2732 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2733 /* Skip over the data. */
2734 if (prop == 0x15) {
2735 buf->ReadByte();
2736 } else {
2737 while (buf->ReadByte() != 0) {
2738 buf->ReadString();
2741 break;
2744 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2746 if (prop == 0x15) {
2747 uint plural_form = buf->ReadByte();
2748 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2749 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2750 } else {
2751 _cur.grffile->language_map[curidx].plural_form = plural_form;
2753 break;
2756 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2757 while (newgrf_id != 0) {
2758 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2760 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2761 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2762 * is just a subset of UTF8, or they need the bigger UTF8 characters
2763 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2764 WChar c;
2765 size_t len = Utf8Decode(&c, name);
2766 if (c == NFO_UTF8_IDENTIFIER) name += len;
2768 LanguageMap::Mapping map;
2769 map.newgrf_id = newgrf_id;
2770 if (prop == 0x13) {
2771 map.openttd_id = lang->GetGenderIndex(name);
2772 if (map.openttd_id >= MAX_NUM_GENDERS) {
2773 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2774 } else {
2775 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2777 } else {
2778 map.openttd_id = lang->GetCaseIndex(name);
2779 if (map.openttd_id >= MAX_NUM_CASES) {
2780 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2781 } else {
2782 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2785 newgrf_id = buf->ReadByte();
2787 break;
2790 default:
2791 ret = CIR_UNKNOWN;
2792 break;
2796 return ret;
2799 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2801 /* Properties which are handled as a whole */
2802 switch (prop) {
2803 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2804 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2806 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2807 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2809 default:
2810 break;
2813 /* Properties which are handled per item */
2814 ChangeInfoResult ret = CIR_SUCCESS;
2815 for (int i = 0; i < numinfo; i++) {
2816 switch (prop) {
2817 case 0x08: // Cost base factor
2818 case 0x15: // Plural form translation
2819 buf->ReadByte();
2820 break;
2822 case 0x0A: // Currency display names
2823 case 0x0C: // Currency options
2824 case 0x0F: // Euro introduction dates
2825 buf->ReadWord();
2826 break;
2828 case 0x0B: // Currency multipliers
2829 case 0x0D: // Currency prefix symbol
2830 case 0x0E: // Currency suffix symbol
2831 buf->ReadDWord();
2832 break;
2834 case 0x10: // Snow line height table
2835 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2836 break;
2838 case 0x11: { // GRF match for engine allocation
2839 uint32 s = buf->ReadDWord();
2840 uint32 t = buf->ReadDWord();
2841 SetNewGRFOverride(s, t);
2842 break;
2845 case 0x13: // Gender translation table
2846 case 0x14: // Case translation table
2847 while (buf->ReadByte() != 0) {
2848 buf->ReadString();
2850 break;
2852 default:
2853 ret = CIR_UNKNOWN;
2854 break;
2858 return ret;
2863 * Define properties for cargoes
2864 * @param cid Local ID of the cargo.
2865 * @param numinfo Number of subsequent IDs to change the property for.
2866 * @param prop The property to change.
2867 * @param buf The property value.
2868 * @return ChangeInfoResult.
2870 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2872 ChangeInfoResult ret = CIR_SUCCESS;
2874 if (cid + numinfo > NUM_CARGO) {
2875 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2876 return CIR_INVALID_ID;
2879 for (int i = 0; i < numinfo; i++) {
2880 CargoSpec *cs = CargoSpec::Get(cid + i);
2882 switch (prop) {
2883 case 0x08: // Bit number of cargo
2884 cs->bitnum = buf->ReadByte();
2885 if (cs->IsValid()) {
2886 cs->grffile = _cur.grffile;
2887 SetBit(_cargo_mask, cid + i);
2888 } else {
2889 ClrBit(_cargo_mask, cid + i);
2891 break;
2893 case 0x09: // String ID for cargo type name
2894 AddStringForMapping(buf->ReadWord(), &cs->name);
2895 break;
2897 case 0x0A: // String for 1 unit of cargo
2898 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2899 break;
2901 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2902 case 0x1B: // String for cargo units
2903 /* String for units of cargo. This is different in OpenTTD
2904 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2905 * Property 1B is used to set OpenTTD's behaviour. */
2906 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2907 break;
2909 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2910 case 0x1C: // String for any amount of cargo
2911 /* Strings for an amount of cargo. This is different in OpenTTD
2912 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2913 * Property 1C is used to set OpenTTD's behaviour. */
2914 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2915 break;
2917 case 0x0D: // String for two letter cargo abbreviation
2918 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2919 break;
2921 case 0x0E: // Sprite ID for cargo icon
2922 cs->sprite = buf->ReadWord();
2923 break;
2925 case 0x0F: // Weight of one unit of cargo
2926 cs->weight = buf->ReadByte();
2927 break;
2929 case 0x10: // Used for payment calculation
2930 cs->transit_days[0] = buf->ReadByte();
2931 break;
2933 case 0x11: // Used for payment calculation
2934 cs->transit_days[1] = buf->ReadByte();
2935 break;
2937 case 0x12: // Base cargo price
2938 cs->initial_payment = buf->ReadDWord();
2939 break;
2941 case 0x13: // Colour for station rating bars
2942 cs->rating_colour = buf->ReadByte();
2943 break;
2945 case 0x14: // Colour for cargo graph
2946 cs->legend_colour = buf->ReadByte();
2947 break;
2949 case 0x15: // Freight status
2950 cs->is_freight = (buf->ReadByte() != 0);
2951 break;
2953 case 0x16: // Cargo classes
2954 cs->classes = buf->ReadWord();
2955 break;
2957 case 0x17: // Cargo label
2958 cs->label = buf->ReadDWord();
2959 cs->label = BSWAP32(cs->label);
2960 break;
2962 case 0x18: { // Town growth substitute type
2963 uint8 substitute_type = buf->ReadByte();
2965 switch (substitute_type) {
2966 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2967 case 0x02: cs->town_effect = TE_MAIL; break;
2968 case 0x05: cs->town_effect = TE_GOODS; break;
2969 case 0x09: cs->town_effect = TE_WATER; break;
2970 case 0x0B: cs->town_effect = TE_FOOD; break;
2971 default:
2972 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2973 FALLTHROUGH;
2974 case 0xFF: cs->town_effect = TE_NONE; break;
2976 break;
2979 case 0x19: // Town growth coefficient
2980 cs->multipliertowngrowth = buf->ReadWord();
2981 break;
2983 case 0x1A: // Bitmask of callbacks to use
2984 cs->callback_mask = buf->ReadByte();
2985 break;
2987 case 0x1D: // Vehicle capacity muliplier
2988 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2989 break;
2991 default:
2992 ret = CIR_UNKNOWN;
2993 break;
2997 return ret;
3002 * Define properties for sound effects
3003 * @param sid Local ID of the sound.
3004 * @param numinfo Number of subsequent IDs to change the property for.
3005 * @param prop The property to change.
3006 * @param buf The property value.
3007 * @return ChangeInfoResult.
3009 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3011 ChangeInfoResult ret = CIR_SUCCESS;
3013 if (_cur.grffile->sound_offset == 0) {
3014 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3015 return CIR_INVALID_ID;
3018 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3019 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3020 return CIR_INVALID_ID;
3023 for (int i = 0; i < numinfo; i++) {
3024 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3026 switch (prop) {
3027 case 0x08: // Relative volume
3028 sound->volume = buf->ReadByte();
3029 break;
3031 case 0x09: // Priority
3032 sound->priority = buf->ReadByte();
3033 break;
3035 case 0x0A: { // Override old sound
3036 SoundID orig_sound = buf->ReadByte();
3038 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3039 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3040 } else {
3041 SoundEntry *old_sound = GetSound(orig_sound);
3043 /* Literally copy the data of the new sound over the original */
3044 *old_sound = *sound;
3046 break;
3049 default:
3050 ret = CIR_UNKNOWN;
3051 break;
3055 return ret;
3059 * Ignore an industry tile property
3060 * @param prop The property to ignore.
3061 * @param buf The property value.
3062 * @return ChangeInfoResult.
3064 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3066 ChangeInfoResult ret = CIR_SUCCESS;
3068 switch (prop) {
3069 case 0x09:
3070 case 0x0D:
3071 case 0x0E:
3072 case 0x10:
3073 case 0x11:
3074 case 0x12:
3075 buf->ReadByte();
3076 break;
3078 case 0x0A:
3079 case 0x0B:
3080 case 0x0C:
3081 case 0x0F:
3082 buf->ReadWord();
3083 break;
3085 default:
3086 ret = CIR_UNKNOWN;
3087 break;
3089 return ret;
3093 * Define properties for industry tiles
3094 * @param indtid Local ID of the industry tile.
3095 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3096 * @param prop The property to change.
3097 * @param buf The property value.
3098 * @return ChangeInfoResult.
3100 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3102 ChangeInfoResult ret = CIR_SUCCESS;
3104 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3105 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3106 return CIR_INVALID_ID;
3109 /* Allocate industry tile specs if they haven't been allocated already. */
3110 if (_cur.grffile->indtspec == NULL) {
3111 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3114 for (int i = 0; i < numinfo; i++) {
3115 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3117 if (prop != 0x08 && tsp == NULL) {
3118 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3119 if (cir > ret) ret = cir;
3120 continue;
3123 switch (prop) {
3124 case 0x08: { // Substitute industry tile type
3125 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3126 byte subs_id = buf->ReadByte();
3128 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3129 /* The substitute id must be one of the original industry tile. */
3130 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3131 continue;
3134 /* Allocate space for this industry. */
3135 if (*tilespec == NULL) {
3136 *tilespec = CallocT<IndustryTileSpec>(1);
3137 tsp = *tilespec;
3139 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3140 tsp->enabled = true;
3142 /* A copied tile should not have the animation infos copied too.
3143 * The anim_state should be left untouched, though
3144 * It is up to the author to animate them himself */
3145 tsp->anim_production = INDUSTRYTILE_NOANIM;
3146 tsp->anim_next = INDUSTRYTILE_NOANIM;
3148 tsp->grf_prop.local_id = indtid + i;
3149 tsp->grf_prop.subst_id = subs_id;
3150 tsp->grf_prop.grffile = _cur.grffile;
3151 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3153 break;
3156 case 0x09: { // Industry tile override
3157 byte ovrid = buf->ReadByte();
3159 /* The industry being overridden must be an original industry. */
3160 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3162 continue;
3165 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3166 break;
3169 case 0x0A: // Tile acceptance
3170 case 0x0B:
3171 case 0x0C: {
3172 uint16 acctp = buf->ReadWord();
3173 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3174 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3175 break;
3178 case 0x0D: // Land shape flags
3179 tsp->slopes_refused = (Slope)buf->ReadByte();
3180 break;
3182 case 0x0E: // Callback mask
3183 tsp->callback_mask = buf->ReadByte();
3184 break;
3186 case 0x0F: // Animation information
3187 tsp->animation.frames = buf->ReadByte();
3188 tsp->animation.status = buf->ReadByte();
3189 break;
3191 case 0x10: // Animation speed
3192 tsp->animation.speed = buf->ReadByte();
3193 break;
3195 case 0x11: // Triggers for callback 25
3196 tsp->animation.triggers = buf->ReadByte();
3197 break;
3199 case 0x12: // Special flags
3200 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3201 break;
3203 default:
3204 ret = CIR_UNKNOWN;
3205 break;
3209 return ret;
3213 * Ignore an industry property
3214 * @param prop The property to ignore.
3215 * @param buf The property value.
3216 * @return ChangeInfoResult.
3218 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3220 ChangeInfoResult ret = CIR_SUCCESS;
3222 switch (prop) {
3223 case 0x09:
3224 case 0x0B:
3225 case 0x0F:
3226 case 0x12:
3227 case 0x13:
3228 case 0x14:
3229 case 0x17:
3230 case 0x18:
3231 case 0x19:
3232 case 0x21:
3233 case 0x22:
3234 buf->ReadByte();
3235 break;
3237 case 0x0C:
3238 case 0x0D:
3239 case 0x0E:
3240 case 0x10:
3241 case 0x1B:
3242 case 0x1F:
3243 case 0x24:
3244 buf->ReadWord();
3245 break;
3247 case 0x11:
3248 case 0x1A:
3249 case 0x1C:
3250 case 0x1D:
3251 case 0x1E:
3252 case 0x20:
3253 case 0x23:
3254 buf->ReadDWord();
3255 break;
3257 case 0x0A: {
3258 byte num_table = buf->ReadByte();
3259 for (byte j = 0; j < num_table; j++) {
3260 for (uint k = 0;; k++) {
3261 byte x = buf->ReadByte();
3262 if (x == 0xFE && k == 0) {
3263 buf->ReadByte();
3264 buf->ReadByte();
3265 break;
3268 byte y = buf->ReadByte();
3269 if (x == 0 && y == 0x80) break;
3271 byte gfx = buf->ReadByte();
3272 if (gfx == 0xFE) buf->ReadWord();
3275 break;
3278 case 0x16:
3279 for (byte j = 0; j < 3; j++) buf->ReadByte();
3280 break;
3282 case 0x15: {
3283 byte number_of_sounds = buf->ReadByte();
3284 for (uint8 j = 0; j < number_of_sounds; j++) {
3285 buf->ReadByte();
3287 break;
3290 default:
3291 ret = CIR_UNKNOWN;
3292 break;
3294 return ret;
3298 * Validate the industry layout; e.g. to prevent duplicate tiles.
3299 * @param layout The layout to check.
3300 * @param size The size of the layout.
3301 * @return True if the layout is deemed valid.
3303 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3305 for (int i = 0; i < size - 1; i++) {
3306 for (int j = i + 1; j < size; j++) {
3307 if (layout[i].ti.x == layout[j].ti.x &&
3308 layout[i].ti.y == layout[j].ti.y) {
3309 return false;
3313 return true;
3316 /** Clean the tile table of the IndustrySpec if it's needed. */
3317 static void CleanIndustryTileTable(IndustrySpec *ind)
3319 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3320 for (int j = 0; j < ind->num_table; j++) {
3321 /* remove the individual layouts */
3322 free(ind->table[j]);
3324 /* remove the layouts pointers */
3325 free(ind->table);
3326 ind->table = NULL;
3331 * Define properties for industries
3332 * @param indid Local ID of the industry.
3333 * @param numinfo Number of subsequent industry IDs to change the property for.
3334 * @param prop The property to change.
3335 * @param buf The property value.
3336 * @return ChangeInfoResult.
3338 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3340 ChangeInfoResult ret = CIR_SUCCESS;
3342 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3343 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3344 return CIR_INVALID_ID;
3347 /* Allocate industry specs if they haven't been allocated already. */
3348 if (_cur.grffile->industryspec == NULL) {
3349 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3352 for (int i = 0; i < numinfo; i++) {
3353 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3355 if (prop != 0x08 && indsp == NULL) {
3356 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3357 if (cir > ret) ret = cir;
3358 continue;
3361 switch (prop) {
3362 case 0x08: { // Substitute industry type
3363 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3364 byte subs_id = buf->ReadByte();
3366 if (subs_id == 0xFF) {
3367 /* Instead of defining a new industry, a substitute industry id
3368 * of 0xFF disables the old industry with the current id. */
3369 _industry_specs[indid + i].enabled = false;
3370 continue;
3371 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3372 /* The substitute id must be one of the original industry. */
3373 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3374 continue;
3377 /* Allocate space for this industry.
3378 * Only need to do it once. If ever it is called again, it should not
3379 * do anything */
3380 if (*indspec == NULL) {
3381 *indspec = CallocT<IndustrySpec>(1);
3382 indsp = *indspec;
3384 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3385 indsp->enabled = true;
3386 indsp->grf_prop.local_id = indid + i;
3387 indsp->grf_prop.subst_id = subs_id;
3388 indsp->grf_prop.grffile = _cur.grffile;
3389 /* If the grf industry needs to check its surounding upon creation, it should
3390 * rely on callbacks, not on the original placement functions */
3391 indsp->check_proc = CHECK_NOTHING;
3393 break;
3396 case 0x09: { // Industry type override
3397 byte ovrid = buf->ReadByte();
3399 /* The industry being overridden must be an original industry. */
3400 if (ovrid >= NEW_INDUSTRYOFFSET) {
3401 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3402 continue;
3404 indsp->grf_prop.override = ovrid;
3405 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3406 break;
3409 case 0x0A: { // Set industry layout(s)
3410 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3411 /* We read the total size in bytes, but we can't rely on the
3412 * newgrf to provide a sane value. First assume the value is
3413 * sane but later on we make sure we enlarge the array if the
3414 * newgrf contains more data. Each tile uses either 3 or 5
3415 * bytes, so to play it safe we assume 3. */
3416 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3417 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3418 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3419 uint size;
3420 const IndustryTileTable *copy_from;
3422 try {
3423 for (byte j = 0; j < new_num_layouts; j++) {
3424 for (uint k = 0;; k++) {
3425 if (k >= def_num_tiles) {
3426 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3427 /* Size reported by newgrf was not big enough so enlarge the array. */
3428 def_num_tiles *= 2;
3429 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3432 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3434 if (itt[k].ti.x == 0xFE && k == 0) {
3435 /* This means we have to borrow the layout from an old industry */
3436 IndustryType type = buf->ReadByte(); // industry holding required layout
3437 byte laynbr = buf->ReadByte(); // layout number to borrow
3439 copy_from = _origin_industry_specs[type].table[laynbr];
3440 for (size = 1;; size++) {
3441 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3443 break;
3446 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3448 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3449 /* Not the same terminator. The one we are using is rather
3450 x = -80, y = x . So, adjust it. */
3451 itt[k].ti.x = -0x80;
3452 itt[k].ti.y = 0;
3453 itt[k].gfx = 0;
3455 size = k + 1;
3456 copy_from = itt;
3457 break;
3460 itt[k].gfx = buf->ReadByte();
3462 if (itt[k].gfx == 0xFE) {
3463 /* Use a new tile from this GRF */
3464 int local_tile_id = buf->ReadWord();
3466 /* Read the ID from the _industile_mngr. */
3467 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3469 if (tempid == INVALID_INDUSTRYTILE) {
3470 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3471 } else {
3472 /* Declared as been valid, can be used */
3473 itt[k].gfx = tempid;
3474 size = k + 1;
3475 copy_from = itt;
3477 } else if (itt[k].gfx == 0xFF) {
3478 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3479 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3481 /* When there were only 256x256 maps, TileIndex was a uint16 and
3482 * itt[k].ti was just a TileIndexDiff that was added to it.
3483 * As such negative "x" values were shifted into the "y" position.
3484 * x = -1, y = 1 -> x = 255, y = 0
3485 * Since GRF version 8 the position is interpreted as pair of independent int8.
3486 * For GRF version < 8 we need to emulate the old shifting behaviour.
3488 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3492 if (!ValidateIndustryLayout(copy_from, size)) {
3493 /* The industry layout was not valid, so skip this one. */
3494 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3495 new_num_layouts--;
3496 j--;
3497 } else {
3498 tile_table[j] = CallocT<IndustryTileTable>(size);
3499 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3502 } catch (...) {
3503 for (int i = 0; i < new_num_layouts; i++) {
3504 free(tile_table[i]);
3506 free(tile_table);
3507 free(itt);
3508 throw;
3511 /* Clean the tile table if it was already set by a previous prop A. */
3512 CleanIndustryTileTable(indsp);
3513 /* Install final layout construction in the industry spec */
3514 indsp->num_table = new_num_layouts;
3515 indsp->table = tile_table;
3516 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3517 free(itt);
3518 break;
3521 case 0x0B: // Industry production flags
3522 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3523 break;
3525 case 0x0C: // Industry closure message
3526 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3527 break;
3529 case 0x0D: // Production increase message
3530 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3531 break;
3533 case 0x0E: // Production decrease message
3534 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3535 break;
3537 case 0x0F: // Fund cost multiplier
3538 indsp->cost_multiplier = buf->ReadByte();
3539 break;
3541 case 0x10: // Production cargo types
3542 for (byte j = 0; j < 2; j++) {
3543 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3545 break;
3547 case 0x11: // Acceptance cargo types
3548 for (byte j = 0; j < 3; j++) {
3549 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3551 buf->ReadByte(); // Unnused, eat it up
3552 break;
3554 case 0x12: // Production multipliers
3555 case 0x13:
3556 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3557 break;
3559 case 0x14: // Minimal amount of cargo distributed
3560 indsp->minimal_cargo = buf->ReadByte();
3561 break;
3563 case 0x15: { // Random sound effects
3564 indsp->number_of_sounds = buf->ReadByte();
3565 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3567 try {
3568 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3569 sounds[j] = buf->ReadByte();
3571 } catch (...) {
3572 free(sounds);
3573 throw;
3576 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3577 free(indsp->random_sounds);
3579 indsp->random_sounds = sounds;
3580 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3581 break;
3584 case 0x16: // Conflicting industry types
3585 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3586 break;
3588 case 0x17: // Probability in random game
3589 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3590 break;
3592 case 0x18: // Probability during gameplay
3593 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3594 break;
3596 case 0x19: // Map colour
3597 indsp->map_colour = buf->ReadByte();
3598 break;
3600 case 0x1A: // Special industry flags to define special behavior
3601 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3602 break;
3604 case 0x1B: // New industry text ID
3605 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3606 break;
3608 case 0x1C: // Input cargo multipliers for the three input cargo types
3609 case 0x1D:
3610 case 0x1E: {
3611 uint32 multiples = buf->ReadDWord();
3612 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3613 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3614 break;
3617 case 0x1F: // Industry name
3618 AddStringForMapping(buf->ReadWord(), &indsp->name);
3619 break;
3621 case 0x20: // Prospecting success chance
3622 indsp->prospecting_chance = buf->ReadDWord();
3623 break;
3625 case 0x21: // Callback mask
3626 case 0x22: { // Callback additional mask
3627 byte aflag = buf->ReadByte();
3628 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3629 break;
3632 case 0x23: // removal cost multiplier
3633 indsp->removal_cost_multiplier = buf->ReadDWord();
3634 break;
3636 case 0x24: { // name for nearby station
3637 uint16 str = buf->ReadWord();
3638 if (str == 0) {
3639 indsp->station_name = STR_NULL;
3640 } else {
3641 AddStringForMapping(str, &indsp->station_name);
3643 break;
3646 default:
3647 ret = CIR_UNKNOWN;
3648 break;
3652 return ret;
3656 * Create a copy of the tile table so it can be freed later
3657 * without problems.
3658 * @param as The AirportSpec to copy the arrays of.
3660 static void DuplicateTileTable(AirportSpec *as)
3662 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3663 for (int i = 0; i < as->num_table; i++) {
3664 uint num_tiles = 1;
3665 const AirportTileTable *it = as->table[0];
3666 do {
3667 num_tiles++;
3668 } while ((++it)->ti.x != -0x80);
3669 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3670 MemCpyT(table_list[i], as->table[i], num_tiles);
3672 as->table = table_list;
3673 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3674 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3675 as->depot_table = depot_table;
3676 Direction *rotation = MallocT<Direction>(as->num_table);
3677 MemCpyT(rotation, as->rotation, as->num_table);
3678 as->rotation = rotation;
3682 * Define properties for airports
3683 * @param airport Local ID of the airport.
3684 * @param numinfo Number of subsequent airport IDs to change the property for.
3685 * @param prop The property to change.
3686 * @param buf The property value.
3687 * @return ChangeInfoResult.
3689 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3691 ChangeInfoResult ret = CIR_SUCCESS;
3693 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3694 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3695 return CIR_INVALID_ID;
3698 /* Allocate industry specs if they haven't been allocated already. */
3699 if (_cur.grffile->airportspec == NULL) {
3700 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3703 for (int i = 0; i < numinfo; i++) {
3704 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3706 if (as == NULL && prop != 0x08 && prop != 0x09) {
3707 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3708 return CIR_INVALID_ID;
3711 switch (prop) {
3712 case 0x08: { // Modify original airport
3713 byte subs_id = buf->ReadByte();
3715 if (subs_id == 0xFF) {
3716 /* Instead of defining a new airport, an airport id
3717 * of 0xFF disables the old airport with the current id. */
3718 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3719 continue;
3720 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3721 /* The substitute id must be one of the original airports. */
3722 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3723 continue;
3726 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3727 /* Allocate space for this airport.
3728 * Only need to do it once. If ever it is called again, it should not
3729 * do anything */
3730 if (*spec == NULL) {
3731 *spec = MallocT<AirportSpec>(1);
3732 as = *spec;
3734 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3735 as->enabled = true;
3736 as->grf_prop.local_id = airport + i;
3737 as->grf_prop.subst_id = subs_id;
3738 as->grf_prop.grffile = _cur.grffile;
3739 /* override the default airport */
3740 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3741 /* Create a copy of the original tiletable so it can be freed later. */
3742 DuplicateTileTable(as);
3744 break;
3747 case 0x0A: { // Set airport layout
3748 free(as->rotation);
3749 as->num_table = buf->ReadByte(); // Number of layaouts
3750 as->rotation = MallocT<Direction>(as->num_table);
3751 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3752 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3753 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3754 int size;
3755 const AirportTileTable *copy_from;
3756 try {
3757 for (byte j = 0; j < as->num_table; j++) {
3758 const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3759 for (int k = 0;; k++) {
3760 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3761 att[k].ti.y = buf->ReadByte();
3763 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3764 /* Not the same terminator. The one we are using is rather
3765 * x = -80, y = 0 . So, adjust it. */
3766 att[k].ti.x = -0x80;
3767 att[k].ti.y = 0;
3768 att[k].gfx = 0;
3770 size = k + 1;
3771 copy_from = att;
3772 break;
3775 att[k].gfx = buf->ReadByte();
3777 if (att[k].gfx == 0xFE) {
3778 /* Use a new tile from this GRF */
3779 int local_tile_id = buf->ReadWord();
3781 /* Read the ID from the _airporttile_mngr. */
3782 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3784 if (tempid == INVALID_AIRPORTTILE) {
3785 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3786 } else {
3787 /* Declared as been valid, can be used */
3788 att[k].gfx = tempid;
3789 size = k + 1;
3790 copy_from = att;
3792 } else if (att[k].gfx == 0xFF) {
3793 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3794 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3797 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3798 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3799 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3800 } else {
3801 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3802 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3805 tile_table[j] = CallocT<AirportTileTable>(size);
3806 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3808 /* Install final layout construction in the airport spec */
3809 as->table = tile_table;
3810 free(att);
3811 } catch (...) {
3812 for (int i = 0; i < as->num_table; i++) {
3813 free(tile_table[i]);
3815 free(tile_table);
3816 free(att);
3817 throw;
3819 break;
3822 case 0x0C:
3823 as->min_year = buf->ReadWord();
3824 as->max_year = buf->ReadWord();
3825 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3826 break;
3828 case 0x0D:
3829 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3830 break;
3832 case 0x0E:
3833 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3834 break;
3836 case 0x0F:
3837 as->noise_level = buf->ReadByte();
3838 break;
3840 case 0x10:
3841 AddStringForMapping(buf->ReadWord(), &as->name);
3842 break;
3844 case 0x11: // Maintenance cost factor
3845 as->maintenance_cost = buf->ReadWord();
3846 break;
3848 default:
3849 ret = CIR_UNKNOWN;
3850 break;
3854 return ret;
3858 * Ignore properties for objects
3859 * @param prop The property to ignore.
3860 * @param buf The property value.
3861 * @return ChangeInfoResult.
3863 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3865 ChangeInfoResult ret = CIR_SUCCESS;
3867 switch (prop) {
3868 case 0x0B:
3869 case 0x0C:
3870 case 0x0D:
3871 case 0x12:
3872 case 0x14:
3873 case 0x16:
3874 case 0x17:
3875 buf->ReadByte();
3876 break;
3878 case 0x09:
3879 case 0x0A:
3880 case 0x10:
3881 case 0x11:
3882 case 0x13:
3883 case 0x15:
3884 buf->ReadWord();
3885 break;
3887 case 0x08:
3888 case 0x0E:
3889 case 0x0F:
3890 buf->ReadDWord();
3891 break;
3893 default:
3894 ret = CIR_UNKNOWN;
3895 break;
3898 return ret;
3902 * Define properties for objects
3903 * @param id Local ID of the object.
3904 * @param numinfo Number of subsequent objectIDs to change the property for.
3905 * @param prop The property to change.
3906 * @param buf The property value.
3907 * @return ChangeInfoResult.
3909 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3911 ChangeInfoResult ret = CIR_SUCCESS;
3913 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3914 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3915 return CIR_INVALID_ID;
3918 /* Allocate object specs if they haven't been allocated already. */
3919 if (_cur.grffile->objectspec == NULL) {
3920 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3923 for (int i = 0; i < numinfo; i++) {
3924 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3926 if (prop != 0x08 && spec == NULL) {
3927 /* If the object property 08 is not yet set, ignore this property */
3928 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3929 if (cir > ret) ret = cir;
3930 continue;
3933 switch (prop) {
3934 case 0x08: { // Class ID
3935 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3937 /* Allocate space for this object. */
3938 if (*ospec == NULL) {
3939 *ospec = CallocT<ObjectSpec>(1);
3940 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3943 /* Swap classid because we read it in BE. */
3944 uint32 classid = buf->ReadDWord();
3945 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3946 (*ospec)->enabled = true;
3947 break;
3950 case 0x09: { // Class name
3951 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3952 AddStringForMapping(buf->ReadWord(), &objclass->name);
3953 break;
3956 case 0x0A: // Object name
3957 AddStringForMapping(buf->ReadWord(), &spec->name);
3958 break;
3960 case 0x0B: // Climate mask
3961 spec->climate = buf->ReadByte();
3962 break;
3964 case 0x0C: // Size
3965 spec->size = buf->ReadByte();
3966 break;
3968 case 0x0D: // Build cost multipler
3969 spec->build_cost_multiplier = buf->ReadByte();
3970 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3971 break;
3973 case 0x0E: // Introduction date
3974 spec->introduction_date = buf->ReadDWord();
3975 break;
3977 case 0x0F: // End of life
3978 spec->end_of_life_date = buf->ReadDWord();
3979 break;
3981 case 0x10: // Flags
3982 spec->flags = (ObjectFlags)buf->ReadWord();
3983 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3984 break;
3986 case 0x11: // Animation info
3987 spec->animation.frames = buf->ReadByte();
3988 spec->animation.status = buf->ReadByte();
3989 break;
3991 case 0x12: // Animation speed
3992 spec->animation.speed = buf->ReadByte();
3993 break;
3995 case 0x13: // Animation triggers
3996 spec->animation.triggers = buf->ReadWord();
3997 break;
3999 case 0x14: // Removal cost multiplier
4000 spec->clear_cost_multiplier = buf->ReadByte();
4001 break;
4003 case 0x15: // Callback mask
4004 spec->callback_mask = buf->ReadWord();
4005 break;
4007 case 0x16: // Building height
4008 spec->height = buf->ReadByte();
4009 break;
4011 case 0x17: // Views
4012 spec->views = buf->ReadByte();
4013 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4014 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4015 spec->views = 1;
4017 break;
4019 case 0x18: // Amount placed on 256^2 map on map creation
4020 spec->generate_amount = buf->ReadByte();
4021 break;
4023 default:
4024 ret = CIR_UNKNOWN;
4025 break;
4029 return ret;
4033 * Define properties for railtypes
4034 * @param id ID of the railtype.
4035 * @param numinfo Number of subsequent IDs to change the property for.
4036 * @param prop The property to change.
4037 * @param buf The property value.
4038 * @return ChangeInfoResult.
4040 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4042 ChangeInfoResult ret = CIR_SUCCESS;
4044 extern RailtypeInfo _railtypes[RAILTYPE_END];
4046 if (id + numinfo > RAILTYPE_END) {
4047 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4048 return CIR_INVALID_ID;
4051 for (int i = 0; i < numinfo; i++) {
4052 RailType rt = _cur.grffile->railtype_map[id + i];
4053 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4055 RailtypeInfo *rti = &_railtypes[rt];
4057 switch (prop) {
4058 case 0x08: // Label of rail type
4059 /* Skipped here as this is loaded during reservation stage. */
4060 buf->ReadDWord();
4061 break;
4063 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4064 uint16 str = buf->ReadWord();
4065 AddStringForMapping(str, &rti->strings.toolbar_caption);
4066 if (_cur.grffile->grf_version < 8) {
4067 AddStringForMapping(str, &rti->strings.name);
4069 break;
4072 case 0x0A: // Menu text of railtype
4073 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4074 break;
4076 case 0x0B: // Build window caption
4077 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4078 break;
4080 case 0x0C: // Autoreplace text
4081 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4082 break;
4084 case 0x0D: // New locomotive text
4085 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4086 break;
4088 case 0x0E: // Compatible railtype list
4089 case 0x0F: // Powered railtype list
4090 case 0x18: // Railtype list required for date introduction
4091 case 0x19: // Introduced railtype list
4093 /* Rail type compatibility bits are added to the existing bits
4094 * to allow multiple GRFs to modify compatibility with the
4095 * default rail types. */
4096 int n = buf->ReadByte();
4097 for (int j = 0; j != n; j++) {
4098 RailTypeLabel label = buf->ReadDWord();
4099 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4100 if (rt != INVALID_RAILTYPE) {
4101 switch (prop) {
4102 case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4103 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4104 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4105 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4109 break;
4112 case 0x10: // Rail Type flags
4113 rti->flags = (RailTypeFlags)buf->ReadByte();
4114 break;
4116 case 0x11: // Curve speed advantage
4117 rti->curve_speed = buf->ReadByte();
4118 break;
4120 case 0x12: // Station graphic
4121 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4122 break;
4124 case 0x13: // Construction cost factor
4125 rti->cost_multiplier = buf->ReadWord();
4126 break;
4128 case 0x14: // Speed limit
4129 rti->max_speed = buf->ReadWord();
4130 break;
4132 case 0x15: // Acceleration model
4133 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4134 break;
4136 case 0x16: // Map colour
4137 rti->map_colour = buf->ReadByte();
4138 break;
4140 case 0x17: // Introduction date
4141 rti->introduction_date = buf->ReadDWord();
4142 break;
4144 case 0x1A: // Sort order
4145 rti->sorting_order = buf->ReadByte();
4146 break;
4148 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4149 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4150 break;
4152 case 0x1C: // Maintenance cost factor
4153 rti->maintenance_multiplier = buf->ReadWord();
4154 break;
4156 case 0x1D: // Alternate rail type label list
4157 /* Skipped here as this is loaded during reservation stage. */
4158 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4159 break;
4161 default:
4162 ret = CIR_UNKNOWN;
4163 break;
4167 return ret;
4170 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4172 ChangeInfoResult ret = CIR_SUCCESS;
4174 extern RailtypeInfo _railtypes[RAILTYPE_END];
4176 if (id + numinfo > RAILTYPE_END) {
4177 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4178 return CIR_INVALID_ID;
4181 for (int i = 0; i < numinfo; i++) {
4182 switch (prop) {
4183 case 0x08: // Label of rail type
4185 RailTypeLabel rtl = buf->ReadDWord();
4186 rtl = BSWAP32(rtl);
4188 RailType rt = GetRailTypeByLabel(rtl, false);
4189 if (rt == INVALID_RAILTYPE) {
4190 /* Set up new rail type */
4191 rt = AllocateRailType(rtl);
4194 _cur.grffile->railtype_map[id + i] = rt;
4195 break;
4198 case 0x09: // Toolbar caption of railtype
4199 case 0x0A: // Menu text
4200 case 0x0B: // Build window caption
4201 case 0x0C: // Autoreplace text
4202 case 0x0D: // New loco
4203 case 0x13: // Construction cost
4204 case 0x14: // Speed limit
4205 case 0x1B: // Name of railtype
4206 case 0x1C: // Maintenance cost factor
4207 buf->ReadWord();
4208 break;
4210 case 0x1D: // Alternate rail type label list
4211 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4212 int n = buf->ReadByte();
4213 for (int j = 0; j != n; j++) {
4214 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4216 break;
4218 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4219 FALLTHROUGH;
4221 case 0x0E: // Compatible railtype list
4222 case 0x0F: // Powered railtype list
4223 case 0x18: // Railtype list required for date introduction
4224 case 0x19: // Introduced railtype list
4225 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4226 break;
4228 case 0x10: // Rail Type flags
4229 case 0x11: // Curve speed advantage
4230 case 0x12: // Station graphic
4231 case 0x15: // Acceleration model
4232 case 0x16: // Map colour
4233 case 0x1A: // Sort order
4234 buf->ReadByte();
4235 break;
4237 case 0x17: // Introduction date
4238 buf->ReadDWord();
4239 break;
4241 default:
4242 ret = CIR_UNKNOWN;
4243 break;
4247 return ret;
4250 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4252 ChangeInfoResult ret = CIR_SUCCESS;
4254 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4255 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4256 return CIR_INVALID_ID;
4259 /* Allocate airport tile specs if they haven't been allocated already. */
4260 if (_cur.grffile->airtspec == NULL) {
4261 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4264 for (int i = 0; i < numinfo; i++) {
4265 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4267 if (prop != 0x08 && tsp == NULL) {
4268 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4269 return CIR_INVALID_ID;
4272 switch (prop) {
4273 case 0x08: { // Substitute airport tile type
4274 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4275 byte subs_id = buf->ReadByte();
4277 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4278 /* The substitute id must be one of the original airport tiles. */
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4280 continue;
4283 /* Allocate space for this airport tile. */
4284 if (*tilespec == NULL) {
4285 *tilespec = CallocT<AirportTileSpec>(1);
4286 tsp = *tilespec;
4288 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4289 tsp->enabled = true;
4291 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4293 tsp->grf_prop.local_id = airtid + i;
4294 tsp->grf_prop.subst_id = subs_id;
4295 tsp->grf_prop.grffile = _cur.grffile;
4296 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4298 break;
4301 case 0x09: { // Airport tile override
4302 byte override = buf->ReadByte();
4304 /* The airport tile being overridden must be an original airport tile. */
4305 if (override >= NEW_AIRPORTTILE_OFFSET) {
4306 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4307 continue;
4310 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4311 break;
4314 case 0x0E: // Callback mask
4315 tsp->callback_mask = buf->ReadByte();
4316 break;
4318 case 0x0F: // Animation information
4319 tsp->animation.frames = buf->ReadByte();
4320 tsp->animation.status = buf->ReadByte();
4321 break;
4323 case 0x10: // Animation speed
4324 tsp->animation.speed = buf->ReadByte();
4325 break;
4327 case 0x11: // Animation triggers
4328 tsp->animation.triggers = buf->ReadByte();
4329 break;
4331 default:
4332 ret = CIR_UNKNOWN;
4333 break;
4337 return ret;
4340 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4342 switch (cir) {
4343 default: NOT_REACHED();
4345 case CIR_DISABLED:
4346 /* Error has already been printed; just stop parsing */
4347 return true;
4349 case CIR_SUCCESS:
4350 return false;
4352 case CIR_UNHANDLED:
4353 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4354 return false;
4356 case CIR_UNKNOWN:
4357 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4358 FALLTHROUGH;
4360 case CIR_INVALID_ID: {
4361 /* No debug message for an invalid ID, as it has already been output */
4362 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4363 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4364 return true;
4369 /* Action 0x00 */
4370 static void FeatureChangeInfo(ByteReader *buf)
4372 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4374 * B feature
4375 * B num-props how many properties to change per vehicle/station
4376 * B num-info how many vehicles/stations to change
4377 * E id ID of first vehicle/station to change, if num-info is
4378 * greater than one, this one and the following
4379 * vehicles/stations will be changed
4380 * B property what property to change, depends on the feature
4381 * V new-info new bytes of info (variable size; depends on properties) */
4383 static const VCI_Handler handler[] = {
4384 /* GSF_TRAINS */ RailVehicleChangeInfo,
4385 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4386 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4387 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4388 /* GSF_STATIONS */ StationChangeInfo,
4389 /* GSF_CANALS */ CanalChangeInfo,
4390 /* GSF_BRIDGES */ BridgeChangeInfo,
4391 /* GSF_HOUSES */ TownHouseChangeInfo,
4392 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4393 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4394 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4395 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4396 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4397 /* GSF_AIRPORTS */ AirportChangeInfo,
4398 /* GSF_SIGNALS */ NULL,
4399 /* GSF_OBJECTS */ ObjectChangeInfo,
4400 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4401 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4404 uint8 feature = buf->ReadByte();
4405 uint8 numprops = buf->ReadByte();
4406 uint numinfo = buf->ReadByte();
4407 uint engine = buf->ReadExtendedByte();
4409 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410 feature, numprops, engine, numinfo);
4412 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4413 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4414 return;
4417 /* Mark the feature as used by the grf */
4418 SetBit(_cur.grffile->grf_features, feature);
4420 while (numprops-- && buf->HasData()) {
4421 uint8 prop = buf->ReadByte();
4423 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4424 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4428 /* Action 0x00 (GLS_SAFETYSCAN) */
4429 static void SafeChangeInfo(ByteReader *buf)
4431 uint8 feature = buf->ReadByte();
4432 uint8 numprops = buf->ReadByte();
4433 uint numinfo = buf->ReadByte();
4434 buf->ReadExtendedByte(); // id
4436 if (feature == GSF_BRIDGES && numprops == 1) {
4437 uint8 prop = buf->ReadByte();
4438 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4439 * is considered safe. */
4440 if (prop == 0x0D) return;
4441 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4442 uint8 prop = buf->ReadByte();
4443 /* Engine ID Mappings are safe, if the source is static */
4444 if (prop == 0x11) {
4445 bool is_safe = true;
4446 for (uint i = 0; i < numinfo; i++) {
4447 uint32 s = buf->ReadDWord();
4448 buf->ReadDWord(); // dest
4449 const GRFConfig *grfconfig = GetGRFConfig(s);
4450 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4451 is_safe = false;
4452 break;
4455 if (is_safe) return;
4459 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4461 /* Skip remainder of GRF */
4462 _cur.skip_sprites = -1;
4465 /* Action 0x00 (GLS_RESERVE) */
4466 static void ReserveChangeInfo(ByteReader *buf)
4468 uint8 feature = buf->ReadByte();
4470 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4472 uint8 numprops = buf->ReadByte();
4473 uint8 numinfo = buf->ReadByte();
4474 uint8 index = buf->ReadExtendedByte();
4476 while (numprops-- && buf->HasData()) {
4477 uint8 prop = buf->ReadByte();
4478 ChangeInfoResult cir = CIR_SUCCESS;
4480 switch (feature) {
4481 default: NOT_REACHED();
4482 case GSF_CARGOES:
4483 cir = CargoChangeInfo(index, numinfo, prop, buf);
4484 break;
4486 case GSF_GLOBALVAR:
4487 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4488 break;
4490 case GSF_RAILTYPES:
4491 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4492 break;
4495 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4499 /* Action 0x01 */
4500 static void NewSpriteSet(ByteReader *buf)
4502 /* Basic format: <01> <feature> <num-sets> <num-ent>
4503 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4505 * B feature feature to define sprites for
4506 * 0, 1, 2, 3: veh-type, 4: train stations
4507 * E first-set first sprite set to define
4508 * B num-sets number of sprite sets (extended byte in extended format)
4509 * E num-ent how many entries per sprite set
4510 * For vehicles, this is the number of different
4511 * vehicle directions in each sprite set
4512 * Set num-dirs=8, unless your sprites are symmetric.
4513 * In that case, use num-dirs=4.
4516 uint8 feature = buf->ReadByte();
4517 uint16 num_sets = buf->ReadByte();
4518 uint16 first_set = 0;
4520 if (num_sets == 0 && buf->HasData(3)) {
4521 /* Extended Action1 format.
4522 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4523 first_set = buf->ReadExtendedByte();
4524 num_sets = buf->ReadExtendedByte();
4526 uint16 num_ents = buf->ReadExtendedByte();
4528 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4530 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4534 for (int i = 0; i < num_sets * num_ents; i++) {
4535 _cur.nfo_line++;
4536 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4540 /* Action 0x01 (SKIP) */
4541 static void SkipAct1(ByteReader *buf)
4543 buf->ReadByte();
4544 uint16 num_sets = buf->ReadByte();
4546 if (num_sets == 0 && buf->HasData(3)) {
4547 /* Extended Action1 format.
4548 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4549 buf->ReadExtendedByte(); // first_set
4550 num_sets = buf->ReadExtendedByte();
4552 uint16 num_ents = buf->ReadExtendedByte();
4554 _cur.skip_sprites = num_sets * num_ents;
4556 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4559 /* Helper function to either create a callback or link to a previously
4560 * defined spritegroup. */
4561 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4563 if (HasBit(groupid, 15)) {
4564 assert(CallbackResultSpriteGroup::CanAllocateItem());
4565 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4568 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4569 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4570 return NULL;
4573 return _cur.spritegroups[groupid];
4577 * Helper function to either create a callback or a result sprite group.
4578 * @param feature GrfSpecFeature to define spritegroup for.
4579 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4580 * @param type Type of the currently being parsed Action2. (only for debug output)
4581 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4582 * @return Created spritegroup.
4584 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4586 if (HasBit(spriteid, 15)) {
4587 assert(CallbackResultSpriteGroup::CanAllocateItem());
4588 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4591 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4592 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4593 return NULL;
4596 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4597 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4599 /* Ensure that the sprites are loeded */
4600 assert(spriteset_start + num_sprites <= _cur.spriteid);
4602 assert(ResultSpriteGroup::CanAllocateItem());
4603 return new ResultSpriteGroup(spriteset_start, num_sprites);
4606 /* Action 0x02 */
4607 static void NewSpriteGroup(ByteReader *buf)
4609 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4611 * B feature see action 1
4612 * B set-id ID of this particular definition
4613 * B type/num-entries
4614 * if 80 or greater, this is a randomized or variational
4615 * list definition, see below
4616 * otherwise it specifies a number of entries, the exact
4617 * meaning depends on the feature
4618 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4619 SpriteGroup *act_group = NULL;
4621 uint8 feature = buf->ReadByte();
4622 uint8 setid = buf->ReadByte();
4623 uint8 type = buf->ReadByte();
4625 /* Sprite Groups are created here but they are allocated from a pool, so
4626 * we do not need to delete anything if there is an exception from the
4627 * ByteReader. */
4629 switch (type) {
4630 /* Deterministic Sprite Group */
4631 case 0x81: // Self scope, byte
4632 case 0x82: // Parent scope, byte
4633 case 0x85: // Self scope, word
4634 case 0x86: // Parent scope, word
4635 case 0x89: // Self scope, dword
4636 case 0x8A: // Parent scope, dword
4638 byte varadjust;
4639 byte varsize;
4641 assert(DeterministicSpriteGroup::CanAllocateItem());
4642 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4643 act_group = group;
4644 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4646 switch (GB(type, 2, 2)) {
4647 default: NOT_REACHED();
4648 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4649 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4650 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4653 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4654 adjusts.Clear();
4656 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4657 * from the outset, so we shall have to keep reallocing. */
4658 do {
4659 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4661 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4662 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4663 adjust->variable = buf->ReadByte();
4664 if (adjust->variable == 0x7E) {
4665 /* Link subroutine group */
4666 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4667 } else {
4668 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4671 varadjust = buf->ReadByte();
4672 adjust->shift_num = GB(varadjust, 0, 5);
4673 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4674 adjust->and_mask = buf->ReadVarSize(varsize);
4676 if (adjust->type != DSGA_TYPE_NONE) {
4677 adjust->add_val = buf->ReadVarSize(varsize);
4678 adjust->divmod_val = buf->ReadVarSize(varsize);
4679 } else {
4680 adjust->add_val = 0;
4681 adjust->divmod_val = 0;
4684 /* Continue reading var adjusts while bit 5 is set. */
4685 } while (HasBit(varadjust, 5));
4687 group->num_adjusts = adjusts.Length();
4688 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4689 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4691 std::vector<DeterministicSpriteGroupRange> ranges;
4692 ranges.resize(buf->ReadByte());
4693 for (uint i = 0; i < ranges.size(); i++) {
4694 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4695 ranges[i].low = buf->ReadVarSize(varsize);
4696 ranges[i].high = buf->ReadVarSize(varsize);
4699 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4700 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
4701 /* nvar == 0 is a special case -- we turn our value into a callback result */
4702 group->calculated_result = ranges.size() == 0;
4704 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4705 std::vector<uint32> bounds;
4706 for (uint i = 0; i < ranges.size(); i++) {
4707 bounds.push_back(ranges[i].low);
4708 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4710 std::sort(bounds.begin(), bounds.end());
4711 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4713 std::vector<const SpriteGroup *> target;
4714 for (uint j = 0; j < bounds.size(); ++j) {
4715 uint32 v = bounds[j];
4716 const SpriteGroup *t = group->default_group;
4717 for (uint i = 0; i < ranges.size(); i++) {
4718 if (ranges[i].low <= v && v <= ranges[i].high) {
4719 t = ranges[i].group;
4720 break;
4723 target.push_back(t);
4725 assert(target.size() == bounds.size());
4727 std::vector<DeterministicSpriteGroupRange> optimised;
4728 for (uint j = 0; j < bounds.size(); ) {
4729 if (target[j] != group->default_group) {
4730 DeterministicSpriteGroupRange r;
4731 r.group = target[j];
4732 r.low = bounds[j];
4733 while (j < bounds.size() && target[j] == r.group) {
4734 j++;
4736 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
4737 optimised.push_back(r);
4738 } else {
4739 j++;
4743 group->num_ranges = optimised.size();
4744 if (group->num_ranges > 0) {
4745 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4746 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
4748 break;
4751 /* Randomized Sprite Group */
4752 case 0x80: // Self scope
4753 case 0x83: // Parent scope
4754 case 0x84: // Relative scope
4756 assert(RandomizedSpriteGroup::CanAllocateItem());
4757 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4758 act_group = group;
4759 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4761 if (HasBit(type, 2)) {
4762 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4763 group->count = buf->ReadByte();
4766 uint8 triggers = buf->ReadByte();
4767 group->triggers = GB(triggers, 0, 7);
4768 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4769 group->lowest_randbit = buf->ReadByte();
4770 group->num_groups = buf->ReadByte();
4771 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4773 for (uint i = 0; i < group->num_groups; i++) {
4774 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4777 break;
4780 /* Neither a variable or randomized sprite group... must be a real group */
4781 default:
4783 switch (feature) {
4784 case GSF_TRAINS:
4785 case GSF_ROADVEHICLES:
4786 case GSF_SHIPS:
4787 case GSF_AIRCRAFT:
4788 case GSF_STATIONS:
4789 case GSF_CANALS:
4790 case GSF_CARGOES:
4791 case GSF_AIRPORTS:
4792 case GSF_RAILTYPES:
4794 byte num_loaded = type;
4795 byte num_loading = buf->ReadByte();
4797 if (!_cur.HasValidSpriteSets(feature)) {
4798 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4799 return;
4802 assert(RealSpriteGroup::CanAllocateItem());
4803 RealSpriteGroup *group = new RealSpriteGroup();
4804 act_group = group;
4806 group->num_loaded = num_loaded;
4807 group->num_loading = num_loading;
4808 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4809 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4811 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4812 setid, num_loaded, num_loading);
4814 for (uint i = 0; i < num_loaded; i++) {
4815 uint16 spriteid = buf->ReadWord();
4816 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4817 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4820 for (uint i = 0; i < num_loading; i++) {
4821 uint16 spriteid = buf->ReadWord();
4822 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4823 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4826 break;
4829 case GSF_HOUSES:
4830 case GSF_AIRPORTTILES:
4831 case GSF_OBJECTS:
4832 case GSF_INDUSTRYTILES: {
4833 byte num_building_sprites = max((uint8)1, type);
4835 assert(TileLayoutSpriteGroup::CanAllocateItem());
4836 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4837 act_group = group;
4839 /* On error, bail out immediately. Temporary GRF data was already freed */
4840 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4841 break;
4844 case GSF_INDUSTRIES: {
4845 if (type > 1) {
4846 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4847 break;
4850 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4851 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4852 act_group = group;
4853 group->version = type;
4854 if (type == 0) {
4855 for (uint i = 0; i < 3; i++) {
4856 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4858 for (uint i = 0; i < 2; i++) {
4859 group->add_output[i] = buf->ReadWord(); // unsigned
4861 group->again = buf->ReadByte();
4862 } else {
4863 for (uint i = 0; i < 3; i++) {
4864 group->subtract_input[i] = buf->ReadByte();
4866 for (uint i = 0; i < 2; i++) {
4867 group->add_output[i] = buf->ReadByte();
4869 group->again = buf->ReadByte();
4871 break;
4874 /* Loading of Tile Layout and Production Callback groups would happen here */
4875 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4880 _cur.spritegroups[setid] = act_group;
4883 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4885 if (feature == GSF_OBJECTS) {
4886 switch (ctype) {
4887 case 0: return 0;
4888 case 0xFF: return CT_PURCHASE_OBJECT;
4889 default:
4890 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4891 return CT_INVALID;
4894 /* Special cargo types for purchase list and stations */
4895 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4896 if (ctype == 0xFF) return CT_PURCHASE;
4898 if (_cur.grffile->cargo_list.Length() == 0) {
4899 /* No cargo table, so use bitnum values */
4900 if (ctype >= 32) {
4901 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4902 return CT_INVALID;
4905 const CargoSpec *cs;
4906 FOR_ALL_CARGOSPECS(cs) {
4907 if (cs->bitnum == ctype) {
4908 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4909 return cs->Index();
4913 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4914 return CT_INVALID;
4917 /* Check if the cargo type is out of bounds of the cargo translation table */
4918 if (ctype >= _cur.grffile->cargo_list.Length()) {
4919 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4920 return CT_INVALID;
4923 /* Look up the cargo label from the translation table */
4924 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4925 if (cl == 0) {
4926 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4927 return CT_INVALID;
4930 ctype = GetCargoIDByLabel(cl);
4931 if (ctype == CT_INVALID) {
4932 grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
4933 return CT_INVALID;
4936 grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
4937 return ctype;
4941 static bool IsValidGroupID(uint16 groupid, const char *function)
4943 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4944 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4945 return false;
4948 return true;
4951 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4953 static EngineID *last_engines;
4954 static uint last_engines_count;
4955 bool wagover = false;
4957 /* Test for 'wagon override' flag */
4958 if (HasBit(idcount, 7)) {
4959 wagover = true;
4960 /* Strip off the flag */
4961 idcount = GB(idcount, 0, 7);
4963 if (last_engines_count == 0) {
4964 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4965 return;
4968 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4969 last_engines_count, idcount);
4970 } else {
4971 if (last_engines_count != idcount) {
4972 last_engines = ReallocT(last_engines, idcount);
4973 last_engines_count = idcount;
4977 EngineID *engines = AllocaM(EngineID, idcount);
4978 for (uint i = 0; i < idcount; i++) {
4979 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4980 if (e == NULL) {
4981 /* No engine could be allocated?!? Deal with it. Okay,
4982 * this might look bad. Also make sure this NewGRF
4983 * gets disabled, as a half loaded one is bad. */
4984 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4985 return;
4988 engines[i] = e->index;
4989 if (!wagover) last_engines[i] = engines[i];
4992 uint8 cidcount = buf->ReadByte();
4993 for (uint c = 0; c < cidcount; c++) {
4994 uint8 ctype = buf->ReadByte();
4995 uint16 groupid = buf->ReadWord();
4996 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4998 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5000 ctype = TranslateCargo(feature, ctype);
5001 if (ctype == CT_INVALID) continue;
5003 for (uint i = 0; i < idcount; i++) {
5004 EngineID engine = engines[i];
5006 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5008 if (wagover) {
5009 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5010 } else {
5011 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5016 uint16 groupid = buf->ReadWord();
5017 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5019 grfmsg(8, "-- Default group id 0x%04X", groupid);
5021 for (uint i = 0; i < idcount; i++) {
5022 EngineID engine = engines[i];
5024 if (wagover) {
5025 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5026 } else {
5027 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5028 SetEngineGRF(engine, _cur.grffile);
5034 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5036 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5037 for (uint i = 0; i < idcount; i++) {
5038 cfs[i] = (CanalFeature)buf->ReadByte();
5041 uint8 cidcount = buf->ReadByte();
5042 buf->Skip(cidcount * 3);
5044 uint16 groupid = buf->ReadWord();
5045 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5047 for (uint i = 0; i < idcount; i++) {
5048 CanalFeature cf = cfs[i];
5050 if (cf >= CF_END) {
5051 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5052 continue;
5055 _water_feature[cf].grffile = _cur.grffile;
5056 _water_feature[cf].group = _cur.spritegroups[groupid];
5061 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5063 uint8 *stations = AllocaM(uint8, idcount);
5064 for (uint i = 0; i < idcount; i++) {
5065 stations[i] = buf->ReadByte();
5068 uint8 cidcount = buf->ReadByte();
5069 for (uint c = 0; c < cidcount; c++) {
5070 uint8 ctype = buf->ReadByte();
5071 uint16 groupid = buf->ReadWord();
5072 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5074 ctype = TranslateCargo(GSF_STATIONS, ctype);
5075 if (ctype == CT_INVALID) continue;
5077 for (uint i = 0; i < idcount; i++) {
5078 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5080 if (statspec == NULL) {
5081 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5082 continue;
5085 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5089 uint16 groupid = buf->ReadWord();
5090 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5092 for (uint i = 0; i < idcount; i++) {
5093 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5095 if (statspec == NULL) {
5096 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5097 continue;
5100 if (statspec->grf_prop.grffile != NULL) {
5101 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5102 continue;
5105 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5106 statspec->grf_prop.grffile = _cur.grffile;
5107 statspec->grf_prop.local_id = stations[i];
5108 StationClass::Assign(statspec);
5113 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5115 uint8 *houses = AllocaM(uint8, idcount);
5116 for (uint i = 0; i < idcount; i++) {
5117 houses[i] = buf->ReadByte();
5120 /* Skip the cargo type section, we only care about the default group */
5121 uint8 cidcount = buf->ReadByte();
5122 buf->Skip(cidcount * 3);
5124 uint16 groupid = buf->ReadWord();
5125 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5127 if (_cur.grffile->housespec == NULL) {
5128 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5129 return;
5132 for (uint i = 0; i < idcount; i++) {
5133 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5135 if (hs == NULL) {
5136 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5137 continue;
5140 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5144 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5146 uint8 *industries = AllocaM(uint8, idcount);
5147 for (uint i = 0; i < idcount; i++) {
5148 industries[i] = buf->ReadByte();
5151 /* Skip the cargo type section, we only care about the default group */
5152 uint8 cidcount = buf->ReadByte();
5153 buf->Skip(cidcount * 3);
5155 uint16 groupid = buf->ReadWord();
5156 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5158 if (_cur.grffile->industryspec == NULL) {
5159 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5160 return;
5163 for (uint i = 0; i < idcount; i++) {
5164 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5166 if (indsp == NULL) {
5167 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5168 continue;
5171 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5175 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5177 uint8 *indtiles = AllocaM(uint8, idcount);
5178 for (uint i = 0; i < idcount; i++) {
5179 indtiles[i] = buf->ReadByte();
5182 /* Skip the cargo type section, we only care about the default group */
5183 uint8 cidcount = buf->ReadByte();
5184 buf->Skip(cidcount * 3);
5186 uint16 groupid = buf->ReadWord();
5187 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5189 if (_cur.grffile->indtspec == NULL) {
5190 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5191 return;
5194 for (uint i = 0; i < idcount; i++) {
5195 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5197 if (indtsp == NULL) {
5198 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5199 continue;
5202 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5206 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5208 CargoID *cargoes = AllocaM(CargoID, idcount);
5209 for (uint i = 0; i < idcount; i++) {
5210 cargoes[i] = buf->ReadByte();
5213 /* Skip the cargo type section, we only care about the default group */
5214 uint8 cidcount = buf->ReadByte();
5215 buf->Skip(cidcount * 3);
5217 uint16 groupid = buf->ReadWord();
5218 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5220 for (uint i = 0; i < idcount; i++) {
5221 CargoID cid = cargoes[i];
5223 if (cid >= NUM_CARGO) {
5224 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5225 continue;
5228 CargoSpec *cs = CargoSpec::Get(cid);
5229 cs->grffile = _cur.grffile;
5230 cs->group = _cur.spritegroups[groupid];
5234 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5236 if (_cur.grffile->objectspec == NULL) {
5237 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5238 return;
5241 uint8 *objects = AllocaM(uint8, idcount);
5242 for (uint i = 0; i < idcount; i++) {
5243 objects[i] = buf->ReadByte();
5246 uint8 cidcount = buf->ReadByte();
5247 for (uint c = 0; c < cidcount; c++) {
5248 uint8 ctype = buf->ReadByte();
5249 uint16 groupid = buf->ReadWord();
5250 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5252 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5253 if (ctype == CT_INVALID) continue;
5255 for (uint i = 0; i < idcount; i++) {
5256 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5258 if (spec == NULL) {
5259 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5260 continue;
5263 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5267 uint16 groupid = buf->ReadWord();
5268 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5270 for (uint i = 0; i < idcount; i++) {
5271 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5273 if (spec == NULL) {
5274 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5275 continue;
5278 if (spec->grf_prop.grffile != NULL) {
5279 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5280 continue;
5283 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5284 spec->grf_prop.grffile = _cur.grffile;
5285 spec->grf_prop.local_id = objects[i];
5289 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5291 uint8 *railtypes = AllocaM(uint8, idcount);
5292 for (uint i = 0; i < idcount; i++) {
5293 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5296 uint8 cidcount = buf->ReadByte();
5297 for (uint c = 0; c < cidcount; c++) {
5298 uint8 ctype = buf->ReadByte();
5299 uint16 groupid = buf->ReadWord();
5300 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5302 if (ctype >= RTSG_END) continue;
5304 extern RailtypeInfo _railtypes[RAILTYPE_END];
5305 for (uint i = 0; i < idcount; i++) {
5306 if (railtypes[i] != INVALID_RAILTYPE) {
5307 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5309 rti->grffile[ctype] = _cur.grffile;
5310 rti->group[ctype] = _cur.spritegroups[groupid];
5315 /* Railtypes do not use the default group. */
5316 buf->ReadWord();
5319 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5321 uint8 *airports = AllocaM(uint8, idcount);
5322 for (uint i = 0; i < idcount; i++) {
5323 airports[i] = buf->ReadByte();
5326 /* Skip the cargo type section, we only care about the default group */
5327 uint8 cidcount = buf->ReadByte();
5328 buf->Skip(cidcount * 3);
5330 uint16 groupid = buf->ReadWord();
5331 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5333 if (_cur.grffile->airportspec == NULL) {
5334 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5335 return;
5338 for (uint i = 0; i < idcount; i++) {
5339 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5341 if (as == NULL) {
5342 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5343 continue;
5346 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5350 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5352 uint8 *airptiles = AllocaM(uint8, idcount);
5353 for (uint i = 0; i < idcount; i++) {
5354 airptiles[i] = buf->ReadByte();
5357 /* Skip the cargo type section, we only care about the default group */
5358 uint8 cidcount = buf->ReadByte();
5359 buf->Skip(cidcount * 3);
5361 uint16 groupid = buf->ReadWord();
5362 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5364 if (_cur.grffile->airtspec == NULL) {
5365 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5366 return;
5369 for (uint i = 0; i < idcount; i++) {
5370 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5372 if (airtsp == NULL) {
5373 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5374 continue;
5377 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5382 /* Action 0x03 */
5383 static void FeatureMapSpriteGroup(ByteReader *buf)
5385 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5386 * id-list := [<id>] [id-list]
5387 * cargo-list := <cargo-type> <cid> [cargo-list]
5389 * B feature see action 0
5390 * B n-id bits 0-6: how many IDs this definition applies to
5391 * bit 7: if set, this is a wagon override definition (see below)
5392 * B ids the IDs for which this definition applies
5393 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5394 * can be zero, in that case the def-cid is used always
5395 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5396 * W cid cargo ID (sprite group ID) for this type of cargo
5397 * W def-cid default cargo ID (sprite group ID) */
5399 uint8 feature = buf->ReadByte();
5400 uint8 idcount = buf->ReadByte();
5402 /* If idcount is zero, this is a feature callback */
5403 if (idcount == 0) {
5404 /* Skip number of cargo ids? */
5405 buf->ReadByte();
5406 uint16 groupid = buf->ReadWord();
5407 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5409 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5411 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5412 return;
5415 /* Mark the feature as used by the grf (generic callbacks do not count) */
5416 SetBit(_cur.grffile->grf_features, feature);
5418 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5420 switch (feature) {
5421 case GSF_TRAINS:
5422 case GSF_ROADVEHICLES:
5423 case GSF_SHIPS:
5424 case GSF_AIRCRAFT:
5425 VehicleMapSpriteGroup(buf, feature, idcount);
5426 return;
5428 case GSF_CANALS:
5429 CanalMapSpriteGroup(buf, idcount);
5430 return;
5432 case GSF_STATIONS:
5433 StationMapSpriteGroup(buf, idcount);
5434 return;
5436 case GSF_HOUSES:
5437 TownHouseMapSpriteGroup(buf, idcount);
5438 return;
5440 case GSF_INDUSTRIES:
5441 IndustryMapSpriteGroup(buf, idcount);
5442 return;
5444 case GSF_INDUSTRYTILES:
5445 IndustrytileMapSpriteGroup(buf, idcount);
5446 return;
5448 case GSF_CARGOES:
5449 CargoMapSpriteGroup(buf, idcount);
5450 return;
5452 case GSF_AIRPORTS:
5453 AirportMapSpriteGroup(buf, idcount);
5454 return;
5456 case GSF_OBJECTS:
5457 ObjectMapSpriteGroup(buf, idcount);
5458 break;
5460 case GSF_RAILTYPES:
5461 RailTypeMapSpriteGroup(buf, idcount);
5462 break;
5464 case GSF_AIRPORTTILES:
5465 AirportTileMapSpriteGroup(buf, idcount);
5466 return;
5468 default:
5469 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5470 return;
5474 /* Action 0x04 */
5475 static void FeatureNewName(ByteReader *buf)
5477 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5479 * B veh-type see action 0 (as 00..07, + 0A
5480 * But IF veh-type = 48, then generic text
5481 * B language-id If bit 6 is set, This is the extended language scheme,
5482 * with up to 64 language.
5483 * Otherwise, it is a mapping where set bits have meaning
5484 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5485 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5486 * B num-veh number of vehicles which are getting a new name
5487 * B/W offset number of the first vehicle that gets a new name
5488 * Byte : ID of vehicle to change
5489 * Word : ID of string to change/add
5490 * S data new texts, each of them zero-terminated, after
5491 * which the next name begins. */
5493 bool new_scheme = _cur.grffile->grf_version >= 7;
5495 uint8 feature = buf->ReadByte();
5496 uint8 lang = buf->ReadByte();
5497 uint8 num = buf->ReadByte();
5498 bool generic = HasBit(lang, 7);
5499 uint16 id;
5500 if (generic) {
5501 id = buf->ReadWord();
5502 } else if (feature <= GSF_AIRCRAFT) {
5503 id = buf->ReadExtendedByte();
5504 } else {
5505 id = buf->ReadByte();
5508 ClrBit(lang, 7);
5510 uint16 endid = id + num;
5512 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5513 id, endid, feature, lang);
5515 for (; id < endid && buf->HasData(); id++) {
5516 const char *name = buf->ReadString();
5517 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5519 switch (feature) {
5520 case GSF_TRAINS:
5521 case GSF_ROADVEHICLES:
5522 case GSF_SHIPS:
5523 case GSF_AIRCRAFT:
5524 if (!generic) {
5525 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5526 if (e == NULL) break;
5527 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5528 e->info.string_id = string;
5529 } else {
5530 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5532 break;
5534 default:
5535 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5536 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5537 break;
5540 switch (GB(id, 8, 8)) {
5541 case 0xC4: // Station class name
5542 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5543 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5544 } else {
5545 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5546 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5548 break;
5550 case 0xC5: // Station name
5551 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5552 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5553 } else {
5554 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5556 break;
5558 case 0xC7: // Airporttile name
5559 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5560 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5561 } else {
5562 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5564 break;
5566 case 0xC9: // House name
5567 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5568 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5569 } else {
5570 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5572 break;
5574 default:
5575 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5576 break;
5578 break;
5584 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5585 * @param num The number of sprites to load.
5586 * @param offset Offset from the base.
5587 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5588 * @param name Used for error warnings.
5589 * @return The number of sprites that is going to be skipped.
5591 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5594 if (offset >= max_sprites) {
5595 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5596 uint orig_num = num;
5597 num = 0;
5598 return orig_num;
5601 if (offset + num > max_sprites) {
5602 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5603 uint orig_num = num;
5604 num = max(max_sprites - offset, 0);
5605 return orig_num - num;
5608 return 0;
5612 /** The type of action 5 type. */
5613 enum Action5BlockType {
5614 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5615 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5616 A5BLOCK_INVALID, ///< unknown/not-implemented type
5618 /** Information about a single action 5 type. */
5619 struct Action5Type {
5620 Action5BlockType block_type; ///< How is this Action5 type processed?
5621 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5622 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5623 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5624 const char *name; ///< Name for error messages.
5627 /** The information about action 5 types. */
5628 static const Action5Type _action5_types[] = {
5629 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5630 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5631 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5632 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5633 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5634 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5635 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5636 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5637 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5638 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5639 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5640 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5641 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5642 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5643 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5644 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5645 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5646 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5647 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5648 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5649 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5650 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5651 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5652 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5653 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5654 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5657 /* Action 0x05 */
5658 static void GraphicsNew(ByteReader *buf)
5660 /* <05> <graphics-type> <num-sprites> <other data...>
5662 * B graphics-type What set of graphics the sprites define.
5663 * E num-sprites How many sprites are in this set?
5664 * V other data Graphics type specific data. Currently unused. */
5665 /* TODO */
5667 uint8 type = buf->ReadByte();
5668 uint16 num = buf->ReadExtendedByte();
5669 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5670 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5672 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5673 /* Special not-TTDP-compatible case used in openttd.grf
5674 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5675 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5676 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5677 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5678 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5679 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5680 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5681 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5682 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5683 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5684 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5685 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5686 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5687 return;
5690 /* Supported type? */
5691 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5692 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5693 _cur.skip_sprites = num;
5694 return;
5697 const Action5Type *action5_type = &_action5_types[type];
5699 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5700 * except for the long version of the shore type:
5701 * Ignore offset if not allowed */
5702 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5703 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5704 offset = 0;
5707 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5708 * This does not make sense, if <offset> is allowed */
5709 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5710 grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
5711 _cur.skip_sprites = num;
5712 return;
5715 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5716 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5717 SpriteID replace = action5_type->sprite_base + offset;
5719 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5720 grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
5722 for (; num > 0; num--) {
5723 _cur.nfo_line++;
5724 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5727 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5729 _cur.skip_sprites = skip_num;
5732 /* Action 0x05 (SKIP) */
5733 static void SkipAct5(ByteReader *buf)
5735 /* Ignore type byte */
5736 buf->ReadByte();
5738 /* Skip the sprites of this action */
5739 _cur.skip_sprites = buf->ReadExtendedByte();
5741 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5745 * Reads a variable common to VarAction2 and Action7/9/D.
5747 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5748 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5750 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5751 * @param value returns the value of the variable.
5752 * @param grffile NewGRF querying the variable
5753 * @return true iff the variable is known and the value is returned in 'value'.
5755 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5757 switch (param) {
5758 case 0x00: // current date
5759 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5760 return true;
5762 case 0x01: // current year
5763 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5764 return true;
5766 case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
5767 YearMonthDay ymd;
5768 ConvertDateToYMD(_date, &ymd);
5769 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5770 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5771 return true;
5774 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5775 *value = _settings_game.game_creation.landscape;
5776 return true;
5778 case 0x06: // road traffic side, bit 4 clear=left, set=right
5779 *value = _settings_game.vehicle.road_side << 4;
5780 return true;
5782 case 0x09: // date fraction
5783 *value = _date_fract * 885;
5784 return true;
5786 case 0x0A: // animation counter
5787 *value = _tick_counter;
5788 return true;
5790 case 0x0B: { // TTDPatch version
5791 uint major = 2;
5792 uint minor = 6;
5793 uint revision = 1; // special case: 2.0.1 is 2.0.10
5794 uint build = 1382;
5795 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5796 return true;
5799 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5800 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5801 return true;
5803 case 0x0E: // Y-offset for train sprites
5804 *value = _cur.grffile->traininfo_vehicle_pitch;
5805 return true;
5807 case 0x0F: // Rail track type cost factors
5808 *value = 0;
5809 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5810 if (_settings_game.vehicle.disable_elrails) {
5811 /* skip elrail multiplier - disabled */
5812 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5813 } else {
5814 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5815 /* Skip monorail multiplier - no space in result */
5817 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5818 return true;
5820 case 0x11: // current rail tool type
5821 *value = 0; // constant fake value to avoid desync
5822 return true;
5824 case 0x12: // Game mode
5825 *value = _game_mode;
5826 return true;
5828 /* case 0x13: // Tile refresh offset to left not implemented */
5829 /* case 0x14: // Tile refresh offset to right not implemented */
5830 /* case 0x15: // Tile refresh offset upwards not implemented */
5831 /* case 0x16: // Tile refresh offset downwards not implemented */
5832 /* case 0x17: // temperate snow line not implemented */
5834 case 0x1A: // Always -1
5835 *value = UINT_MAX;
5836 return true;
5838 case 0x1B: // Display options
5839 *value = 0x3F; // constant fake value to avoid desync
5840 return true;
5842 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5843 *value = 1;
5844 return true;
5846 case 0x1E: // Miscellaneous GRF features
5847 *value = _misc_grf_features;
5849 /* Add the local flags */
5850 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5851 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5852 return true;
5854 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5856 case 0x20: { // snow line height
5857 byte snowline = GetSnowLine();
5858 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5859 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5860 } else {
5861 /* No snow */
5862 *value = 0xFF;
5864 return true;
5867 case 0x21: // OpenTTD version
5868 *value = _openttd_newgrf_version;
5869 return true;
5871 case 0x22: // difficulty level
5872 *value = SP_CUSTOM;
5873 return true;
5875 case 0x23: // long format date
5876 *value = _date;
5877 return true;
5879 case 0x24: // long format year
5880 *value = _cur_year;
5881 return true;
5883 default: return false;
5887 static uint32 GetParamVal(byte param, uint32 *cond_val)
5889 /* First handle variable common with VarAction2 */
5890 uint32 value;
5891 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5893 /* Non-common variable */
5894 switch (param) {
5895 case 0x84: { // GRF loading stage
5896 uint32 res = 0;
5898 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5899 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5900 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5901 return res;
5904 case 0x85: // TTDPatch flags, only for bit tests
5905 if (cond_val == NULL) {
5906 /* Supported in Action 0x07 and 0x09, not 0x0D */
5907 return 0;
5908 } else {
5909 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5910 *cond_val %= 0x20;
5911 return param_val;
5914 case 0x88: // GRF ID check
5915 return 0;
5917 /* case 0x99: Global ID offset not implemented */
5919 default:
5920 /* GRF Parameter */
5921 if (param < 0x80) return _cur.grffile->GetParam(param);
5923 /* In-game variable. */
5924 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5925 return UINT_MAX;
5929 /* Action 0x06 */
5930 static void CfgApply(ByteReader *buf)
5932 /* <06> <param-num> <param-size> <offset> ... <FF>
5934 * B param-num Number of parameter to substitute (First = "zero")
5935 * Ignored if that parameter was not specified in newgrf.cfg
5936 * B param-size How many bytes to replace. If larger than 4, the
5937 * bytes of the following parameter are used. In that
5938 * case, nothing is applied unless *all* parameters
5939 * were specified.
5940 * B offset Offset into data from beginning of next sprite
5941 * to place where parameter is to be stored. */
5943 /* Preload the next sprite */
5944 size_t pos = FioGetPos();
5945 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5946 uint8 type = FioReadByte();
5947 byte *preload_sprite = NULL;
5949 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5950 if (type == 0xFF) {
5951 preload_sprite = MallocT<byte>(num);
5952 FioReadBlock(preload_sprite, num);
5955 /* Reset the file position to the start of the next sprite */
5956 FioSeekTo(pos, SEEK_SET);
5958 if (type != 0xFF) {
5959 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5960 free(preload_sprite);
5961 return;
5964 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5965 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5966 if (it != _grf_line_to_action6_sprite_override.end()) {
5967 free(preload_sprite);
5968 preload_sprite = _grf_line_to_action6_sprite_override[location];
5969 } else {
5970 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5973 /* Now perform the Action 0x06 on our data. */
5975 for (;;) {
5976 uint i;
5977 uint param_num;
5978 uint param_size;
5979 uint offset;
5980 bool add_value;
5982 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5983 param_num = buf->ReadByte();
5984 if (param_num == 0xFF) break;
5986 /* Get the size of the parameter to use. If the size covers multiple
5987 * double words, sequential parameter values are used. */
5988 param_size = buf->ReadByte();
5990 /* Bit 7 of param_size indicates we should add to the original value
5991 * instead of replacing it. */
5992 add_value = HasBit(param_size, 7);
5993 param_size = GB(param_size, 0, 7);
5995 /* Where to apply the data to within the pseudo sprite data. */
5996 offset = buf->ReadExtendedByte();
5998 /* If the parameter is a GRF parameter (not an internal variable) check
5999 * if it (and all further sequential parameters) has been defined. */
6000 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6001 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6002 break;
6005 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6007 bool carry = false;
6008 for (i = 0; i < param_size && offset + i < num; i++) {
6009 uint32 value = GetParamVal(param_num + i / 4, NULL);
6010 /* Reset carry flag for each iteration of the variable (only really
6011 * matters if param_size is greater than 4) */
6012 if (i % 4 == 0) carry = false;
6014 if (add_value) {
6015 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6016 preload_sprite[offset + i] = GB(new_value, 0, 8);
6017 /* Check if the addition overflowed */
6018 carry = new_value >= 256;
6019 } else {
6020 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6027 * Disable a static NewGRF when it is influencing another (non-static)
6028 * NewGRF as this could cause desyncs.
6030 * We could just tell the NewGRF querying that the file doesn't exist,
6031 * but that might give unwanted results. Disabling the NewGRF gives the
6032 * best result as no NewGRF author can complain about that.
6033 * @param c The NewGRF to disable.
6035 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6037 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6038 error->data = stredup(_cur.grfconfig->GetName());
6041 /* Action 0x07
6042 * Action 0x09 */
6043 static void SkipIf(ByteReader *buf)
6045 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6047 * B param-num
6048 * B param-size
6049 * B condition-type
6050 * V value
6051 * B num-sprites */
6052 /* TODO: More params. More condition types. */
6053 uint32 cond_val = 0;
6054 uint32 mask = 0;
6055 bool result;
6057 uint8 param = buf->ReadByte();
6058 uint8 paramsize = buf->ReadByte();
6059 uint8 condtype = buf->ReadByte();
6061 if (condtype < 2) {
6062 /* Always 1 for bit tests, the given value should be ignored. */
6063 paramsize = 1;
6066 switch (paramsize) {
6067 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6068 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6069 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6070 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6071 default: break;
6074 if (param < 0x80 && _cur.grffile->param_end <= param) {
6075 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6076 return;
6079 uint32 param_val = GetParamVal(param, &cond_val);
6081 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6084 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6085 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6086 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6087 * So, when the condition type is one of those, the specific variable
6088 * 0x88 code is skipped, so the "general" code for the cargo
6089 * availability conditions kicks in.
6091 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6092 /* GRF ID checks */
6094 GRFConfig *c = GetGRFConfig(cond_val, mask);
6096 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6097 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6098 c = NULL;
6101 if (condtype != 10 && c == NULL) {
6102 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6103 return;
6106 switch (condtype) {
6107 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6108 case 0x06: // Is GRFID active?
6109 result = c->status == GCS_ACTIVATED;
6110 break;
6112 case 0x07: // Is GRFID non-active?
6113 result = c->status != GCS_ACTIVATED;
6114 break;
6116 case 0x08: // GRFID is not but will be active?
6117 result = c->status == GCS_INITIALISED;
6118 break;
6120 case 0x09: // GRFID is or will be active?
6121 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6122 break;
6124 case 0x0A: // GRFID is not nor will be active
6125 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6126 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6127 break;
6129 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6131 } else {
6132 /* Parameter or variable tests */
6133 switch (condtype) {
6134 case 0x00: result = !!(param_val & (1 << cond_val));
6135 break;
6136 case 0x01: result = !(param_val & (1 << cond_val));
6137 break;
6138 case 0x02: result = (param_val & mask) == cond_val;
6139 break;
6140 case 0x03: result = (param_val & mask) != cond_val;
6141 break;
6142 case 0x04: result = (param_val & mask) < cond_val;
6143 break;
6144 case 0x05: result = (param_val & mask) > cond_val;
6145 break;
6146 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6147 break;
6148 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6149 break;
6150 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6151 break;
6152 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6153 break;
6155 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6159 if (!result) {
6160 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6161 return;
6164 uint8 numsprites = buf->ReadByte();
6166 /* numsprites can be a GOTO label if it has been defined in the GRF
6167 * file. The jump will always be the first matching label that follows
6168 * the current nfo_line. If no matching label is found, the first matching
6169 * label in the file is used. */
6170 GRFLabel *choice = NULL;
6171 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6172 if (label->label != numsprites) continue;
6174 /* Remember a goto before the current line */
6175 if (choice == NULL) choice = label;
6176 /* If we find a label here, this is definitely good */
6177 if (label->nfo_line > _cur.nfo_line) {
6178 choice = label;
6179 break;
6183 if (choice != NULL) {
6184 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6185 FioSeekTo(choice->pos, SEEK_SET);
6186 _cur.nfo_line = choice->nfo_line;
6187 return;
6190 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6191 _cur.skip_sprites = numsprites;
6192 if (_cur.skip_sprites == 0) {
6193 /* Zero means there are no sprites to skip, so
6194 * we use -1 to indicate that all further
6195 * sprites should be skipped. */
6196 _cur.skip_sprites = -1;
6198 /* If an action 8 hasn't been encountered yet, disable the grf. */
6199 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6200 DisableGrf();
6206 /* Action 0x08 (GLS_FILESCAN) */
6207 static void ScanInfo(ByteReader *buf)
6209 uint8 grf_version = buf->ReadByte();
6210 uint32 grfid = buf->ReadDWord();
6211 const char *name = buf->ReadString();
6213 _cur.grfconfig->ident.grfid = grfid;
6215 if (grf_version < 2 || grf_version > 8) {
6216 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6217 DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
6220 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6221 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6223 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6225 if (buf->HasData()) {
6226 const char *info = buf->ReadString();
6227 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6230 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6231 _cur.skip_sprites = -1;
6234 /* Action 0x08 */
6235 static void GRFInfo(ByteReader *buf)
6237 /* <08> <version> <grf-id> <name> <info>
6239 * B version newgrf version, currently 06
6240 * 4*B grf-id globally unique ID of this .grf file
6241 * S name name of this .grf set
6242 * S info string describing the set, and e.g. author and copyright */
6244 uint8 version = buf->ReadByte();
6245 uint32 grfid = buf->ReadDWord();
6246 const char *name = buf->ReadString();
6248 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6249 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6250 return;
6253 if (_cur.grffile->grfid != grfid) {
6254 DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
6255 _cur.grffile->grfid = grfid;
6258 _cur.grffile->grf_version = version;
6259 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6261 /* Do swap the GRFID for displaying purposes since people expect that */
6262 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
6265 /* Action 0x0A */
6266 static void SpriteReplace(ByteReader *buf)
6268 /* <0A> <num-sets> <set1> [<set2> ...]
6269 * <set>: <num-sprites> <first-sprite>
6271 * B num-sets How many sets of sprites to replace.
6272 * Each set:
6273 * B num-sprites How many sprites are in this set
6274 * W first-sprite First sprite number to replace */
6276 uint8 num_sets = buf->ReadByte();
6278 for (uint i = 0; i < num_sets; i++) {
6279 uint8 num_sprites = buf->ReadByte();
6280 uint16 first_sprite = buf->ReadWord();
6282 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6283 i, num_sprites, first_sprite
6286 for (uint j = 0; j < num_sprites; j++) {
6287 int load_index = first_sprite + j;
6288 _cur.nfo_line++;
6289 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6291 /* Shore sprites now located at different addresses.
6292 * So detect when the old ones get replaced. */
6293 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6294 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6300 /* Action 0x0A (SKIP) */
6301 static void SkipActA(ByteReader *buf)
6303 uint8 num_sets = buf->ReadByte();
6305 for (uint i = 0; i < num_sets; i++) {
6306 /* Skip the sprites this replaces */
6307 _cur.skip_sprites += buf->ReadByte();
6308 /* But ignore where they go */
6309 buf->ReadWord();
6312 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6315 /* Action 0x0B */
6316 static void GRFLoadError(ByteReader *buf)
6318 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6320 * B severity 00: notice, contine loading grf file
6321 * 01: warning, continue loading grf file
6322 * 02: error, but continue loading grf file, and attempt
6323 * loading grf again when loading or starting next game
6324 * 03: error, abort loading and prevent loading again in
6325 * the future (only when restarting the patch)
6326 * B language-id see action 4, use 1F for built-in error messages
6327 * B message-id message to show, see below
6328 * S message for custom messages (message-id FF), text of the message
6329 * not present for built-in messages.
6330 * V data additional data for built-in (or custom) messages
6331 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6333 static const StringID msgstr[] = {
6334 STR_NEWGRF_ERROR_VERSION_NUMBER,
6335 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6336 STR_NEWGRF_ERROR_UNSET_SWITCH,
6337 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6338 STR_NEWGRF_ERROR_LOAD_BEFORE,
6339 STR_NEWGRF_ERROR_LOAD_AFTER,
6340 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6343 static const StringID sevstr[] = {
6344 STR_NEWGRF_ERROR_MSG_INFO,
6345 STR_NEWGRF_ERROR_MSG_WARNING,
6346 STR_NEWGRF_ERROR_MSG_ERROR,
6347 STR_NEWGRF_ERROR_MSG_FATAL
6350 byte severity = buf->ReadByte();
6351 byte lang = buf->ReadByte();
6352 byte message_id = buf->ReadByte();
6354 /* Skip the error if it isn't valid for the current language. */
6355 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6357 /* Skip the error until the activation stage unless bit 7 of the severity
6358 * is set. */
6359 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6360 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6361 return;
6363 ClrBit(severity, 7);
6365 if (severity >= lengthof(sevstr)) {
6366 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6367 severity = 2;
6368 } else if (severity == 3) {
6369 /* This is a fatal error, so make sure the GRF is deactivated and no
6370 * more of it gets loaded. */
6371 DisableGrf();
6373 /* Make sure we show fatal errors, instead of silly infos from before */
6374 delete _cur.grfconfig->error;
6375 _cur.grfconfig->error = NULL;
6378 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6379 grfmsg(7, "GRFLoadError: Invalid message id.");
6380 return;
6383 if (buf->Remaining() <= 1) {
6384 grfmsg(7, "GRFLoadError: No message data supplied.");
6385 return;
6388 /* For now we can only show one message per newgrf file. */
6389 if (_cur.grfconfig->error != NULL) return;
6391 GRFError *error = new GRFError(sevstr[severity]);
6393 if (message_id == 0xFF) {
6394 /* This is a custom error message. */
6395 if (buf->HasData()) {
6396 const char *message = buf->ReadString();
6398 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6399 } else {
6400 grfmsg(7, "GRFLoadError: No custom message supplied.");
6401 error->custom_message = stredup("");
6403 } else {
6404 error->message = msgstr[message_id];
6407 if (buf->HasData()) {
6408 const char *data = buf->ReadString();
6410 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6411 } else {
6412 grfmsg(7, "GRFLoadError: No message data supplied.");
6413 error->data = stredup("");
6416 /* Only two parameter numbers can be used in the string. */
6417 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6418 uint param_number = buf->ReadByte();
6419 error->param_value[i] = _cur.grffile->GetParam(param_number);
6422 _cur.grfconfig->error = error;
6425 /* Action 0x0C */
6426 static void GRFComment(ByteReader *buf)
6428 /* <0C> [<ignored...>]
6430 * V ignored Anything following the 0C is ignored */
6432 if (!buf->HasData()) return;
6434 const char *text = buf->ReadString();
6435 grfmsg(2, "GRFComment: %s", text);
6438 /* Action 0x0D (GLS_SAFETYSCAN) */
6439 static void SafeParamSet(ByteReader *buf)
6441 uint8 target = buf->ReadByte();
6443 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6444 if (target < 0x80 || target == 0x9E) return;
6446 /* GRM could be unsafe, but as here it can only happen after other GRFs
6447 * are loaded, it should be okay. If the GRF tried to use the slots it
6448 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6449 * sprites is considered safe. */
6451 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6453 /* Skip remainder of GRF */
6454 _cur.skip_sprites = -1;
6458 static uint32 GetPatchVariable(uint8 param)
6460 switch (param) {
6461 /* start year - 1920 */
6462 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6464 /* freight trains weight factor */
6465 case 0x0E: return _settings_game.vehicle.freight_trains;
6467 /* empty wagon speed increase */
6468 case 0x0F: return 0;
6470 /* plane speed factor; our patch option is reversed from TTDPatch's,
6471 * the following is good for 1x, 2x and 4x (most common?) and...
6472 * well not really for 3x. */
6473 case 0x10:
6474 switch (_settings_game.vehicle.plane_speed) {
6475 default:
6476 case 4: return 1;
6477 case 3: return 2;
6478 case 2: return 2;
6479 case 1: return 4;
6483 /* 2CC colourmap base sprite */
6484 case 0x11: return SPR_2CCMAP_BASE;
6486 /* map size: format = -MABXYSS
6487 * M : the type of map
6488 * bit 0 : set : squared map. Bit 1 is now not relevant
6489 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6490 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6491 * clear : X is the bigger edge.
6492 * A : minimum edge(log2) of the map
6493 * B : maximum edge(log2) of the map
6494 * XY : edges(log2) of each side of the map.
6495 * SS : combination of both X and Y, thus giving the size(log2) of the map
6497 case 0x13: {
6498 byte map_bits = 0;
6499 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6500 byte log_Y = MapLogY() - 6;
6501 byte max_edge = max(log_X, log_Y);
6503 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6504 SetBit(map_bits, 0);
6505 } else {
6506 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6509 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6510 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6513 /* The maximum height of the map. */
6514 case 0x14:
6515 return _settings_game.construction.max_heightlevel;
6517 /* Extra foundations base sprite */
6518 case 0x15:
6519 return SPR_SLOPES_BASE;
6521 /* Shore base sprite */
6522 case 0x16:
6523 return SPR_SHORE_BASE;
6525 default:
6526 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6527 return 0;
6532 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6534 uint start = 0;
6535 uint size = 0;
6537 if (op == 6) {
6538 /* Return GRFID of set that reserved ID */
6539 return grm[_cur.grffile->GetParam(target)];
6542 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6543 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6545 for (uint i = start; i < num_ids; i++) {
6546 if (grm[i] == 0) {
6547 size++;
6548 } else {
6549 if (op == 2 || op == 3) break;
6550 start = i + 1;
6551 size = 0;
6554 if (size == count) break;
6557 if (size == count) {
6558 /* Got the slot... */
6559 if (op == 0 || op == 3) {
6560 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6561 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6563 return start;
6566 /* Unable to allocate */
6567 if (op != 4 && op != 5) {
6568 /* Deactivate GRF */
6569 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6570 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6571 return UINT_MAX;
6574 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6575 return UINT_MAX;
6579 /** Action 0x0D: Set parameter */
6580 static void ParamSet(ByteReader *buf)
6582 /* <0D> <target> <operation> <source1> <source2> [<data>]
6584 * B target parameter number where result is stored
6585 * B operation operation to perform, see below
6586 * B source1 first source operand
6587 * B source2 second source operand
6588 * D data data to use in the calculation, not necessary
6589 * if both source1 and source2 refer to actual parameters
6591 * Operations
6592 * 00 Set parameter equal to source1
6593 * 01 Addition, source1 + source2
6594 * 02 Subtraction, source1 - source2
6595 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6596 * 04 Signed multiplication, source1 * source2 (both signed)
6597 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6598 * signed quantity; left shift if positive and right shift if
6599 * negative, source1 is unsigned)
6600 * 06 Signed bit shift, source1 by source2
6601 * (source2 like in 05, and source1 as well)
6604 uint8 target = buf->ReadByte();
6605 uint8 oper = buf->ReadByte();
6606 uint32 src1 = buf->ReadByte();
6607 uint32 src2 = buf->ReadByte();
6609 uint32 data = 0;
6610 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6612 /* You can add 80 to the operation to make it apply only if the target
6613 * is not defined yet. In this respect, a parameter is taken to be
6614 * defined if any of the following applies:
6615 * - it has been set to any value in the newgrf(w).cfg parameter list
6616 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6617 * an earlier action D */
6618 if (HasBit(oper, 7)) {
6619 if (target < 0x80 && target < _cur.grffile->param_end) {
6620 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6621 return;
6624 oper = GB(oper, 0, 7);
6627 if (src2 == 0xFE) {
6628 if (GB(data, 0, 8) == 0xFF) {
6629 if (data == 0x0000FFFF) {
6630 /* Patch variables */
6631 src1 = GetPatchVariable(src1);
6632 } else {
6633 /* GRF Resource Management */
6634 uint8 op = src1;
6635 uint8 feature = GB(data, 8, 8);
6636 uint16 count = GB(data, 16, 16);
6638 if (_cur.stage == GLS_RESERVE) {
6639 if (feature == 0x08) {
6640 /* General sprites */
6641 if (op == 0) {
6642 /* Check if the allocated sprites will fit below the original sprite limit */
6643 if (_cur.spriteid + count >= 16384) {
6644 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6645 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6646 return;
6649 /* Reserve space at the current sprite ID */
6650 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6651 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6652 _cur.spriteid += count;
6655 /* Ignore GRM result during reservation */
6656 src1 = 0;
6657 } else if (_cur.stage == GLS_ACTIVATION) {
6658 switch (feature) {
6659 case 0x00: // Trains
6660 case 0x01: // Road Vehicles
6661 case 0x02: // Ships
6662 case 0x03: // Aircraft
6663 if (!_settings_game.vehicle.dynamic_engines) {
6664 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6665 if (_cur.skip_sprites == -1) return;
6666 } else {
6667 /* GRM does not apply for dynamic engine allocation. */
6668 switch (op) {
6669 case 2:
6670 case 3:
6671 src1 = _cur.grffile->GetParam(target);
6672 break;
6674 default:
6675 src1 = 0;
6676 break;
6679 break;
6681 case 0x08: // General sprites
6682 switch (op) {
6683 case 0:
6684 /* Return space reserved during reservation stage */
6685 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6686 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6687 break;
6689 case 1:
6690 src1 = _cur.spriteid;
6691 break;
6693 default:
6694 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6695 return;
6697 break;
6699 case 0x0B: // Cargo
6700 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6701 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6702 if (_cur.skip_sprites == -1) return;
6703 break;
6705 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6707 } else {
6708 /* Ignore GRM during initialization */
6709 src1 = 0;
6712 } else {
6713 /* Read another GRF File's parameter */
6714 const GRFFile *file = GetFileByGRFID(data);
6715 GRFConfig *c = GetGRFConfig(data);
6716 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6717 /* Disable the read GRF if it is a static NewGRF. */
6718 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6719 src1 = 0;
6720 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6721 src1 = 0;
6722 } else if (src1 == 0xFE) {
6723 src1 = c->version;
6724 } else {
6725 src1 = file->GetParam(src1);
6728 } else {
6729 /* The source1 and source2 operands refer to the grf parameter number
6730 * like in action 6 and 7. In addition, they can refer to the special
6731 * variables available in action 7, or they can be FF to use the value
6732 * of <data>. If referring to parameters that are undefined, a value
6733 * of 0 is used instead. */
6734 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6735 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6738 /* TODO: You can access the parameters of another GRF file by using
6739 * source2=FE, source1=the other GRF's parameter number and data=GRF
6740 * ID. This is only valid with operation 00 (set). If the GRF ID
6741 * cannot be found, a value of 0 is used for the parameter value
6742 * instead. */
6744 uint32 res;
6745 switch (oper) {
6746 case 0x00:
6747 res = src1;
6748 break;
6750 case 0x01:
6751 res = src1 + src2;
6752 break;
6754 case 0x02:
6755 res = src1 - src2;
6756 break;
6758 case 0x03:
6759 res = src1 * src2;
6760 break;
6762 case 0x04:
6763 res = (int32)src1 * (int32)src2;
6764 break;
6766 case 0x05:
6767 if ((int32)src2 < 0) {
6768 res = src1 >> -(int32)src2;
6769 } else {
6770 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6772 break;
6774 case 0x06:
6775 if ((int32)src2 < 0) {
6776 res = (int32)src1 >> -(int32)src2;
6777 } else {
6778 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6780 break;
6782 case 0x07: // Bitwise AND
6783 res = src1 & src2;
6784 break;
6786 case 0x08: // Bitwise OR
6787 res = src1 | src2;
6788 break;
6790 case 0x09: // Unsigned division
6791 if (src2 == 0) {
6792 res = src1;
6793 } else {
6794 res = src1 / src2;
6796 break;
6798 case 0x0A: // Signed divison
6799 if (src2 == 0) {
6800 res = src1;
6801 } else {
6802 res = (int32)src1 / (int32)src2;
6804 break;
6806 case 0x0B: // Unsigned modulo
6807 if (src2 == 0) {
6808 res = src1;
6809 } else {
6810 res = src1 % src2;
6812 break;
6814 case 0x0C: // Signed modulo
6815 if (src2 == 0) {
6816 res = src1;
6817 } else {
6818 res = (int32)src1 % (int32)src2;
6820 break;
6822 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6825 switch (target) {
6826 case 0x8E: // Y-Offset for train sprites
6827 _cur.grffile->traininfo_vehicle_pitch = res;
6828 break;
6830 case 0x8F: { // Rail track type cost factors
6831 extern RailtypeInfo _railtypes[RAILTYPE_END];
6832 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6833 if (_settings_game.vehicle.disable_elrails) {
6834 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6835 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6836 } else {
6837 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6838 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6840 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6841 break;
6844 /* @todo implement */
6845 case 0x93: // Tile refresh offset to left
6846 case 0x94: // Tile refresh offset to right
6847 case 0x95: // Tile refresh offset upwards
6848 case 0x96: // Tile refresh offset downwards
6849 case 0x97: // Snow line height
6850 case 0x99: // Global ID offset
6851 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6852 break;
6854 case 0x9E: // Miscellaneous GRF features
6855 /* Set train list engine width */
6856 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6857 /* Remove the local flags from the global flags */
6858 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6860 /* Only copy safe bits for static grfs */
6861 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6862 uint32 safe_bits = 0;
6863 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6865 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6866 } else {
6867 _misc_grf_features = res;
6869 break;
6871 case 0x9F: // locale-dependent settings
6872 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6873 break;
6875 default:
6876 if (target < 0x80) {
6877 _cur.grffile->param[target] = res;
6878 /* param is zeroed by default */
6879 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6880 } else {
6881 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6883 break;
6887 /* Action 0x0E (GLS_SAFETYSCAN) */
6888 static void SafeGRFInhibit(ByteReader *buf)
6890 /* <0E> <num> <grfids...>
6892 * B num Number of GRFIDs that follow
6893 * D grfids GRFIDs of the files to deactivate */
6895 uint8 num = buf->ReadByte();
6897 for (uint i = 0; i < num; i++) {
6898 uint32 grfid = buf->ReadDWord();
6900 /* GRF is unsafe it if tries to deactivate other GRFs */
6901 if (grfid != _cur.grfconfig->ident.grfid) {
6902 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6904 /* Skip remainder of GRF */
6905 _cur.skip_sprites = -1;
6907 return;
6912 /* Action 0x0E */
6913 static void GRFInhibit(ByteReader *buf)
6915 /* <0E> <num> <grfids...>
6917 * B num Number of GRFIDs that follow
6918 * D grfids GRFIDs of the files to deactivate */
6920 uint8 num = buf->ReadByte();
6922 for (uint i = 0; i < num; i++) {
6923 uint32 grfid = buf->ReadDWord();
6924 GRFConfig *file = GetGRFConfig(grfid);
6926 /* Unset activation flag */
6927 if (file != NULL && file != _cur.grfconfig) {
6928 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6929 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6930 error->data = stredup(_cur.grfconfig->GetName());
6935 /** Action 0x0F - Define Town names */
6936 static void FeatureTownName(ByteReader *buf)
6938 /* <0F> <id> <style-name> <num-parts> <parts>
6940 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6941 * V style-name Name of the style (only for final definition)
6942 * B num-parts Number of parts in this definition
6943 * V parts The parts */
6945 uint32 grfid = _cur.grffile->grfid;
6947 GRFTownName *townname = AddGRFTownName(grfid);
6949 byte id = buf->ReadByte();
6950 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6952 if (HasBit(id, 7)) {
6953 /* Final definition */
6954 ClrBit(id, 7);
6955 bool new_scheme = _cur.grffile->grf_version >= 7;
6957 byte lang = buf->ReadByte();
6959 byte nb_gen = townname->nb_gen;
6960 do {
6961 ClrBit(lang, 7);
6963 const char *name = buf->ReadString();
6965 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6966 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6967 free(lang_name);
6969 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6971 lang = buf->ReadByte();
6972 } while (lang != 0);
6973 townname->id[nb_gen] = id;
6974 townname->nb_gen++;
6977 byte nb = buf->ReadByte();
6978 grfmsg(6, "FeatureTownName: %u parts", nb);
6980 townname->nbparts[id] = nb;
6981 townname->partlist[id] = CallocT<NamePartList>(nb);
6983 for (int i = 0; i < nb; i++) {
6984 byte nbtext = buf->ReadByte();
6985 townname->partlist[id][i].bitstart = buf->ReadByte();
6986 townname->partlist[id][i].bitcount = buf->ReadByte();
6987 townname->partlist[id][i].maxprob = 0;
6988 townname->partlist[id][i].partcount = nbtext;
6989 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6990 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);
6992 for (int j = 0; j < nbtext; j++) {
6993 byte prob = buf->ReadByte();
6995 if (HasBit(prob, 7)) {
6996 byte ref_id = buf->ReadByte();
6998 if (townname->nbparts[ref_id] == 0) {
6999 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7000 DelGRFTownName(grfid);
7001 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7002 return;
7005 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7006 townname->partlist[id][i].parts[j].data.id = ref_id;
7007 } else {
7008 const char *text = buf->ReadString();
7009 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7010 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7012 townname->partlist[id][i].parts[j].prob = prob;
7013 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7015 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7019 /** Action 0x10 - Define goto label */
7020 static void DefineGotoLabel(ByteReader *buf)
7022 /* <10> <label> [<comment>]
7024 * B label The label to define
7025 * V comment Optional comment - ignored */
7027 byte nfo_label = buf->ReadByte();
7029 GRFLabel *label = MallocT<GRFLabel>(1);
7030 label->label = nfo_label;
7031 label->nfo_line = _cur.nfo_line;
7032 label->pos = FioGetPos();
7033 label->next = NULL;
7035 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7036 if (_cur.grffile->label == NULL) {
7037 _cur.grffile->label = label;
7038 } else {
7039 /* Attach the label to the end of the list */
7040 GRFLabel *l;
7041 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7042 l->next = label;
7045 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7049 * Process a sound import from another GRF file.
7050 * @param sound Destination for sound.
7052 static void ImportGRFSound(SoundEntry *sound)
7054 const GRFFile *file;
7055 uint32 grfid = FioReadDword();
7056 SoundID sound_id = FioReadWord();
7058 file = GetFileByGRFID(grfid);
7059 if (file == NULL || file->sound_offset == 0) {
7060 grfmsg(1, "ImportGRFSound: Source file not available");
7061 return;
7064 if (sound_id >= file->num_sounds) {
7065 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7066 return;
7069 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7071 *sound = *GetSound(file->sound_offset + sound_id);
7073 /* Reset volume and priority, which TTDPatch doesn't copy */
7074 sound->volume = 128;
7075 sound->priority = 0;
7079 * Load a sound from a file.
7080 * @param offs File offset to read sound from.
7081 * @param sound Destination for sound.
7083 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7085 /* Set default volume and priority */
7086 sound->volume = 0x80;
7087 sound->priority = 0;
7089 if (offs != SIZE_MAX) {
7090 /* Sound is present in the NewGRF. */
7091 sound->file_slot = _cur.file_index;
7092 sound->file_offset = offs;
7093 sound->grf_container_ver = _cur.grf_container_ver;
7097 /* Action 0x11 */
7098 static void GRFSound(ByteReader *buf)
7100 /* <11> <num>
7102 * W num Number of sound files that follow */
7104 uint16 num = buf->ReadWord();
7105 if (num == 0) return;
7107 SoundEntry *sound;
7108 if (_cur.grffile->sound_offset == 0) {
7109 _cur.grffile->sound_offset = GetNumSounds();
7110 _cur.grffile->num_sounds = num;
7111 sound = AllocateSound(num);
7112 } else {
7113 sound = GetSound(_cur.grffile->sound_offset);
7116 for (int i = 0; i < num; i++) {
7117 _cur.nfo_line++;
7119 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7120 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7121 bool invalid = i >= _cur.grffile->num_sounds;
7123 size_t offs = FioGetPos();
7125 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7126 byte type = FioReadByte();
7128 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7129 /* Reference to sprite section. */
7130 if (invalid) {
7131 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7132 FioSkipBytes(len);
7133 } else if (len != 4) {
7134 grfmsg(1, "GRFSound: Invalid sprite section import");
7135 FioSkipBytes(len);
7136 } else {
7137 uint32 id = FioReadDword();
7138 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7140 continue;
7143 if (type != 0xFF) {
7144 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7145 FioSkipBytes(7);
7146 SkipSpriteData(type, len - 8);
7147 continue;
7150 if (invalid) {
7151 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7152 FioSkipBytes(len);
7155 byte action = FioReadByte();
7156 switch (action) {
7157 case 0xFF:
7158 /* Allocate sound only in init stage. */
7159 if (_cur.stage == GLS_INIT) {
7160 if (_cur.grf_container_ver >= 2) {
7161 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7162 } else {
7163 LoadGRFSound(offs, sound + i);
7166 FioSkipBytes(len - 1); // already read <action>
7167 break;
7169 case 0xFE:
7170 if (_cur.stage == GLS_ACTIVATION) {
7171 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7172 * importing sounds, so this is probably all wrong... */
7173 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7174 ImportGRFSound(sound + i);
7175 } else {
7176 FioSkipBytes(len - 1); // already read <action>
7178 break;
7180 default:
7181 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7182 FioSkipBytes(len - 1); // already read <action>
7183 break;
7188 /* Action 0x11 (SKIP) */
7189 static void SkipAct11(ByteReader *buf)
7191 /* <11> <num>
7193 * W num Number of sound files that follow */
7195 _cur.skip_sprites = buf->ReadWord();
7197 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7200 /** Action 0x12 */
7201 static void LoadFontGlyph(ByteReader *buf)
7203 /* <12> <num_def> <font_size> <num_char> <base_char>
7205 * B num_def Number of definitions
7206 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7207 * B num_char Number of consecutive glyphs
7208 * W base_char First character index */
7210 uint8 num_def = buf->ReadByte();
7212 for (uint i = 0; i < num_def; i++) {
7213 FontSize size = (FontSize)buf->ReadByte();
7214 uint8 num_char = buf->ReadByte();
7215 uint16 base_char = buf->ReadWord();
7217 if (size >= FS_END) {
7218 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7221 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7223 for (uint c = 0; c < num_char; c++) {
7224 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7225 _cur.nfo_line++;
7226 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7231 /** Action 0x12 (SKIP) */
7232 static void SkipAct12(ByteReader *buf)
7234 /* <12> <num_def> <font_size> <num_char> <base_char>
7236 * B num_def Number of definitions
7237 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7238 * B num_char Number of consecutive glyphs
7239 * W base_char First character index */
7241 uint8 num_def = buf->ReadByte();
7243 for (uint i = 0; i < num_def; i++) {
7244 /* Ignore 'size' byte */
7245 buf->ReadByte();
7247 /* Sum up number of characters */
7248 _cur.skip_sprites += buf->ReadByte();
7250 /* Ignore 'base_char' word */
7251 buf->ReadWord();
7254 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7257 /** Action 0x13 */
7258 static void TranslateGRFStrings(ByteReader *buf)
7260 /* <13> <grfid> <num-ent> <offset> <text...>
7262 * 4*B grfid The GRFID of the file whose texts are to be translated
7263 * B num-ent Number of strings
7264 * W offset First text ID
7265 * S text... Zero-terminated strings */
7267 uint32 grfid = buf->ReadDWord();
7268 const GRFConfig *c = GetGRFConfig(grfid);
7269 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7270 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7271 return;
7274 if (c->status == GCS_INITIALISED) {
7275 /* If the file is not active but will be activated later, give an error
7276 * and disable this file. */
7277 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7279 char tmp[256];
7280 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7281 error->data = stredup(tmp);
7283 return;
7286 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7287 * to be added as a generic string, thus the language id of 0x7F. For this to work
7288 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7289 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7290 * not change anything if a string has been provided specifically for this language. */
7291 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7292 byte num_strings = buf->ReadByte();
7293 uint16 first_id = buf->ReadWord();
7295 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7296 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7297 return;
7300 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7301 const char *string = buf->ReadString();
7303 if (StrEmpty(string)) {
7304 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7305 continue;
7308 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7312 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7313 static bool ChangeGRFName(byte langid, const char *str)
7315 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7316 return true;
7319 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7320 static bool ChangeGRFDescription(byte langid, const char *str)
7322 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7323 return true;
7326 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7327 static bool ChangeGRFURL(byte langid, const char *str)
7329 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7330 return true;
7333 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7334 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7336 if (len != 1) {
7337 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7338 buf->Skip(len);
7339 } else {
7340 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7342 return true;
7345 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7346 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7348 if (len != 1) {
7349 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7350 buf->Skip(len);
7351 } else {
7352 char data = buf->ReadByte();
7353 GRFPalette pal = GRFP_GRF_UNSET;
7354 switch (data) {
7355 case '*':
7356 case 'A': pal = GRFP_GRF_ANY; break;
7357 case 'W': pal = GRFP_GRF_WINDOWS; break;
7358 case 'D': pal = GRFP_GRF_DOS; break;
7359 default:
7360 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7361 break;
7363 if (pal != GRFP_GRF_UNSET) {
7364 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7365 _cur.grfconfig->palette |= pal;
7368 return true;
7371 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7372 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7374 if (len != 1) {
7375 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7376 buf->Skip(len);
7377 } else {
7378 char data = buf->ReadByte();
7379 GRFPalette pal = GRFP_BLT_UNSET;
7380 switch (data) {
7381 case '8': pal = GRFP_BLT_UNSET; break;
7382 case '3': pal = GRFP_BLT_32BPP; break;
7383 default:
7384 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7385 return true;
7387 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7388 _cur.grfconfig->palette |= pal;
7390 return true;
7393 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7394 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7396 if (len != 4) {
7397 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7398 buf->Skip(len);
7399 } else {
7400 /* Set min_loadable_version as well (default to minimal compatibility) */
7401 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7403 return true;
7406 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7407 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7409 if (len != 4) {
7410 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7411 buf->Skip(len);
7412 } else {
7413 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7414 if (_cur.grfconfig->version == 0) {
7415 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7416 _cur.grfconfig->min_loadable_version = 0;
7418 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7419 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7420 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7423 return true;
7426 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7428 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7429 static bool ChangeGRFParamName(byte langid, const char *str)
7431 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7432 return true;
7435 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7436 static bool ChangeGRFParamDescription(byte langid, const char *str)
7438 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7439 return true;
7442 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7443 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7445 if (len != 1) {
7446 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7447 buf->Skip(len);
7448 } else {
7449 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7450 if (type < PTYPE_END) {
7451 _cur_parameter->type = type;
7452 } else {
7453 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7456 return true;
7459 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7460 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7462 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7463 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7464 buf->Skip(len);
7465 } else if (len != 8) {
7466 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7467 buf->Skip(len);
7468 } else {
7469 _cur_parameter->min_value = buf->ReadDWord();
7470 _cur_parameter->max_value = buf->ReadDWord();
7472 return true;
7475 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7476 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7478 if (len < 1 || len > 3) {
7479 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7480 buf->Skip(len);
7481 } else {
7482 byte param_nr = buf->ReadByte();
7483 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7484 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7485 buf->Skip(len - 1);
7486 } else {
7487 _cur_parameter->param_nr = param_nr;
7488 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7489 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7493 return true;
7496 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7497 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7499 if (len != 4) {
7500 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7501 buf->Skip(len);
7502 } else {
7503 _cur_parameter->def_value = buf->ReadDWord();
7505 _cur.grfconfig->has_param_defaults = true;
7506 return true;
7509 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7510 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7511 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7514 * Data structure to store the allowed id/type combinations for action 14. The
7515 * data can be represented as a tree with 3 types of nodes:
7516 * 1. Branch nodes (identified by 'C' for choice).
7517 * 2. Binary leaf nodes (identified by 'B').
7518 * 3. Text leaf nodes (identified by 'T').
7520 struct AllowedSubtags {
7521 /** Create empty subtags object used to identify the end of a list. */
7522 AllowedSubtags() :
7523 id(0),
7524 type(0)
7528 * Create a binary leaf node.
7529 * @param id The id for this node.
7530 * @param handler The callback function to call.
7532 AllowedSubtags(uint32 id, DataHandler handler) :
7533 id(id),
7534 type('B')
7536 this->handler.data = handler;
7540 * Create a text leaf node.
7541 * @param id The id for this node.
7542 * @param handler The callback function to call.
7544 AllowedSubtags(uint32 id, TextHandler handler) :
7545 id(id),
7546 type('T')
7548 this->handler.text = handler;
7552 * Create a branch node with a callback handler
7553 * @param id The id for this node.
7554 * @param handler The callback function to call.
7556 AllowedSubtags(uint32 id, BranchHandler handler) :
7557 id(id),
7558 type('C')
7560 this->handler.call_handler = true;
7561 this->handler.u.branch = handler;
7565 * Create a branch node with a list of sub-nodes.
7566 * @param id The id for this node.
7567 * @param subtags Array with all valid subtags.
7569 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7570 id(id),
7571 type('C')
7573 this->handler.call_handler = false;
7574 this->handler.u.subtags = subtags;
7577 uint32 id; ///< The identifier for this node
7578 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7579 union {
7580 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7581 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7582 struct {
7583 union {
7584 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7585 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7586 } u;
7587 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7589 } handler;
7592 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7593 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7596 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7597 * of some parameter values (type uint/enum) or the names of some bits
7598 * (type bitmask). In both cases the format is the same:
7599 * Each subnode should be a text node with the value/bit number as id.
7601 static bool ChangeGRFParamValueNames(ByteReader *buf)
7603 byte type = buf->ReadByte();
7604 while (type != 0) {
7605 uint32 id = buf->ReadDWord();
7606 if (type != 'T' || id > _cur_parameter->max_value) {
7607 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7608 if (!SkipUnknownInfo(buf, type)) return false;
7609 type = buf->ReadByte();
7610 continue;
7613 byte langid = buf->ReadByte();
7614 const char *name_string = buf->ReadString();
7616 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7617 if (val_name != _cur_parameter->value_names.End()) {
7618 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7619 } else {
7620 GRFText *list = NULL;
7621 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7622 _cur_parameter->value_names.Insert(id, list);
7625 type = buf->ReadByte();
7627 return true;
7630 /** Action14 parameter tags */
7631 AllowedSubtags _tags_parameters[] = {
7632 AllowedSubtags('NAME', ChangeGRFParamName),
7633 AllowedSubtags('DESC', ChangeGRFParamDescription),
7634 AllowedSubtags('TYPE', ChangeGRFParamType),
7635 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7636 AllowedSubtags('MASK', ChangeGRFParamMask),
7637 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7638 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7639 AllowedSubtags()
7643 * Callback function for 'INFO'->'PARA' to set extra information about the
7644 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7645 * the parameter number as id. The first parameter has id 0. The maximum
7646 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7648 static bool HandleParameterInfo(ByteReader *buf)
7650 byte type = buf->ReadByte();
7651 while (type != 0) {
7652 uint32 id = buf->ReadDWord();
7653 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7654 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7655 if (!SkipUnknownInfo(buf, type)) return false;
7656 type = buf->ReadByte();
7657 continue;
7660 if (id >= _cur.grfconfig->param_info.Length()) {
7661 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7662 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7663 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7665 if (_cur.grfconfig->param_info[id] == NULL) {
7666 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7668 _cur_parameter = _cur.grfconfig->param_info[id];
7669 /* Read all parameter-data and process each node. */
7670 if (!HandleNodes(buf, _tags_parameters)) return false;
7671 type = buf->ReadByte();
7673 return true;
7676 /** Action14 tags for the INFO node */
7677 AllowedSubtags _tags_info[] = {
7678 AllowedSubtags('NAME', ChangeGRFName),
7679 AllowedSubtags('DESC', ChangeGRFDescription),
7680 AllowedSubtags('URL_', ChangeGRFURL),
7681 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7682 AllowedSubtags('PALS', ChangeGRFPalette),
7683 AllowedSubtags('BLTR', ChangeGRFBlitter),
7684 AllowedSubtags('VRSN', ChangeGRFVersion),
7685 AllowedSubtags('MINV', ChangeGRFMinVersion),
7686 AllowedSubtags('PARA', HandleParameterInfo),
7687 AllowedSubtags()
7690 /** Action14 root tags */
7691 AllowedSubtags _tags_root[] = {
7692 AllowedSubtags('INFO', _tags_info),
7693 AllowedSubtags()
7698 * Try to skip the current node and all subnodes (if it's a branch node).
7699 * @param buf Buffer.
7700 * @param type The node type to skip.
7701 * @return True if we could skip the node, false if an error occurred.
7703 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7705 /* type and id are already read */
7706 switch (type) {
7707 case 'C': {
7708 byte new_type = buf->ReadByte();
7709 while (new_type != 0) {
7710 buf->ReadDWord(); // skip the id
7711 if (!SkipUnknownInfo(buf, new_type)) return false;
7712 new_type = buf->ReadByte();
7714 break;
7717 case 'T':
7718 buf->ReadByte(); // lang
7719 buf->ReadString(); // actual text
7720 break;
7722 case 'B': {
7723 uint16 size = buf->ReadWord();
7724 buf->Skip(size);
7725 break;
7728 default:
7729 return false;
7732 return true;
7736 * Handle the nodes of an Action14
7737 * @param type Type of node.
7738 * @param id ID.
7739 * @param buf Buffer.
7740 * @param subtags Allowed subtags.
7741 * @return Whether all tags could be handled.
7743 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7745 uint i = 0;
7746 AllowedSubtags *tag;
7747 while ((tag = &subtags[i++])->type != 0) {
7748 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7749 switch (type) {
7750 default: NOT_REACHED();
7752 case 'T': {
7753 byte langid = buf->ReadByte();
7754 return tag->handler.text(langid, buf->ReadString());
7757 case 'B': {
7758 size_t len = buf->ReadWord();
7759 if (buf->Remaining() < len) return false;
7760 return tag->handler.data(len, buf);
7763 case 'C': {
7764 if (tag->handler.call_handler) {
7765 return tag->handler.u.branch(buf);
7767 return HandleNodes(buf, tag->handler.u.subtags);
7771 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7772 return SkipUnknownInfo(buf, type);
7776 * Handle the contents of a 'C' choice of an Action14
7777 * @param buf Buffer.
7778 * @param subtags List of subtags.
7779 * @return Whether the nodes could all be handled.
7781 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7783 byte type = buf->ReadByte();
7784 while (type != 0) {
7785 uint32 id = buf->ReadDWord();
7786 if (!HandleNode(type, id, buf, subtags)) return false;
7787 type = buf->ReadByte();
7789 return true;
7793 * Handle Action 0x14
7794 * @param buf Buffer.
7796 static void StaticGRFInfo(ByteReader *buf)
7798 /* <14> <type> <id> <text/data...> */
7799 HandleNodes(buf, _tags_root);
7803 * Set the current NewGRF as unsafe for static use
7804 * @param buf Unused.
7805 * @note Used during safety scan on unsafe actions.
7807 static void GRFUnsafe(ByteReader *buf)
7809 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7811 /* Skip remainder of GRF */
7812 _cur.skip_sprites = -1;
7816 /** Initialize the TTDPatch flags */
7817 static void InitializeGRFSpecial()
7819 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7820 | (1 << 0x0D) // newairports
7821 | (1 << 0x0E) // largestations
7822 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7823 | (0 << 0x10) // loadtime
7824 | (1 << 0x12) // presignals
7825 | (1 << 0x13) // extpresignals
7826 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7827 | (1 << 0x1B) // multihead
7828 | (1 << 0x1D) // lowmemory
7829 | (1 << 0x1E); // generalfixes
7831 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7832 | (1 << 0x08) // mammothtrains
7833 | (1 << 0x09) // trainrefit
7834 | (0 << 0x0B) // subsidiaries
7835 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7836 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7837 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7838 | (1 << 0x14) // bridgespeedlimits
7839 | (1 << 0x16) // eternalgame
7840 | (1 << 0x17) // newtrains
7841 | (1 << 0x18) // newrvs
7842 | (1 << 0x19) // newships
7843 | (1 << 0x1A) // newplanes
7844 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7845 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7847 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7848 | (1 << 0x03) // semaphores
7849 | (1 << 0x0A) // newobjects
7850 | (0 << 0x0B) // enhancedgui
7851 | (0 << 0x0C) // newagerating
7852 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7853 | (1 << 0x0E) // fullloadany
7854 | (1 << 0x0F) // planespeed
7855 | (0 << 0x10) // moreindustriesperclimate - obsolete
7856 | (0 << 0x11) // moretoylandfeatures
7857 | (1 << 0x12) // newstations
7858 | (1 << 0x13) // tracktypecostdiff
7859 | (1 << 0x14) // manualconvert
7860 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7861 | (1 << 0x16) // canals
7862 | (1 << 0x17) // newstartyear
7863 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7864 | (1 << 0x19) // newhouses
7865 | (1 << 0x1A) // newbridges
7866 | (1 << 0x1B) // newtownnames
7867 | (1 << 0x1C) // moreanimation
7868 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7869 | (1 << 0x1E) // newshistory
7870 | (0 << 0x1F); // custombridgeheads
7872 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7873 | (1 << 0x01) // windowsnap
7874 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7875 | (1 << 0x03) // pathbasedsignalling
7876 | (0 << 0x04) // aichoosechance
7877 | (1 << 0x05) // resolutionwidth
7878 | (1 << 0x06) // resolutionheight
7879 | (1 << 0x07) // newindustries
7880 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7881 | (0 << 0x09) // townroadbranchprob
7882 | (0 << 0x0A) // tempsnowline
7883 | (1 << 0x0B) // newcargo
7884 | (1 << 0x0C) // enhancemultiplayer
7885 | (1 << 0x0D) // onewayroads
7886 | (1 << 0x0E) // irregularstations
7887 | (1 << 0x0F) // statistics
7888 | (1 << 0x10) // newsounds
7889 | (1 << 0x11) // autoreplace
7890 | (1 << 0x12) // autoslope
7891 | (0 << 0x13) // followvehicle
7892 | (1 << 0x14) // trams
7893 | (0 << 0x15) // enhancetunnels
7894 | (1 << 0x16) // shortrvs
7895 | (1 << 0x17) // articulatedrvs
7896 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7897 | (1 << 0x1E) // variablerunningcosts
7898 | (1 << 0x1F); // any switch is on
7901 /** Reset and clear all NewGRF stations */
7902 static void ResetCustomStations()
7904 const GRFFile * const *end = _grf_files.End();
7905 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7906 StationSpec **&stations = (*file)->stations;
7907 if (stations == NULL) continue;
7908 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7909 if (stations[i] == NULL) continue;
7910 StationSpec *statspec = stations[i];
7912 delete[] statspec->renderdata;
7914 /* Release platforms and layouts */
7915 if (!statspec->copied_layouts) {
7916 for (uint l = 0; l < statspec->lengths; l++) {
7917 for (uint p = 0; p < statspec->platforms[l]; p++) {
7918 free(statspec->layouts[l][p]);
7920 free(statspec->layouts[l]);
7922 free(statspec->layouts);
7923 free(statspec->platforms);
7926 /* Release this station */
7927 free(statspec);
7930 /* Free and reset the station data */
7931 free(stations);
7932 stations = NULL;
7936 /** Reset and clear all NewGRF houses */
7937 static void ResetCustomHouses()
7939 const GRFFile * const *end = _grf_files.End();
7940 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7941 HouseSpec **&housespec = (*file)->housespec;
7942 if (housespec == NULL) continue;
7943 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7944 free(housespec[i]);
7947 free(housespec);
7948 housespec = NULL;
7952 /** Reset and clear all NewGRF airports */
7953 static void ResetCustomAirports()
7955 const GRFFile * const *end = _grf_files.End();
7956 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7957 AirportSpec **aslist = (*file)->airportspec;
7958 if (aslist != NULL) {
7959 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7960 AirportSpec *as = aslist[i];
7962 if (as != NULL) {
7963 /* We need to remove the tiles layouts */
7964 for (int j = 0; j < as->num_table; j++) {
7965 /* remove the individual layouts */
7966 free(as->table[j]);
7968 free(as->table);
7969 free(as->depot_table);
7970 free(as->rotation);
7972 free(as);
7975 free(aslist);
7976 (*file)->airportspec = NULL;
7979 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7980 if (airporttilespec != NULL) {
7981 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7982 free(airporttilespec[i]);
7984 free(airporttilespec);
7985 airporttilespec = NULL;
7990 /** Reset and clear all NewGRF industries */
7991 static void ResetCustomIndustries()
7993 const GRFFile * const *end = _grf_files.End();
7994 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7995 IndustrySpec **&industryspec = (*file)->industryspec;
7996 IndustryTileSpec **&indtspec = (*file)->indtspec;
7998 /* We are verifiying both tiles and industries specs loaded from the grf file
7999 * First, let's deal with industryspec */
8000 if (industryspec != NULL) {
8001 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8002 IndustrySpec *ind = industryspec[i];
8003 if (ind == NULL) continue;
8005 /* We need to remove the sounds array */
8006 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8007 free(ind->random_sounds);
8010 /* We need to remove the tiles layouts */
8011 CleanIndustryTileTable(ind);
8013 free(ind);
8016 free(industryspec);
8017 industryspec = NULL;
8020 if (indtspec == NULL) continue;
8021 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8022 free(indtspec[i]);
8025 free(indtspec);
8026 indtspec = NULL;
8030 /** Reset and clear all NewObjects */
8031 static void ResetCustomObjects()
8033 const GRFFile * const *end = _grf_files.End();
8034 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8035 ObjectSpec **&objectspec = (*file)->objectspec;
8036 if (objectspec == NULL) continue;
8037 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8038 free(objectspec[i]);
8041 free(objectspec);
8042 objectspec = NULL;
8046 /** Reset and clear all NewGRFs */
8047 static void ResetNewGRF()
8049 const GRFFile * const *end = _grf_files.End();
8050 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8051 delete *file;
8054 _grf_files.Clear();
8055 _cur.grffile = NULL;
8058 /** Clear all NewGRF errors */
8059 static void ResetNewGRFErrors()
8061 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8062 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8063 delete c->error;
8064 c->error = NULL;
8070 * Reset all NewGRF loaded data
8071 * TODO
8073 void ResetNewGRFData()
8075 CleanUpStrings();
8076 CleanUpGRFTownNames();
8078 /* Copy/reset original engine info data */
8079 SetupEngines();
8081 /* Copy/reset original bridge info data */
8082 ResetBridges();
8084 /* Reset rail type information */
8085 ResetRailTypes();
8087 /* Allocate temporary refit/cargo class data */
8088 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8090 /* Fill rail type label temporary data for default trains */
8091 Engine *e;
8092 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8093 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8096 /* Reset GRM reservations */
8097 memset(&_grm_engines, 0, sizeof(_grm_engines));
8098 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8100 /* Reset generic feature callback lists */
8101 ResetGenericCallbacks();
8103 /* Reset price base data */
8104 ResetPriceBaseMultipliers();
8106 /* Reset the curencies array */
8107 ResetCurrencies();
8109 /* Reset the house array */
8110 ResetCustomHouses();
8111 ResetHouses();
8113 /* Reset the industries structures*/
8114 ResetCustomIndustries();
8115 ResetIndustries();
8117 /* Reset the objects. */
8118 ObjectClass::Reset();
8119 ResetCustomObjects();
8120 ResetObjects();
8122 /* Reset station classes */
8123 StationClass::Reset();
8124 ResetCustomStations();
8126 /* Reset airport-related structures */
8127 AirportClass::Reset();
8128 ResetCustomAirports();
8129 AirportSpec::ResetAirports();
8130 AirportTileSpec::ResetAirportTiles();
8132 /* Reset canal sprite groups and flags */
8133 memset(_water_feature, 0, sizeof(_water_feature));
8135 /* Reset the snowline table. */
8136 ClearSnowLine();
8138 /* Reset NewGRF files */
8139 ResetNewGRF();
8141 /* Reset NewGRF errors. */
8142 ResetNewGRFErrors();
8144 /* Set up the default cargo types */
8145 SetupCargoForClimate(_settings_game.game_creation.landscape);
8147 /* Reset misc GRF features and train list display variables */
8148 _misc_grf_features = 0;
8150 _loaded_newgrf_features.has_2CC = false;
8151 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8152 _loaded_newgrf_features.has_newhouses = false;
8153 _loaded_newgrf_features.has_newindustries = false;
8154 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8156 /* Clear all GRF overrides */
8157 _grf_id_overrides.clear();
8159 InitializeSoundPool();
8160 _spritegroup_pool.CleanPool();
8164 * Reset NewGRF data which is stored persistently in savegames.
8166 void ResetPersistentNewGRFData()
8168 /* Reset override managers */
8169 _engine_mngr.ResetToDefaultMapping();
8170 _house_mngr.ResetMapping();
8171 _industry_mngr.ResetMapping();
8172 _industile_mngr.ResetMapping();
8173 _airport_mngr.ResetMapping();
8174 _airporttile_mngr.ResetMapping();
8178 * Construct the Cargo Mapping
8179 * @note This is the reverse of a cargo translation table
8181 static void BuildCargoTranslationMap()
8183 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8185 for (CargoID c = 0; c < NUM_CARGO; c++) {
8186 const CargoSpec *cs = CargoSpec::Get(c);
8187 if (!cs->IsValid()) continue;
8189 if (_cur.grffile->cargo_list.Length() == 0) {
8190 /* Default translation table, so just a straight mapping to bitnum */
8191 _cur.grffile->cargo_map[c] = cs->bitnum;
8192 } else {
8193 /* Check the translation table for this cargo's label */
8194 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8195 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8201 * Prepare loading a NewGRF file with its config
8202 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8204 static void InitNewGRFFile(const GRFConfig *config)
8206 GRFFile *newfile = GetFileByFilename(config->filename);
8207 if (newfile != NULL) {
8208 /* We already loaded it once. */
8209 _cur.grffile = newfile;
8210 return;
8213 newfile = new GRFFile(config);
8214 *_grf_files.Append() = _cur.grffile = newfile;
8218 * Constructor for GRFFile
8219 * @param config GRFConfig to copy name, grfid and parameters from.
8221 GRFFile::GRFFile(const GRFConfig *config)
8223 this->filename = stredup(config->filename);
8224 this->grfid = config->ident.grfid;
8226 /* Initialise local settings to defaults */
8227 this->traininfo_vehicle_pitch = 0;
8228 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8230 /* Mark price_base_multipliers as 'not set' */
8231 for (Price i = PR_BEGIN; i < PR_END; i++) {
8232 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8235 /* Initialise rail type map with default rail types */
8236 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8237 this->railtype_map[0] = RAILTYPE_RAIL;
8238 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8239 this->railtype_map[2] = RAILTYPE_MONO;
8240 this->railtype_map[3] = RAILTYPE_MAGLEV;
8242 /* Copy the initial parameter list
8243 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8244 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8246 assert(config->num_params <= lengthof(config->param));
8247 this->param_end = config->num_params;
8248 if (this->param_end > 0) {
8249 MemCpyT(this->param, config->param, this->param_end);
8253 GRFFile::~GRFFile()
8255 free(this->filename);
8256 delete[] this->language_map;
8261 * List of what cargo labels are refittable for the given the vehicle-type.
8262 * Only currently active labels are applied.
8264 static const CargoLabel _default_refitmasks_rail[] = {
8265 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8266 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8267 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8268 'PLST', 'FZDR',
8269 0 };
8271 static const CargoLabel _default_refitmasks_road[] = {
8272 0 };
8274 static const CargoLabel _default_refitmasks_ships[] = {
8275 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8276 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8277 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8278 'PLST', 'FZDR',
8279 0 };
8281 static const CargoLabel _default_refitmasks_aircraft[] = {
8282 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8283 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8284 0 };
8286 static const CargoLabel * const _default_refitmasks[] = {
8287 _default_refitmasks_rail,
8288 _default_refitmasks_road,
8289 _default_refitmasks_ships,
8290 _default_refitmasks_aircraft,
8295 * Precalculate refit masks from cargo classes for all vehicles.
8297 static void CalculateRefitMasks()
8299 Engine *e;
8301 FOR_ALL_ENGINES(e) {
8302 EngineID engine = e->index;
8303 EngineInfo *ei = &e->info;
8304 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8306 /* Did the newgrf specify any refitting? If not, use defaults. */
8307 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8308 uint32 mask = 0;
8309 uint32 not_mask = 0;
8310 uint32 xor_mask = ei->refit_mask;
8312 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8313 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8314 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8316 if (_gted[engine].cargo_allowed != 0) {
8317 /* Build up the list of cargo types from the set cargo classes. */
8318 const CargoSpec *cs;
8319 FOR_ALL_CARGOSPECS(cs) {
8320 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8321 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8325 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8327 /* Apply explicit refit includes/excludes. */
8328 ei->refit_mask |= _gted[engine].ctt_include_mask;
8329 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8330 } else {
8331 uint32 xor_mask = 0;
8333 /* Don't apply default refit mask to wagons nor engines with no capacity */
8334 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8335 const CargoLabel *cl = _default_refitmasks[e->type];
8336 for (uint i = 0;; i++) {
8337 if (cl[i] == 0) break;
8339 CargoID cargo = GetCargoIDByLabel(cl[i]);
8340 if (cargo == CT_INVALID) continue;
8342 SetBit(xor_mask, cargo);
8346 ei->refit_mask = xor_mask & _cargo_mask;
8348 /* If the mask is zero, the vehicle shall only carry the default cargo */
8349 only_defaultcargo = (ei->refit_mask == 0);
8352 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8353 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8355 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8356 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8357 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8358 ei->cargo_type = CT_INVALID;
8361 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8362 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8363 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8364 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8365 const uint8 *cargo_map_for_first_refittable = NULL;
8367 const GRFFile *file = _gted[engine].defaultcargo_grf;
8368 if (file == NULL) file = e->GetGRF();
8369 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8370 cargo_map_for_first_refittable = file->cargo_map;
8374 if (cargo_map_for_first_refittable != NULL) {
8375 /* Use first refittable cargo from cargo translation table */
8376 byte best_local_slot = 0xFF;
8377 CargoID cargo_type;
8378 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8379 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8380 if (local_slot < best_local_slot) {
8381 best_local_slot = local_slot;
8382 ei->cargo_type = cargo_type;
8387 if (ei->cargo_type == CT_INVALID) {
8388 /* Use first refittable cargo slot */
8389 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8392 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8394 /* Clear refit_mask for not refittable ships */
8395 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8396 ei->refit_mask = 0;
8401 /** Set to use the correct action0 properties for each canal feature */
8402 static void FinaliseCanals()
8404 for (uint i = 0; i < CF_END; i++) {
8405 if (_water_feature[i].grffile != NULL) {
8406 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8407 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8412 /** Check for invalid engines */
8413 static void FinaliseEngineArray()
8415 Engine *e;
8417 FOR_ALL_ENGINES(e) {
8418 if (e->GetGRF() == NULL) {
8419 const EngineIDMapping &eid = _engine_mngr[e->index];
8420 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8421 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8425 /* When the train does not set property 27 (misc flags), but it
8426 * is overridden by a NewGRF graphically we want to disable the
8427 * flipping possibility. */
8428 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8429 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8432 /* Skip wagons, there livery is defined via the engine */
8433 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8434 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8435 SetBit(_loaded_newgrf_features.used_liveries, ls);
8436 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8438 if (e->type == VEH_TRAIN) {
8439 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8440 switch (ls) {
8441 case LS_STEAM:
8442 case LS_DIESEL:
8443 case LS_ELECTRIC:
8444 case LS_MONORAIL:
8445 case LS_MAGLEV:
8446 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8447 break;
8449 case LS_DMU:
8450 case LS_EMU:
8451 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8452 break;
8454 default: NOT_REACHED();
8461 /** Check for invalid cargoes */
8462 static void FinaliseCargoArray()
8464 for (CargoID c = 0; c < NUM_CARGO; c++) {
8465 CargoSpec *cs = CargoSpec::Get(c);
8466 if (!cs->IsValid()) {
8467 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8468 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8469 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8475 * Check if a given housespec is valid and disable it if it's not.
8476 * The housespecs that follow it are used to check the validity of
8477 * multitile houses.
8478 * @param hs The housespec to check.
8479 * @param next1 The housespec that follows \c hs.
8480 * @param next2 The housespec that follows \c next1.
8481 * @param next3 The housespec that follows \c next2.
8482 * @param filename The filename of the newgrf this house was defined in.
8483 * @return Whether the given housespec is valid.
8485 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8487 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8488 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8489 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8490 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8491 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8492 hs->enabled = false;
8493 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);
8494 return false;
8497 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8498 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8499 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8500 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8501 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8502 hs->enabled = false;
8503 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);
8504 return false;
8507 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8508 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8509 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8510 hs->enabled = false;
8511 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);
8512 return false;
8515 /* Make sure that additional parts of multitile houses are not available. */
8516 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8517 hs->enabled = false;
8518 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);
8519 return false;
8522 return true;
8526 * Make sure there is at least one house available in the year 0 for the given
8527 * climate / housezone combination.
8528 * @param bitmask The climate and housezone to check for. Exactly one climate
8529 * bit and one housezone bit should be set.
8531 static void EnsureEarlyHouse(HouseZones bitmask)
8533 Year min_year = MAX_YEAR;
8535 for (int i = 0; i < NUM_HOUSES; i++) {
8536 HouseSpec *hs = HouseSpec::Get(i);
8537 if (hs == NULL || !hs->enabled) continue;
8538 if ((hs->building_availability & bitmask) != bitmask) continue;
8539 if (hs->min_year < min_year) min_year = hs->min_year;
8542 if (min_year == 0) return;
8544 for (int i = 0; i < NUM_HOUSES; i++) {
8545 HouseSpec *hs = HouseSpec::Get(i);
8546 if (hs == NULL || !hs->enabled) continue;
8547 if ((hs->building_availability & bitmask) != bitmask) continue;
8548 if (hs->min_year == min_year) hs->min_year = 0;
8553 * Add all new houses to the house array. House properties can be set at any
8554 * time in the GRF file, so we can only add a house spec to the house array
8555 * after the file has finished loading. We also need to check the dates, due to
8556 * the TTDPatch behaviour described below that we need to emulate.
8558 static void FinaliseHouseArray()
8560 /* If there are no houses with start dates before 1930, then all houses
8561 * with start dates of 1930 have them reset to 0. This is in order to be
8562 * compatible with TTDPatch, where if no houses have start dates before
8563 * 1930 and the date is before 1930, the game pretends that this is 1930.
8564 * If there have been any houses defined with start dates before 1930 then
8565 * the dates are left alone.
8566 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8567 * minimum introduction date to 0.
8569 const GRFFile * const *end = _grf_files.End();
8570 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8571 HouseSpec **&housespec = (*file)->housespec;
8572 if (housespec == NULL) continue;
8574 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8575 HouseSpec *hs = housespec[i];
8577 if (hs == NULL) continue;
8579 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8580 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8581 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8583 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8585 _house_mngr.SetEntitySpec(hs);
8589 for (int i = 0; i < NUM_HOUSES; i++) {
8590 HouseSpec *hs = HouseSpec::Get(i);
8591 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8592 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8593 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8595 /* We need to check all houses again to we are sure that multitile houses
8596 * did get consecutive IDs and none of the parts are missing. */
8597 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8598 /* GetHouseNorthPart checks 3 houses that are directly before
8599 * it in the house pool. If any of those houses have multi-tile
8600 * flags set it assumes it's part of a multitile house. Since
8601 * we can have invalid houses in the pool marked as disabled, we
8602 * don't want to have them influencing valid tiles. As such set
8603 * building_flags to zero here to make sure any house following
8604 * this one in the pool is properly handled as 1x1 house. */
8605 hs->building_flags = TILE_NO_FLAG;
8609 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8610 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8611 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8612 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8613 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8614 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8616 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8617 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8618 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8619 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8620 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8621 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8626 * Add all new industries to the industry array. Industry properties can be set at any
8627 * time in the GRF file, so we can only add a industry spec to the industry array
8628 * after the file has finished loading.
8630 static void FinaliseIndustriesArray()
8632 const GRFFile * const *end = _grf_files.End();
8633 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8634 IndustrySpec **&industryspec = (*file)->industryspec;
8635 IndustryTileSpec **&indtspec = (*file)->indtspec;
8636 if (industryspec != NULL) {
8637 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8638 IndustrySpec *indsp = industryspec[i];
8640 if (indsp != NULL && indsp->enabled) {
8641 StringID strid;
8642 /* process the conversion of text at the end, so to be sure everything will be fine
8643 * and available. Check if it does not return undefind marker, which is a very good sign of a
8644 * substitute industry who has not changed the string been examined, thus using it as such */
8645 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8646 if (strid != STR_UNDEFINED) indsp->name = strid;
8648 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8649 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8651 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8652 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8654 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8655 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8657 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8658 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8660 if (indsp->station_name != STR_NULL) {
8661 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8662 * station's name. Don't want to lose the value, therefore, do not process. */
8663 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8664 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8667 _industry_mngr.SetEntitySpec(indsp);
8668 _loaded_newgrf_features.has_newindustries = true;
8673 if (indtspec != NULL) {
8674 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8675 IndustryTileSpec *indtsp = indtspec[i];
8676 if (indtsp != NULL) {
8677 _industile_mngr.SetEntitySpec(indtsp);
8683 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8684 IndustrySpec *indsp = &_industry_specs[j];
8685 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8686 for (uint i = 0; i < 3; i++) {
8687 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8690 if (!indsp->enabled) {
8691 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8697 * Add all new objects to the object array. Object properties can be set at any
8698 * time in the GRF file, so we can only add an object spec to the object array
8699 * after the file has finished loading.
8701 static void FinaliseObjectsArray()
8703 const GRFFile * const *end = _grf_files.End();
8704 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8705 ObjectSpec **&objectspec = (*file)->objectspec;
8706 if (objectspec != NULL) {
8707 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8708 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8709 _object_mngr.SetEntitySpec(objectspec[i]);
8717 * Add all new airports to the airport array. Airport properties can be set at any
8718 * time in the GRF file, so we can only add a airport spec to the airport array
8719 * after the file has finished loading.
8721 static void FinaliseAirportsArray()
8723 const GRFFile * const *end = _grf_files.End();
8724 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8725 AirportSpec **&airportspec = (*file)->airportspec;
8726 if (airportspec != NULL) {
8727 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8728 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8729 _airport_mngr.SetEntitySpec(airportspec[i]);
8734 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8735 if (airporttilespec != NULL) {
8736 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8737 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8738 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8745 /* Here we perform initial decoding of some special sprites (as are they
8746 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8747 * partial implementation yet).
8748 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8749 * a crafted invalid GRF file. We should tell that to the user somehow, or
8750 * better make this more robust in the future. */
8751 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8753 /* XXX: There is a difference between staged loading in TTDPatch and
8754 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8755 * during stage 1, whilst action 3 is carried out during stage 2 (to
8756 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8757 * IDs are valid only within a given set (action 1) block, and may be
8758 * overwritten after action 3 associates them. But overwriting happens
8759 * in an earlier stage than associating, so... We just process actions
8760 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8761 * --pasky
8762 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8763 * is not in memory and scanning the file every time would be too expensive.
8764 * In other stages we skip action 0x10 since it's already dealt with. */
8765 static const SpecialSpriteHandler handlers[][GLS_END] = {
8766 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8767 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8768 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8769 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8770 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8771 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8772 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8773 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8774 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8775 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8776 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8777 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8778 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8779 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8780 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8781 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8782 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8783 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8784 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8785 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8786 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8789 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8791 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8792 if (it == _grf_line_to_action6_sprite_override.end()) {
8793 /* No preloaded sprite to work with; read the
8794 * pseudo sprite content. */
8795 FioReadBlock(buf, num);
8796 } else {
8797 /* Use the preloaded sprite data. */
8798 buf = _grf_line_to_action6_sprite_override[location];
8799 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8801 /* Skip the real (original) content of this action. */
8802 FioSeekTo(num, SEEK_CUR);
8805 ByteReader br(buf, buf + num);
8806 ByteReader *bufp = &br;
8808 try {
8809 byte action = bufp->ReadByte();
8811 if (action == 0xFF) {
8812 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8813 } else if (action == 0xFE) {
8814 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8815 } else if (action >= lengthof(handlers)) {
8816 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8817 } else if (handlers[action][stage] == NULL) {
8818 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8819 } else {
8820 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8821 handlers[action][stage](bufp);
8823 } catch (...) {
8824 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8825 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8830 /** Signature of a container version 2 GRF. */
8831 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8834 * Get the container version of the currently opened GRF file.
8835 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8837 byte GetGRFContainerVersion()
8839 size_t pos = FioGetPos();
8841 if (FioReadWord() == 0) {
8842 /* Check for GRF container version 2, which is identified by the bytes
8843 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8844 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8845 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8848 return 2;
8851 /* Container version 1 has no header, rewind to start. */
8852 FioSeekTo(pos, SEEK_SET);
8853 return 1;
8857 * Load a particular NewGRF.
8858 * @param config The configuration of the to be loaded NewGRF.
8859 * @param file_index The Fio index of the first NewGRF to load.
8860 * @param stage The loading stage of the NewGRF.
8861 * @param subdir The sub directory to find the NewGRF in.
8863 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8865 const char *filename = config->filename;
8867 /* A .grf file is activated only if it was active when the game was
8868 * started. If a game is loaded, only its active .grfs will be
8869 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8870 * considered active if its action 8 has been processed, i.e. its
8871 * action 8 hasn't been skipped using an action 7.
8873 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8874 * carried out. All others are ignored, because they only need to be
8875 * processed once at initialization. */
8876 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8877 _cur.grffile = GetFileByFilename(filename);
8878 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8879 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8880 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8883 if (file_index >= MAX_FILE_SLOTS) {
8884 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
8885 config->status = GCS_DISABLED;
8886 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8887 return;
8890 FioOpenFile(file_index, filename, subdir);
8891 _cur.file_index = file_index; // XXX
8892 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8894 _cur.grfconfig = config;
8896 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8898 _cur.grf_container_ver = GetGRFContainerVersion();
8899 if (_cur.grf_container_ver == 0) {
8900 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8901 return;
8904 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8905 /* We need the sprite offsets in the init stage for NewGRF sounds
8906 * and in the activation stage for real sprites. */
8907 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8908 } else {
8909 /* Skip sprite section offset if present. */
8910 if (_cur.grf_container_ver >= 2) FioReadDword();
8913 if (_cur.grf_container_ver >= 2) {
8914 /* Read compression value. */
8915 byte compression = FioReadByte();
8916 if (compression != 0) {
8917 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8918 return;
8922 /* Skip the first sprite; we don't care about how many sprites this
8923 * does contain; newest TTDPatches and George's longvehicles don't
8924 * neither, apparently. */
8925 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8926 if (num == 4 && FioReadByte() == 0xFF) {
8927 FioReadDword();
8928 } else {
8929 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8930 return;
8933 _cur.ClearDataForNextFile();
8935 ReusableBuffer<byte> buf;
8937 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8938 byte type = FioReadByte();
8939 _cur.nfo_line++;
8941 if (type == 0xFF) {
8942 if (_cur.skip_sprites == 0) {
8943 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8945 /* Stop all processing if we are to skip the remaining sprites */
8946 if (_cur.skip_sprites == -1) break;
8948 continue;
8949 } else {
8950 FioSkipBytes(num);
8952 } else {
8953 if (_cur.skip_sprites == 0) {
8954 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8955 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8956 break;
8959 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8960 /* Reference to data section. Container version >= 2 only. */
8961 FioSkipBytes(num);
8962 } else {
8963 FioSkipBytes(7);
8964 SkipSpriteData(type, num - 8);
8968 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8973 * Relocates the old shore sprites at new positions.
8975 * 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)
8976 * 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)
8977 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8979 static void ActivateOldShore()
8981 /* Use default graphics, if no shore sprites were loaded.
8982 * Should not happen, as the base set's extra grf should include some. */
8983 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8985 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8986 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8987 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8988 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8989 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8990 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8991 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8992 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8993 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8996 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8997 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8998 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8999 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9000 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9001 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9002 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9003 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9004 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9006 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9007 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9008 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9009 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9014 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9016 static void FinalisePriceBaseMultipliers()
9018 extern const PriceBaseSpec _price_base_specs[];
9019 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9020 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9022 /* Evaluate grf overrides */
9023 int num_grfs = _grf_files.Length();
9024 int *grf_overrides = AllocaM(int, num_grfs);
9025 for (int i = 0; i < num_grfs; i++) {
9026 grf_overrides[i] = -1;
9028 GRFFile *source = _grf_files[i];
9029 uint32 override = _grf_id_overrides[source->grfid];
9030 if (override == 0) continue;
9032 GRFFile *dest = GetFileByGRFID(override);
9033 if (dest == NULL) continue;
9035 grf_overrides[i] = _grf_files.FindIndex(dest);
9036 assert(grf_overrides[i] >= 0);
9039 /* Override features and price base multipliers of earlier loaded grfs */
9040 for (int i = 0; i < num_grfs; i++) {
9041 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9042 GRFFile *source = _grf_files[i];
9043 GRFFile *dest = _grf_files[grf_overrides[i]];
9045 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9046 source->grf_features |= features;
9047 dest->grf_features |= features;
9049 for (Price p = PR_BEGIN; p < PR_END; p++) {
9050 /* No price defined -> nothing to do */
9051 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9052 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9053 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9057 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9058 for (int i = num_grfs - 1; i >= 0; i--) {
9059 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9060 GRFFile *source = _grf_files[i];
9061 GRFFile *dest = _grf_files[grf_overrides[i]];
9063 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9064 source->grf_features |= features;
9065 dest->grf_features |= features;
9067 for (Price p = PR_BEGIN; p < PR_END; p++) {
9068 /* Already a price defined -> nothing to do */
9069 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9070 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9071 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9075 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9076 for (int i = 0; i < num_grfs; i++) {
9077 if (grf_overrides[i] < 0) continue;
9078 GRFFile *source = _grf_files[i];
9079 GRFFile *dest = _grf_files[grf_overrides[i]];
9081 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9082 source->grf_features |= features;
9083 dest->grf_features |= features;
9085 for (Price p = PR_BEGIN; p < PR_END; p++) {
9086 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9087 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9088 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9090 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9094 /* Apply fallback prices for grf version < 8 */
9095 const GRFFile * const *end = _grf_files.End();
9096 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9097 if ((*file)->grf_version >= 8) continue;
9098 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9099 for (Price p = PR_BEGIN; p < PR_END; p++) {
9100 Price fallback_price = _price_base_specs[p].fallback_price;
9101 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9102 /* No price multiplier has been set.
9103 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9104 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9109 /* Decide local/global scope of price base multipliers */
9110 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9111 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9112 for (Price p = PR_BEGIN; p < PR_END; p++) {
9113 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9114 /* No multiplier was set; set it to a neutral value */
9115 price_base_multipliers[p] = 0;
9116 } else {
9117 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9118 /* The grf does not define any objects of the feature,
9119 * so it must be a difficulty setting. Apply it globally */
9120 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9121 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9122 price_base_multipliers[p] = 0;
9123 } else {
9124 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9131 extern void InitGRFTownGeneratorNames();
9133 /** Finish loading NewGRFs and execute needed post-processing */
9134 static void AfterLoadGRFs()
9136 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9137 *it->target = MapGRFStringID(it->grfid, it->source);
9139 _string_to_grf_mapping.Clear();
9141 /* Free the action 6 override sprites. */
9142 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9143 free((*it).second);
9145 _grf_line_to_action6_sprite_override.clear();
9147 /* Polish cargoes */
9148 FinaliseCargoArray();
9150 /* Pre-calculate all refit masks after loading GRF files. */
9151 CalculateRefitMasks();
9153 /* Polish engines */
9154 FinaliseEngineArray();
9156 /* Set the actually used Canal properties */
9157 FinaliseCanals();
9159 /* Add all new houses to the house array. */
9160 FinaliseHouseArray();
9162 /* Add all new industries to the industry array. */
9163 FinaliseIndustriesArray();
9165 /* Add all new objects to the object array. */
9166 FinaliseObjectsArray();
9168 InitializeSortedCargoSpecs();
9170 /* Sort the list of industry types. */
9171 SortIndustryTypes();
9173 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9174 BuildIndustriesLegend();
9176 /* Build the routemap legend, based on the available cargos */
9177 BuildLinkStatsLegend();
9179 /* Add all new airports to the airports array. */
9180 FinaliseAirportsArray();
9181 BindAirportSpecs();
9183 /* Update the townname generators list */
9184 InitGRFTownGeneratorNames();
9186 /* Run all queued vehicle list order changes */
9187 CommitVehicleListOrderChanges();
9189 /* Load old shore sprites in new position, if they were replaced by ActionA */
9190 ActivateOldShore();
9192 /* Set up custom rail types */
9193 InitRailTypes();
9195 Engine *e;
9196 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9197 if (_gted[e->index].rv_max_speed != 0) {
9198 /* Set RV maximum speed from the mph/0.8 unit value */
9199 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9203 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9204 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9205 if (railtype == INVALID_RAILTYPE) {
9206 /* Rail type is not available, so disable this engine */
9207 e->info.climates = 0;
9208 } else {
9209 e->u.rail.railtype = railtype;
9213 SetYearEngineAgingStops();
9215 FinalisePriceBaseMultipliers();
9217 /* Deallocate temporary loading data */
9218 free(_gted);
9219 _grm_sprites.clear();
9223 * Load all the NewGRFs.
9224 * @param load_index The offset for the first sprite to add.
9225 * @param file_index The Fio index of the first NewGRF to load.
9226 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9228 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9230 /* In case of networking we need to "sync" the start values
9231 * so all NewGRFs are loaded equally. For this we use the
9232 * start date of the game and we set the counters, etc. to
9233 * 0 so they're the same too. */
9234 Date date = _date;
9235 Year year = _cur_year;
9236 DateFract date_fract = _date_fract;
9237 uint16 tick_counter = _tick_counter;
9238 byte display_opt = _display_opt;
9240 if (_networking) {
9241 _cur_year = _settings_game.game_creation.starting_year;
9242 _date = ConvertYMDToDate(_cur_year, 0, 1);
9243 _date_fract = 0;
9244 _tick_counter = 0;
9245 _display_opt = 0;
9248 InitializeGRFSpecial();
9250 ResetNewGRFData();
9253 * Reset the status of all files, so we can 'retry' to load them.
9254 * This is needed when one for example rearranges the NewGRFs in-game
9255 * and a previously disabled NewGRF becomes useable. If it would not
9256 * be reset, the NewGRF would remain disabled even though it should
9257 * have been enabled.
9259 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9260 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9263 _cur.spriteid = load_index;
9265 /* Load newgrf sprites
9266 * in each loading stage, (try to) open each file specified in the config
9267 * and load information from it. */
9268 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9269 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9270 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9271 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9272 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9275 if (stage == GLS_RESERVE) {
9276 static const uint32 overrides[][2] = {
9277 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9278 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9279 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9281 for (size_t i = 0; i < lengthof(overrides); i++) {
9282 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9286 uint slot = file_index;
9287 uint num_non_static = 0;
9289 _cur.stage = stage;
9290 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9291 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9292 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9294 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9295 if (!FioCheckFileExists(c->filename, subdir)) {
9296 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9297 c->status = GCS_NOT_FOUND;
9298 continue;
9301 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9303 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9304 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9305 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9306 c->status = GCS_DISABLED;
9307 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9308 continue;
9310 num_non_static++;
9312 LoadNewGRFFile(c, slot++, stage, subdir);
9313 if (stage == GLS_RESERVE) {
9314 SetBit(c->flags, GCF_RESERVED);
9315 } else if (stage == GLS_ACTIVATION) {
9316 ClrBit(c->flags, GCF_RESERVED);
9317 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9318 ClearTemporaryNewGRFData(_cur.grffile);
9319 BuildCargoTranslationMap();
9320 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9321 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9322 /* We're not going to activate this, so free whatever data we allocated */
9323 ClearTemporaryNewGRFData(_cur.grffile);
9328 /* Pseudo sprite processing is finished; free temporary stuff */
9329 _cur.ClearDataForNextFile();
9331 /* Call any functions that should be run after GRFs have been loaded. */
9332 AfterLoadGRFs();
9334 /* Now revert back to the original situation */
9335 _cur_year = year;
9336 _date = date;
9337 _date_fract = date_fract;
9338 _tick_counter = tick_counter;
9339 _display_opt = display_opt;