(svn r27985) -Codechange: Convert VA2 switches into ones with non-overlapping ranges...
[openttd.git] / src / newgrf.cpp
blob41d7195918a64366b00d2574bd74887e30ee11fc
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;
4702 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4703 std::vector<uint32> bounds;
4704 for (uint i = 0; i < ranges.size(); i++) {
4705 bounds.push_back(ranges[i].low);
4706 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4708 std::sort(bounds.begin(), bounds.end());
4709 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4711 std::vector<const SpriteGroup *> target;
4712 for (uint j = 0; j < bounds.size(); ++j) {
4713 uint32 v = bounds[j];
4714 const SpriteGroup *t = NULL;
4715 for (uint i = 0; i < ranges.size(); i++) {
4716 if (ranges[i].low <= v && v <= ranges[i].high) {
4717 t = ranges[i].group;
4720 target.push_back(t);
4722 assert(target.size() == bounds.size());
4724 std::vector<DeterministicSpriteGroupRange> optimised;
4725 for (uint j = 0; j < bounds.size(); ) {
4726 if (target[j]) {
4727 DeterministicSpriteGroupRange r;
4728 r.group = target[j];
4729 r.low = bounds[j];
4730 while (j < bounds.size() && target[j] == r.group) {
4731 j++;
4733 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
4734 optimised.push_back(r);
4735 } else {
4736 j++;
4740 group->num_ranges = optimised.size();
4741 if (group->num_ranges > 0) {
4742 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4743 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
4745 break;
4748 /* Randomized Sprite Group */
4749 case 0x80: // Self scope
4750 case 0x83: // Parent scope
4751 case 0x84: // Relative scope
4753 assert(RandomizedSpriteGroup::CanAllocateItem());
4754 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4755 act_group = group;
4756 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4758 if (HasBit(type, 2)) {
4759 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4760 group->count = buf->ReadByte();
4763 uint8 triggers = buf->ReadByte();
4764 group->triggers = GB(triggers, 0, 7);
4765 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4766 group->lowest_randbit = buf->ReadByte();
4767 group->num_groups = buf->ReadByte();
4768 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4770 for (uint i = 0; i < group->num_groups; i++) {
4771 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4774 break;
4777 /* Neither a variable or randomized sprite group... must be a real group */
4778 default:
4780 switch (feature) {
4781 case GSF_TRAINS:
4782 case GSF_ROADVEHICLES:
4783 case GSF_SHIPS:
4784 case GSF_AIRCRAFT:
4785 case GSF_STATIONS:
4786 case GSF_CANALS:
4787 case GSF_CARGOES:
4788 case GSF_AIRPORTS:
4789 case GSF_RAILTYPES:
4791 byte num_loaded = type;
4792 byte num_loading = buf->ReadByte();
4794 if (!_cur.HasValidSpriteSets(feature)) {
4795 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4796 return;
4799 assert(RealSpriteGroup::CanAllocateItem());
4800 RealSpriteGroup *group = new RealSpriteGroup();
4801 act_group = group;
4803 group->num_loaded = num_loaded;
4804 group->num_loading = num_loading;
4805 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4806 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4808 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4809 setid, num_loaded, num_loading);
4811 for (uint i = 0; i < num_loaded; i++) {
4812 uint16 spriteid = buf->ReadWord();
4813 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4814 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4817 for (uint i = 0; i < num_loading; i++) {
4818 uint16 spriteid = buf->ReadWord();
4819 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4820 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4823 break;
4826 case GSF_HOUSES:
4827 case GSF_AIRPORTTILES:
4828 case GSF_OBJECTS:
4829 case GSF_INDUSTRYTILES: {
4830 byte num_building_sprites = max((uint8)1, type);
4832 assert(TileLayoutSpriteGroup::CanAllocateItem());
4833 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4834 act_group = group;
4836 /* On error, bail out immediately. Temporary GRF data was already freed */
4837 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4838 break;
4841 case GSF_INDUSTRIES: {
4842 if (type > 1) {
4843 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4844 break;
4847 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4848 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4849 act_group = group;
4850 group->version = type;
4851 if (type == 0) {
4852 for (uint i = 0; i < 3; i++) {
4853 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4855 for (uint i = 0; i < 2; i++) {
4856 group->add_output[i] = buf->ReadWord(); // unsigned
4858 group->again = buf->ReadByte();
4859 } else {
4860 for (uint i = 0; i < 3; i++) {
4861 group->subtract_input[i] = buf->ReadByte();
4863 for (uint i = 0; i < 2; i++) {
4864 group->add_output[i] = buf->ReadByte();
4866 group->again = buf->ReadByte();
4868 break;
4871 /* Loading of Tile Layout and Production Callback groups would happen here */
4872 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4877 _cur.spritegroups[setid] = act_group;
4880 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4882 if (feature == GSF_OBJECTS) {
4883 switch (ctype) {
4884 case 0: return 0;
4885 case 0xFF: return CT_PURCHASE_OBJECT;
4886 default:
4887 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4888 return CT_INVALID;
4891 /* Special cargo types for purchase list and stations */
4892 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4893 if (ctype == 0xFF) return CT_PURCHASE;
4895 if (_cur.grffile->cargo_list.Length() == 0) {
4896 /* No cargo table, so use bitnum values */
4897 if (ctype >= 32) {
4898 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4899 return CT_INVALID;
4902 const CargoSpec *cs;
4903 FOR_ALL_CARGOSPECS(cs) {
4904 if (cs->bitnum == ctype) {
4905 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4906 return cs->Index();
4910 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4911 return CT_INVALID;
4914 /* Check if the cargo type is out of bounds of the cargo translation table */
4915 if (ctype >= _cur.grffile->cargo_list.Length()) {
4916 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4917 return CT_INVALID;
4920 /* Look up the cargo label from the translation table */
4921 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4922 if (cl == 0) {
4923 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4924 return CT_INVALID;
4927 ctype = GetCargoIDByLabel(cl);
4928 if (ctype == CT_INVALID) {
4929 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));
4930 return CT_INVALID;
4933 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);
4934 return ctype;
4938 static bool IsValidGroupID(uint16 groupid, const char *function)
4940 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4941 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4942 return false;
4945 return true;
4948 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4950 static EngineID *last_engines;
4951 static uint last_engines_count;
4952 bool wagover = false;
4954 /* Test for 'wagon override' flag */
4955 if (HasBit(idcount, 7)) {
4956 wagover = true;
4957 /* Strip off the flag */
4958 idcount = GB(idcount, 0, 7);
4960 if (last_engines_count == 0) {
4961 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4962 return;
4965 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4966 last_engines_count, idcount);
4967 } else {
4968 if (last_engines_count != idcount) {
4969 last_engines = ReallocT(last_engines, idcount);
4970 last_engines_count = idcount;
4974 EngineID *engines = AllocaM(EngineID, idcount);
4975 for (uint i = 0; i < idcount; i++) {
4976 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4977 if (e == NULL) {
4978 /* No engine could be allocated?!? Deal with it. Okay,
4979 * this might look bad. Also make sure this NewGRF
4980 * gets disabled, as a half loaded one is bad. */
4981 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4982 return;
4985 engines[i] = e->index;
4986 if (!wagover) last_engines[i] = engines[i];
4989 uint8 cidcount = buf->ReadByte();
4990 for (uint c = 0; c < cidcount; c++) {
4991 uint8 ctype = buf->ReadByte();
4992 uint16 groupid = buf->ReadWord();
4993 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4995 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4997 ctype = TranslateCargo(feature, ctype);
4998 if (ctype == CT_INVALID) continue;
5000 for (uint i = 0; i < idcount; i++) {
5001 EngineID engine = engines[i];
5003 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5005 if (wagover) {
5006 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5007 } else {
5008 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5013 uint16 groupid = buf->ReadWord();
5014 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5016 grfmsg(8, "-- Default group id 0x%04X", groupid);
5018 for (uint i = 0; i < idcount; i++) {
5019 EngineID engine = engines[i];
5021 if (wagover) {
5022 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5023 } else {
5024 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5025 SetEngineGRF(engine, _cur.grffile);
5031 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5033 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5034 for (uint i = 0; i < idcount; i++) {
5035 cfs[i] = (CanalFeature)buf->ReadByte();
5038 uint8 cidcount = buf->ReadByte();
5039 buf->Skip(cidcount * 3);
5041 uint16 groupid = buf->ReadWord();
5042 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5044 for (uint i = 0; i < idcount; i++) {
5045 CanalFeature cf = cfs[i];
5047 if (cf >= CF_END) {
5048 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5049 continue;
5052 _water_feature[cf].grffile = _cur.grffile;
5053 _water_feature[cf].group = _cur.spritegroups[groupid];
5058 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5060 uint8 *stations = AllocaM(uint8, idcount);
5061 for (uint i = 0; i < idcount; i++) {
5062 stations[i] = buf->ReadByte();
5065 uint8 cidcount = buf->ReadByte();
5066 for (uint c = 0; c < cidcount; c++) {
5067 uint8 ctype = buf->ReadByte();
5068 uint16 groupid = buf->ReadWord();
5069 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5071 ctype = TranslateCargo(GSF_STATIONS, ctype);
5072 if (ctype == CT_INVALID) continue;
5074 for (uint i = 0; i < idcount; i++) {
5075 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5077 if (statspec == NULL) {
5078 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5079 continue;
5082 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5086 uint16 groupid = buf->ReadWord();
5087 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5089 for (uint i = 0; i < idcount; i++) {
5090 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5092 if (statspec == NULL) {
5093 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5094 continue;
5097 if (statspec->grf_prop.grffile != NULL) {
5098 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5099 continue;
5102 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5103 statspec->grf_prop.grffile = _cur.grffile;
5104 statspec->grf_prop.local_id = stations[i];
5105 StationClass::Assign(statspec);
5110 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5112 uint8 *houses = AllocaM(uint8, idcount);
5113 for (uint i = 0; i < idcount; i++) {
5114 houses[i] = buf->ReadByte();
5117 /* Skip the cargo type section, we only care about the default group */
5118 uint8 cidcount = buf->ReadByte();
5119 buf->Skip(cidcount * 3);
5121 uint16 groupid = buf->ReadWord();
5122 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5124 if (_cur.grffile->housespec == NULL) {
5125 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5126 return;
5129 for (uint i = 0; i < idcount; i++) {
5130 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5132 if (hs == NULL) {
5133 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5134 continue;
5137 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5141 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5143 uint8 *industries = AllocaM(uint8, idcount);
5144 for (uint i = 0; i < idcount; i++) {
5145 industries[i] = buf->ReadByte();
5148 /* Skip the cargo type section, we only care about the default group */
5149 uint8 cidcount = buf->ReadByte();
5150 buf->Skip(cidcount * 3);
5152 uint16 groupid = buf->ReadWord();
5153 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5155 if (_cur.grffile->industryspec == NULL) {
5156 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5157 return;
5160 for (uint i = 0; i < idcount; i++) {
5161 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5163 if (indsp == NULL) {
5164 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5165 continue;
5168 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5172 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5174 uint8 *indtiles = AllocaM(uint8, idcount);
5175 for (uint i = 0; i < idcount; i++) {
5176 indtiles[i] = buf->ReadByte();
5179 /* Skip the cargo type section, we only care about the default group */
5180 uint8 cidcount = buf->ReadByte();
5181 buf->Skip(cidcount * 3);
5183 uint16 groupid = buf->ReadWord();
5184 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5186 if (_cur.grffile->indtspec == NULL) {
5187 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5188 return;
5191 for (uint i = 0; i < idcount; i++) {
5192 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5194 if (indtsp == NULL) {
5195 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5196 continue;
5199 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5203 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5205 CargoID *cargoes = AllocaM(CargoID, idcount);
5206 for (uint i = 0; i < idcount; i++) {
5207 cargoes[i] = buf->ReadByte();
5210 /* Skip the cargo type section, we only care about the default group */
5211 uint8 cidcount = buf->ReadByte();
5212 buf->Skip(cidcount * 3);
5214 uint16 groupid = buf->ReadWord();
5215 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5217 for (uint i = 0; i < idcount; i++) {
5218 CargoID cid = cargoes[i];
5220 if (cid >= NUM_CARGO) {
5221 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5222 continue;
5225 CargoSpec *cs = CargoSpec::Get(cid);
5226 cs->grffile = _cur.grffile;
5227 cs->group = _cur.spritegroups[groupid];
5231 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5233 if (_cur.grffile->objectspec == NULL) {
5234 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5235 return;
5238 uint8 *objects = AllocaM(uint8, idcount);
5239 for (uint i = 0; i < idcount; i++) {
5240 objects[i] = buf->ReadByte();
5243 uint8 cidcount = buf->ReadByte();
5244 for (uint c = 0; c < cidcount; c++) {
5245 uint8 ctype = buf->ReadByte();
5246 uint16 groupid = buf->ReadWord();
5247 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5249 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5250 if (ctype == CT_INVALID) continue;
5252 for (uint i = 0; i < idcount; i++) {
5253 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5255 if (spec == NULL) {
5256 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5257 continue;
5260 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5264 uint16 groupid = buf->ReadWord();
5265 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5267 for (uint i = 0; i < idcount; i++) {
5268 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5270 if (spec == NULL) {
5271 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5272 continue;
5275 if (spec->grf_prop.grffile != NULL) {
5276 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5277 continue;
5280 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5281 spec->grf_prop.grffile = _cur.grffile;
5282 spec->grf_prop.local_id = objects[i];
5286 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5288 uint8 *railtypes = AllocaM(uint8, idcount);
5289 for (uint i = 0; i < idcount; i++) {
5290 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5293 uint8 cidcount = buf->ReadByte();
5294 for (uint c = 0; c < cidcount; c++) {
5295 uint8 ctype = buf->ReadByte();
5296 uint16 groupid = buf->ReadWord();
5297 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5299 if (ctype >= RTSG_END) continue;
5301 extern RailtypeInfo _railtypes[RAILTYPE_END];
5302 for (uint i = 0; i < idcount; i++) {
5303 if (railtypes[i] != INVALID_RAILTYPE) {
5304 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5306 rti->grffile[ctype] = _cur.grffile;
5307 rti->group[ctype] = _cur.spritegroups[groupid];
5312 /* Railtypes do not use the default group. */
5313 buf->ReadWord();
5316 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5318 uint8 *airports = AllocaM(uint8, idcount);
5319 for (uint i = 0; i < idcount; i++) {
5320 airports[i] = buf->ReadByte();
5323 /* Skip the cargo type section, we only care about the default group */
5324 uint8 cidcount = buf->ReadByte();
5325 buf->Skip(cidcount * 3);
5327 uint16 groupid = buf->ReadWord();
5328 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5330 if (_cur.grffile->airportspec == NULL) {
5331 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5332 return;
5335 for (uint i = 0; i < idcount; i++) {
5336 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5338 if (as == NULL) {
5339 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5340 continue;
5343 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5347 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5349 uint8 *airptiles = AllocaM(uint8, idcount);
5350 for (uint i = 0; i < idcount; i++) {
5351 airptiles[i] = buf->ReadByte();
5354 /* Skip the cargo type section, we only care about the default group */
5355 uint8 cidcount = buf->ReadByte();
5356 buf->Skip(cidcount * 3);
5358 uint16 groupid = buf->ReadWord();
5359 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5361 if (_cur.grffile->airtspec == NULL) {
5362 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5363 return;
5366 for (uint i = 0; i < idcount; i++) {
5367 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5369 if (airtsp == NULL) {
5370 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5371 continue;
5374 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5379 /* Action 0x03 */
5380 static void FeatureMapSpriteGroup(ByteReader *buf)
5382 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5383 * id-list := [<id>] [id-list]
5384 * cargo-list := <cargo-type> <cid> [cargo-list]
5386 * B feature see action 0
5387 * B n-id bits 0-6: how many IDs this definition applies to
5388 * bit 7: if set, this is a wagon override definition (see below)
5389 * B ids the IDs for which this definition applies
5390 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5391 * can be zero, in that case the def-cid is used always
5392 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5393 * W cid cargo ID (sprite group ID) for this type of cargo
5394 * W def-cid default cargo ID (sprite group ID) */
5396 uint8 feature = buf->ReadByte();
5397 uint8 idcount = buf->ReadByte();
5399 /* If idcount is zero, this is a feature callback */
5400 if (idcount == 0) {
5401 /* Skip number of cargo ids? */
5402 buf->ReadByte();
5403 uint16 groupid = buf->ReadWord();
5404 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5406 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5408 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5409 return;
5412 /* Mark the feature as used by the grf (generic callbacks do not count) */
5413 SetBit(_cur.grffile->grf_features, feature);
5415 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5417 switch (feature) {
5418 case GSF_TRAINS:
5419 case GSF_ROADVEHICLES:
5420 case GSF_SHIPS:
5421 case GSF_AIRCRAFT:
5422 VehicleMapSpriteGroup(buf, feature, idcount);
5423 return;
5425 case GSF_CANALS:
5426 CanalMapSpriteGroup(buf, idcount);
5427 return;
5429 case GSF_STATIONS:
5430 StationMapSpriteGroup(buf, idcount);
5431 return;
5433 case GSF_HOUSES:
5434 TownHouseMapSpriteGroup(buf, idcount);
5435 return;
5437 case GSF_INDUSTRIES:
5438 IndustryMapSpriteGroup(buf, idcount);
5439 return;
5441 case GSF_INDUSTRYTILES:
5442 IndustrytileMapSpriteGroup(buf, idcount);
5443 return;
5445 case GSF_CARGOES:
5446 CargoMapSpriteGroup(buf, idcount);
5447 return;
5449 case GSF_AIRPORTS:
5450 AirportMapSpriteGroup(buf, idcount);
5451 return;
5453 case GSF_OBJECTS:
5454 ObjectMapSpriteGroup(buf, idcount);
5455 break;
5457 case GSF_RAILTYPES:
5458 RailTypeMapSpriteGroup(buf, idcount);
5459 break;
5461 case GSF_AIRPORTTILES:
5462 AirportTileMapSpriteGroup(buf, idcount);
5463 return;
5465 default:
5466 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5467 return;
5471 /* Action 0x04 */
5472 static void FeatureNewName(ByteReader *buf)
5474 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5476 * B veh-type see action 0 (as 00..07, + 0A
5477 * But IF veh-type = 48, then generic text
5478 * B language-id If bit 6 is set, This is the extended language scheme,
5479 * with up to 64 language.
5480 * Otherwise, it is a mapping where set bits have meaning
5481 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5482 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5483 * B num-veh number of vehicles which are getting a new name
5484 * B/W offset number of the first vehicle that gets a new name
5485 * Byte : ID of vehicle to change
5486 * Word : ID of string to change/add
5487 * S data new texts, each of them zero-terminated, after
5488 * which the next name begins. */
5490 bool new_scheme = _cur.grffile->grf_version >= 7;
5492 uint8 feature = buf->ReadByte();
5493 uint8 lang = buf->ReadByte();
5494 uint8 num = buf->ReadByte();
5495 bool generic = HasBit(lang, 7);
5496 uint16 id;
5497 if (generic) {
5498 id = buf->ReadWord();
5499 } else if (feature <= GSF_AIRCRAFT) {
5500 id = buf->ReadExtendedByte();
5501 } else {
5502 id = buf->ReadByte();
5505 ClrBit(lang, 7);
5507 uint16 endid = id + num;
5509 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5510 id, endid, feature, lang);
5512 for (; id < endid && buf->HasData(); id++) {
5513 const char *name = buf->ReadString();
5514 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5516 switch (feature) {
5517 case GSF_TRAINS:
5518 case GSF_ROADVEHICLES:
5519 case GSF_SHIPS:
5520 case GSF_AIRCRAFT:
5521 if (!generic) {
5522 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5523 if (e == NULL) break;
5524 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5525 e->info.string_id = string;
5526 } else {
5527 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5529 break;
5531 default:
5532 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5533 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5534 break;
5537 switch (GB(id, 8, 8)) {
5538 case 0xC4: // Station class name
5539 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5540 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5541 } else {
5542 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5543 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5545 break;
5547 case 0xC5: // Station name
5548 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5549 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5550 } else {
5551 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5553 break;
5555 case 0xC7: // Airporttile name
5556 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5557 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5558 } else {
5559 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5561 break;
5563 case 0xC9: // House name
5564 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5565 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5566 } else {
5567 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5569 break;
5571 default:
5572 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5573 break;
5575 break;
5581 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5582 * @param num The number of sprites to load.
5583 * @param offset Offset from the base.
5584 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5585 * @param name Used for error warnings.
5586 * @return The number of sprites that is going to be skipped.
5588 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5591 if (offset >= max_sprites) {
5592 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5593 uint orig_num = num;
5594 num = 0;
5595 return orig_num;
5598 if (offset + num > max_sprites) {
5599 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5600 uint orig_num = num;
5601 num = max(max_sprites - offset, 0);
5602 return orig_num - num;
5605 return 0;
5609 /** The type of action 5 type. */
5610 enum Action5BlockType {
5611 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5612 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5613 A5BLOCK_INVALID, ///< unknown/not-implemented type
5615 /** Information about a single action 5 type. */
5616 struct Action5Type {
5617 Action5BlockType block_type; ///< How is this Action5 type processed?
5618 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5619 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5620 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5621 const char *name; ///< Name for error messages.
5624 /** The information about action 5 types. */
5625 static const Action5Type _action5_types[] = {
5626 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5627 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5628 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5629 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5630 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5631 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5632 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5633 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5634 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5635 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5636 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5637 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5638 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5639 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5640 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5641 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5642 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5643 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5644 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5645 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5646 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5647 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5648 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5649 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5650 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5651 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5654 /* Action 0x05 */
5655 static void GraphicsNew(ByteReader *buf)
5657 /* <05> <graphics-type> <num-sprites> <other data...>
5659 * B graphics-type What set of graphics the sprites define.
5660 * E num-sprites How many sprites are in this set?
5661 * V other data Graphics type specific data. Currently unused. */
5662 /* TODO */
5664 uint8 type = buf->ReadByte();
5665 uint16 num = buf->ReadExtendedByte();
5666 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5667 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5669 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5670 /* Special not-TTDP-compatible case used in openttd.grf
5671 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5672 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5673 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5674 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5675 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5676 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5677 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5678 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5679 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5680 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5681 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5682 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5683 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5684 return;
5687 /* Supported type? */
5688 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5689 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5690 _cur.skip_sprites = num;
5691 return;
5694 const Action5Type *action5_type = &_action5_types[type];
5696 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5697 * except for the long version of the shore type:
5698 * Ignore offset if not allowed */
5699 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5700 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5701 offset = 0;
5704 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5705 * This does not make sense, if <offset> is allowed */
5706 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5707 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);
5708 _cur.skip_sprites = num;
5709 return;
5712 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5713 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5714 SpriteID replace = action5_type->sprite_base + offset;
5716 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5717 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);
5719 for (; num > 0; num--) {
5720 _cur.nfo_line++;
5721 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5724 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5726 _cur.skip_sprites = skip_num;
5729 /* Action 0x05 (SKIP) */
5730 static void SkipAct5(ByteReader *buf)
5732 /* Ignore type byte */
5733 buf->ReadByte();
5735 /* Skip the sprites of this action */
5736 _cur.skip_sprites = buf->ReadExtendedByte();
5738 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5742 * Reads a variable common to VarAction2 and Action7/9/D.
5744 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5745 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5747 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5748 * @param value returns the value of the variable.
5749 * @param grffile NewGRF querying the variable
5750 * @return true iff the variable is known and the value is returned in 'value'.
5752 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5754 switch (param) {
5755 case 0x00: // current date
5756 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5757 return true;
5759 case 0x01: // current year
5760 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5761 return true;
5763 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)
5764 YearMonthDay ymd;
5765 ConvertDateToYMD(_date, &ymd);
5766 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5767 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5768 return true;
5771 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5772 *value = _settings_game.game_creation.landscape;
5773 return true;
5775 case 0x06: // road traffic side, bit 4 clear=left, set=right
5776 *value = _settings_game.vehicle.road_side << 4;
5777 return true;
5779 case 0x09: // date fraction
5780 *value = _date_fract * 885;
5781 return true;
5783 case 0x0A: // animation counter
5784 *value = _tick_counter;
5785 return true;
5787 case 0x0B: { // TTDPatch version
5788 uint major = 2;
5789 uint minor = 6;
5790 uint revision = 1; // special case: 2.0.1 is 2.0.10
5791 uint build = 1382;
5792 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5793 return true;
5796 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5797 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5798 return true;
5800 case 0x0E: // Y-offset for train sprites
5801 *value = _cur.grffile->traininfo_vehicle_pitch;
5802 return true;
5804 case 0x0F: // Rail track type cost factors
5805 *value = 0;
5806 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5807 if (_settings_game.vehicle.disable_elrails) {
5808 /* skip elrail multiplier - disabled */
5809 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5810 } else {
5811 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5812 /* Skip monorail multiplier - no space in result */
5814 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5815 return true;
5817 case 0x11: // current rail tool type
5818 *value = 0; // constant fake value to avoid desync
5819 return true;
5821 case 0x12: // Game mode
5822 *value = _game_mode;
5823 return true;
5825 /* case 0x13: // Tile refresh offset to left not implemented */
5826 /* case 0x14: // Tile refresh offset to right not implemented */
5827 /* case 0x15: // Tile refresh offset upwards not implemented */
5828 /* case 0x16: // Tile refresh offset downwards not implemented */
5829 /* case 0x17: // temperate snow line not implemented */
5831 case 0x1A: // Always -1
5832 *value = UINT_MAX;
5833 return true;
5835 case 0x1B: // Display options
5836 *value = 0x3F; // constant fake value to avoid desync
5837 return true;
5839 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5840 *value = 1;
5841 return true;
5843 case 0x1E: // Miscellaneous GRF features
5844 *value = _misc_grf_features;
5846 /* Add the local flags */
5847 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5848 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5849 return true;
5851 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5853 case 0x20: { // snow line height
5854 byte snowline = GetSnowLine();
5855 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5856 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5857 } else {
5858 /* No snow */
5859 *value = 0xFF;
5861 return true;
5864 case 0x21: // OpenTTD version
5865 *value = _openttd_newgrf_version;
5866 return true;
5868 case 0x22: // difficulty level
5869 *value = SP_CUSTOM;
5870 return true;
5872 case 0x23: // long format date
5873 *value = _date;
5874 return true;
5876 case 0x24: // long format year
5877 *value = _cur_year;
5878 return true;
5880 default: return false;
5884 static uint32 GetParamVal(byte param, uint32 *cond_val)
5886 /* First handle variable common with VarAction2 */
5887 uint32 value;
5888 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5890 /* Non-common variable */
5891 switch (param) {
5892 case 0x84: { // GRF loading stage
5893 uint32 res = 0;
5895 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5896 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5897 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5898 return res;
5901 case 0x85: // TTDPatch flags, only for bit tests
5902 if (cond_val == NULL) {
5903 /* Supported in Action 0x07 and 0x09, not 0x0D */
5904 return 0;
5905 } else {
5906 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5907 *cond_val %= 0x20;
5908 return param_val;
5911 case 0x88: // GRF ID check
5912 return 0;
5914 /* case 0x99: Global ID offset not implemented */
5916 default:
5917 /* GRF Parameter */
5918 if (param < 0x80) return _cur.grffile->GetParam(param);
5920 /* In-game variable. */
5921 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5922 return UINT_MAX;
5926 /* Action 0x06 */
5927 static void CfgApply(ByteReader *buf)
5929 /* <06> <param-num> <param-size> <offset> ... <FF>
5931 * B param-num Number of parameter to substitute (First = "zero")
5932 * Ignored if that parameter was not specified in newgrf.cfg
5933 * B param-size How many bytes to replace. If larger than 4, the
5934 * bytes of the following parameter are used. In that
5935 * case, nothing is applied unless *all* parameters
5936 * were specified.
5937 * B offset Offset into data from beginning of next sprite
5938 * to place where parameter is to be stored. */
5940 /* Preload the next sprite */
5941 size_t pos = FioGetPos();
5942 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5943 uint8 type = FioReadByte();
5944 byte *preload_sprite = NULL;
5946 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5947 if (type == 0xFF) {
5948 preload_sprite = MallocT<byte>(num);
5949 FioReadBlock(preload_sprite, num);
5952 /* Reset the file position to the start of the next sprite */
5953 FioSeekTo(pos, SEEK_SET);
5955 if (type != 0xFF) {
5956 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5957 free(preload_sprite);
5958 return;
5961 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5962 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5963 if (it != _grf_line_to_action6_sprite_override.end()) {
5964 free(preload_sprite);
5965 preload_sprite = _grf_line_to_action6_sprite_override[location];
5966 } else {
5967 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5970 /* Now perform the Action 0x06 on our data. */
5972 for (;;) {
5973 uint i;
5974 uint param_num;
5975 uint param_size;
5976 uint offset;
5977 bool add_value;
5979 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5980 param_num = buf->ReadByte();
5981 if (param_num == 0xFF) break;
5983 /* Get the size of the parameter to use. If the size covers multiple
5984 * double words, sequential parameter values are used. */
5985 param_size = buf->ReadByte();
5987 /* Bit 7 of param_size indicates we should add to the original value
5988 * instead of replacing it. */
5989 add_value = HasBit(param_size, 7);
5990 param_size = GB(param_size, 0, 7);
5992 /* Where to apply the data to within the pseudo sprite data. */
5993 offset = buf->ReadExtendedByte();
5995 /* If the parameter is a GRF parameter (not an internal variable) check
5996 * if it (and all further sequential parameters) has been defined. */
5997 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5998 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5999 break;
6002 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6004 bool carry = false;
6005 for (i = 0; i < param_size && offset + i < num; i++) {
6006 uint32 value = GetParamVal(param_num + i / 4, NULL);
6007 /* Reset carry flag for each iteration of the variable (only really
6008 * matters if param_size is greater than 4) */
6009 if (i % 4 == 0) carry = false;
6011 if (add_value) {
6012 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6013 preload_sprite[offset + i] = GB(new_value, 0, 8);
6014 /* Check if the addition overflowed */
6015 carry = new_value >= 256;
6016 } else {
6017 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6024 * Disable a static NewGRF when it is influencing another (non-static)
6025 * NewGRF as this could cause desyncs.
6027 * We could just tell the NewGRF querying that the file doesn't exist,
6028 * but that might give unwanted results. Disabling the NewGRF gives the
6029 * best result as no NewGRF author can complain about that.
6030 * @param c The NewGRF to disable.
6032 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6034 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6035 error->data = stredup(_cur.grfconfig->GetName());
6038 /* Action 0x07
6039 * Action 0x09 */
6040 static void SkipIf(ByteReader *buf)
6042 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6044 * B param-num
6045 * B param-size
6046 * B condition-type
6047 * V value
6048 * B num-sprites */
6049 /* TODO: More params. More condition types. */
6050 uint32 cond_val = 0;
6051 uint32 mask = 0;
6052 bool result;
6054 uint8 param = buf->ReadByte();
6055 uint8 paramsize = buf->ReadByte();
6056 uint8 condtype = buf->ReadByte();
6058 if (condtype < 2) {
6059 /* Always 1 for bit tests, the given value should be ignored. */
6060 paramsize = 1;
6063 switch (paramsize) {
6064 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6065 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6066 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6067 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6068 default: break;
6071 if (param < 0x80 && _cur.grffile->param_end <= param) {
6072 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6073 return;
6076 uint32 param_val = GetParamVal(param, &cond_val);
6078 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6081 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6082 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6083 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6084 * So, when the condition type is one of those, the specific variable
6085 * 0x88 code is skipped, so the "general" code for the cargo
6086 * availability conditions kicks in.
6088 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6089 /* GRF ID checks */
6091 GRFConfig *c = GetGRFConfig(cond_val, mask);
6093 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6094 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6095 c = NULL;
6098 if (condtype != 10 && c == NULL) {
6099 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6100 return;
6103 switch (condtype) {
6104 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6105 case 0x06: // Is GRFID active?
6106 result = c->status == GCS_ACTIVATED;
6107 break;
6109 case 0x07: // Is GRFID non-active?
6110 result = c->status != GCS_ACTIVATED;
6111 break;
6113 case 0x08: // GRFID is not but will be active?
6114 result = c->status == GCS_INITIALISED;
6115 break;
6117 case 0x09: // GRFID is or will be active?
6118 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6119 break;
6121 case 0x0A: // GRFID is not nor will be active
6122 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6123 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6124 break;
6126 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6128 } else {
6129 /* Parameter or variable tests */
6130 switch (condtype) {
6131 case 0x00: result = !!(param_val & (1 << cond_val));
6132 break;
6133 case 0x01: result = !(param_val & (1 << cond_val));
6134 break;
6135 case 0x02: result = (param_val & mask) == cond_val;
6136 break;
6137 case 0x03: result = (param_val & mask) != cond_val;
6138 break;
6139 case 0x04: result = (param_val & mask) < cond_val;
6140 break;
6141 case 0x05: result = (param_val & mask) > cond_val;
6142 break;
6143 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6144 break;
6145 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6146 break;
6147 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6148 break;
6149 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6150 break;
6152 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6156 if (!result) {
6157 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6158 return;
6161 uint8 numsprites = buf->ReadByte();
6163 /* numsprites can be a GOTO label if it has been defined in the GRF
6164 * file. The jump will always be the first matching label that follows
6165 * the current nfo_line. If no matching label is found, the first matching
6166 * label in the file is used. */
6167 GRFLabel *choice = NULL;
6168 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6169 if (label->label != numsprites) continue;
6171 /* Remember a goto before the current line */
6172 if (choice == NULL) choice = label;
6173 /* If we find a label here, this is definitely good */
6174 if (label->nfo_line > _cur.nfo_line) {
6175 choice = label;
6176 break;
6180 if (choice != NULL) {
6181 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6182 FioSeekTo(choice->pos, SEEK_SET);
6183 _cur.nfo_line = choice->nfo_line;
6184 return;
6187 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6188 _cur.skip_sprites = numsprites;
6189 if (_cur.skip_sprites == 0) {
6190 /* Zero means there are no sprites to skip, so
6191 * we use -1 to indicate that all further
6192 * sprites should be skipped. */
6193 _cur.skip_sprites = -1;
6195 /* If an action 8 hasn't been encountered yet, disable the grf. */
6196 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6197 DisableGrf();
6203 /* Action 0x08 (GLS_FILESCAN) */
6204 static void ScanInfo(ByteReader *buf)
6206 uint8 grf_version = buf->ReadByte();
6207 uint32 grfid = buf->ReadDWord();
6208 const char *name = buf->ReadString();
6210 _cur.grfconfig->ident.grfid = grfid;
6212 if (grf_version < 2 || grf_version > 8) {
6213 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6214 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);
6217 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6218 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6220 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6222 if (buf->HasData()) {
6223 const char *info = buf->ReadString();
6224 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6227 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6228 _cur.skip_sprites = -1;
6231 /* Action 0x08 */
6232 static void GRFInfo(ByteReader *buf)
6234 /* <08> <version> <grf-id> <name> <info>
6236 * B version newgrf version, currently 06
6237 * 4*B grf-id globally unique ID of this .grf file
6238 * S name name of this .grf set
6239 * S info string describing the set, and e.g. author and copyright */
6241 uint8 version = buf->ReadByte();
6242 uint32 grfid = buf->ReadDWord();
6243 const char *name = buf->ReadString();
6245 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6246 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6247 return;
6250 if (_cur.grffile->grfid != grfid) {
6251 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));
6252 _cur.grffile->grfid = grfid;
6255 _cur.grffile->grf_version = version;
6256 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6258 /* Do swap the GRFID for displaying purposes since people expect that */
6259 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);
6262 /* Action 0x0A */
6263 static void SpriteReplace(ByteReader *buf)
6265 /* <0A> <num-sets> <set1> [<set2> ...]
6266 * <set>: <num-sprites> <first-sprite>
6268 * B num-sets How many sets of sprites to replace.
6269 * Each set:
6270 * B num-sprites How many sprites are in this set
6271 * W first-sprite First sprite number to replace */
6273 uint8 num_sets = buf->ReadByte();
6275 for (uint i = 0; i < num_sets; i++) {
6276 uint8 num_sprites = buf->ReadByte();
6277 uint16 first_sprite = buf->ReadWord();
6279 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6280 i, num_sprites, first_sprite
6283 for (uint j = 0; j < num_sprites; j++) {
6284 int load_index = first_sprite + j;
6285 _cur.nfo_line++;
6286 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6288 /* Shore sprites now located at different addresses.
6289 * So detect when the old ones get replaced. */
6290 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6291 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6297 /* Action 0x0A (SKIP) */
6298 static void SkipActA(ByteReader *buf)
6300 uint8 num_sets = buf->ReadByte();
6302 for (uint i = 0; i < num_sets; i++) {
6303 /* Skip the sprites this replaces */
6304 _cur.skip_sprites += buf->ReadByte();
6305 /* But ignore where they go */
6306 buf->ReadWord();
6309 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6312 /* Action 0x0B */
6313 static void GRFLoadError(ByteReader *buf)
6315 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6317 * B severity 00: notice, contine loading grf file
6318 * 01: warning, continue loading grf file
6319 * 02: error, but continue loading grf file, and attempt
6320 * loading grf again when loading or starting next game
6321 * 03: error, abort loading and prevent loading again in
6322 * the future (only when restarting the patch)
6323 * B language-id see action 4, use 1F for built-in error messages
6324 * B message-id message to show, see below
6325 * S message for custom messages (message-id FF), text of the message
6326 * not present for built-in messages.
6327 * V data additional data for built-in (or custom) messages
6328 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6330 static const StringID msgstr[] = {
6331 STR_NEWGRF_ERROR_VERSION_NUMBER,
6332 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6333 STR_NEWGRF_ERROR_UNSET_SWITCH,
6334 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6335 STR_NEWGRF_ERROR_LOAD_BEFORE,
6336 STR_NEWGRF_ERROR_LOAD_AFTER,
6337 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6340 static const StringID sevstr[] = {
6341 STR_NEWGRF_ERROR_MSG_INFO,
6342 STR_NEWGRF_ERROR_MSG_WARNING,
6343 STR_NEWGRF_ERROR_MSG_ERROR,
6344 STR_NEWGRF_ERROR_MSG_FATAL
6347 byte severity = buf->ReadByte();
6348 byte lang = buf->ReadByte();
6349 byte message_id = buf->ReadByte();
6351 /* Skip the error if it isn't valid for the current language. */
6352 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6354 /* Skip the error until the activation stage unless bit 7 of the severity
6355 * is set. */
6356 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6357 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6358 return;
6360 ClrBit(severity, 7);
6362 if (severity >= lengthof(sevstr)) {
6363 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6364 severity = 2;
6365 } else if (severity == 3) {
6366 /* This is a fatal error, so make sure the GRF is deactivated and no
6367 * more of it gets loaded. */
6368 DisableGrf();
6370 /* Make sure we show fatal errors, instead of silly infos from before */
6371 delete _cur.grfconfig->error;
6372 _cur.grfconfig->error = NULL;
6375 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6376 grfmsg(7, "GRFLoadError: Invalid message id.");
6377 return;
6380 if (buf->Remaining() <= 1) {
6381 grfmsg(7, "GRFLoadError: No message data supplied.");
6382 return;
6385 /* For now we can only show one message per newgrf file. */
6386 if (_cur.grfconfig->error != NULL) return;
6388 GRFError *error = new GRFError(sevstr[severity]);
6390 if (message_id == 0xFF) {
6391 /* This is a custom error message. */
6392 if (buf->HasData()) {
6393 const char *message = buf->ReadString();
6395 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6396 } else {
6397 grfmsg(7, "GRFLoadError: No custom message supplied.");
6398 error->custom_message = stredup("");
6400 } else {
6401 error->message = msgstr[message_id];
6404 if (buf->HasData()) {
6405 const char *data = buf->ReadString();
6407 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6408 } else {
6409 grfmsg(7, "GRFLoadError: No message data supplied.");
6410 error->data = stredup("");
6413 /* Only two parameter numbers can be used in the string. */
6414 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6415 uint param_number = buf->ReadByte();
6416 error->param_value[i] = _cur.grffile->GetParam(param_number);
6419 _cur.grfconfig->error = error;
6422 /* Action 0x0C */
6423 static void GRFComment(ByteReader *buf)
6425 /* <0C> [<ignored...>]
6427 * V ignored Anything following the 0C is ignored */
6429 if (!buf->HasData()) return;
6431 const char *text = buf->ReadString();
6432 grfmsg(2, "GRFComment: %s", text);
6435 /* Action 0x0D (GLS_SAFETYSCAN) */
6436 static void SafeParamSet(ByteReader *buf)
6438 uint8 target = buf->ReadByte();
6440 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6441 if (target < 0x80 || target == 0x9E) return;
6443 /* GRM could be unsafe, but as here it can only happen after other GRFs
6444 * are loaded, it should be okay. If the GRF tried to use the slots it
6445 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6446 * sprites is considered safe. */
6448 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6450 /* Skip remainder of GRF */
6451 _cur.skip_sprites = -1;
6455 static uint32 GetPatchVariable(uint8 param)
6457 switch (param) {
6458 /* start year - 1920 */
6459 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6461 /* freight trains weight factor */
6462 case 0x0E: return _settings_game.vehicle.freight_trains;
6464 /* empty wagon speed increase */
6465 case 0x0F: return 0;
6467 /* plane speed factor; our patch option is reversed from TTDPatch's,
6468 * the following is good for 1x, 2x and 4x (most common?) and...
6469 * well not really for 3x. */
6470 case 0x10:
6471 switch (_settings_game.vehicle.plane_speed) {
6472 default:
6473 case 4: return 1;
6474 case 3: return 2;
6475 case 2: return 2;
6476 case 1: return 4;
6480 /* 2CC colourmap base sprite */
6481 case 0x11: return SPR_2CCMAP_BASE;
6483 /* map size: format = -MABXYSS
6484 * M : the type of map
6485 * bit 0 : set : squared map. Bit 1 is now not relevant
6486 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6487 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6488 * clear : X is the bigger edge.
6489 * A : minimum edge(log2) of the map
6490 * B : maximum edge(log2) of the map
6491 * XY : edges(log2) of each side of the map.
6492 * SS : combination of both X and Y, thus giving the size(log2) of the map
6494 case 0x13: {
6495 byte map_bits = 0;
6496 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6497 byte log_Y = MapLogY() - 6;
6498 byte max_edge = max(log_X, log_Y);
6500 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6501 SetBit(map_bits, 0);
6502 } else {
6503 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6506 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6507 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6510 /* The maximum height of the map. */
6511 case 0x14:
6512 return _settings_game.construction.max_heightlevel;
6514 /* Extra foundations base sprite */
6515 case 0x15:
6516 return SPR_SLOPES_BASE;
6518 /* Shore base sprite */
6519 case 0x16:
6520 return SPR_SHORE_BASE;
6522 default:
6523 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6524 return 0;
6529 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6531 uint start = 0;
6532 uint size = 0;
6534 if (op == 6) {
6535 /* Return GRFID of set that reserved ID */
6536 return grm[_cur.grffile->GetParam(target)];
6539 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6540 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6542 for (uint i = start; i < num_ids; i++) {
6543 if (grm[i] == 0) {
6544 size++;
6545 } else {
6546 if (op == 2 || op == 3) break;
6547 start = i + 1;
6548 size = 0;
6551 if (size == count) break;
6554 if (size == count) {
6555 /* Got the slot... */
6556 if (op == 0 || op == 3) {
6557 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6558 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6560 return start;
6563 /* Unable to allocate */
6564 if (op != 4 && op != 5) {
6565 /* Deactivate GRF */
6566 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6567 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6568 return UINT_MAX;
6571 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6572 return UINT_MAX;
6576 /** Action 0x0D: Set parameter */
6577 static void ParamSet(ByteReader *buf)
6579 /* <0D> <target> <operation> <source1> <source2> [<data>]
6581 * B target parameter number where result is stored
6582 * B operation operation to perform, see below
6583 * B source1 first source operand
6584 * B source2 second source operand
6585 * D data data to use in the calculation, not necessary
6586 * if both source1 and source2 refer to actual parameters
6588 * Operations
6589 * 00 Set parameter equal to source1
6590 * 01 Addition, source1 + source2
6591 * 02 Subtraction, source1 - source2
6592 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6593 * 04 Signed multiplication, source1 * source2 (both signed)
6594 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6595 * signed quantity; left shift if positive and right shift if
6596 * negative, source1 is unsigned)
6597 * 06 Signed bit shift, source1 by source2
6598 * (source2 like in 05, and source1 as well)
6601 uint8 target = buf->ReadByte();
6602 uint8 oper = buf->ReadByte();
6603 uint32 src1 = buf->ReadByte();
6604 uint32 src2 = buf->ReadByte();
6606 uint32 data = 0;
6607 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6609 /* You can add 80 to the operation to make it apply only if the target
6610 * is not defined yet. In this respect, a parameter is taken to be
6611 * defined if any of the following applies:
6612 * - it has been set to any value in the newgrf(w).cfg parameter list
6613 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6614 * an earlier action D */
6615 if (HasBit(oper, 7)) {
6616 if (target < 0x80 && target < _cur.grffile->param_end) {
6617 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6618 return;
6621 oper = GB(oper, 0, 7);
6624 if (src2 == 0xFE) {
6625 if (GB(data, 0, 8) == 0xFF) {
6626 if (data == 0x0000FFFF) {
6627 /* Patch variables */
6628 src1 = GetPatchVariable(src1);
6629 } else {
6630 /* GRF Resource Management */
6631 uint8 op = src1;
6632 uint8 feature = GB(data, 8, 8);
6633 uint16 count = GB(data, 16, 16);
6635 if (_cur.stage == GLS_RESERVE) {
6636 if (feature == 0x08) {
6637 /* General sprites */
6638 if (op == 0) {
6639 /* Check if the allocated sprites will fit below the original sprite limit */
6640 if (_cur.spriteid + count >= 16384) {
6641 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6642 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6643 return;
6646 /* Reserve space at the current sprite ID */
6647 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6648 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6649 _cur.spriteid += count;
6652 /* Ignore GRM result during reservation */
6653 src1 = 0;
6654 } else if (_cur.stage == GLS_ACTIVATION) {
6655 switch (feature) {
6656 case 0x00: // Trains
6657 case 0x01: // Road Vehicles
6658 case 0x02: // Ships
6659 case 0x03: // Aircraft
6660 if (!_settings_game.vehicle.dynamic_engines) {
6661 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6662 if (_cur.skip_sprites == -1) return;
6663 } else {
6664 /* GRM does not apply for dynamic engine allocation. */
6665 switch (op) {
6666 case 2:
6667 case 3:
6668 src1 = _cur.grffile->GetParam(target);
6669 break;
6671 default:
6672 src1 = 0;
6673 break;
6676 break;
6678 case 0x08: // General sprites
6679 switch (op) {
6680 case 0:
6681 /* Return space reserved during reservation stage */
6682 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6683 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6684 break;
6686 case 1:
6687 src1 = _cur.spriteid;
6688 break;
6690 default:
6691 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6692 return;
6694 break;
6696 case 0x0B: // Cargo
6697 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6698 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6699 if (_cur.skip_sprites == -1) return;
6700 break;
6702 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6704 } else {
6705 /* Ignore GRM during initialization */
6706 src1 = 0;
6709 } else {
6710 /* Read another GRF File's parameter */
6711 const GRFFile *file = GetFileByGRFID(data);
6712 GRFConfig *c = GetGRFConfig(data);
6713 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6714 /* Disable the read GRF if it is a static NewGRF. */
6715 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6716 src1 = 0;
6717 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6718 src1 = 0;
6719 } else if (src1 == 0xFE) {
6720 src1 = c->version;
6721 } else {
6722 src1 = file->GetParam(src1);
6725 } else {
6726 /* The source1 and source2 operands refer to the grf parameter number
6727 * like in action 6 and 7. In addition, they can refer to the special
6728 * variables available in action 7, or they can be FF to use the value
6729 * of <data>. If referring to parameters that are undefined, a value
6730 * of 0 is used instead. */
6731 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6732 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6735 /* TODO: You can access the parameters of another GRF file by using
6736 * source2=FE, source1=the other GRF's parameter number and data=GRF
6737 * ID. This is only valid with operation 00 (set). If the GRF ID
6738 * cannot be found, a value of 0 is used for the parameter value
6739 * instead. */
6741 uint32 res;
6742 switch (oper) {
6743 case 0x00:
6744 res = src1;
6745 break;
6747 case 0x01:
6748 res = src1 + src2;
6749 break;
6751 case 0x02:
6752 res = src1 - src2;
6753 break;
6755 case 0x03:
6756 res = src1 * src2;
6757 break;
6759 case 0x04:
6760 res = (int32)src1 * (int32)src2;
6761 break;
6763 case 0x05:
6764 if ((int32)src2 < 0) {
6765 res = src1 >> -(int32)src2;
6766 } else {
6767 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6769 break;
6771 case 0x06:
6772 if ((int32)src2 < 0) {
6773 res = (int32)src1 >> -(int32)src2;
6774 } else {
6775 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6777 break;
6779 case 0x07: // Bitwise AND
6780 res = src1 & src2;
6781 break;
6783 case 0x08: // Bitwise OR
6784 res = src1 | src2;
6785 break;
6787 case 0x09: // Unsigned division
6788 if (src2 == 0) {
6789 res = src1;
6790 } else {
6791 res = src1 / src2;
6793 break;
6795 case 0x0A: // Signed divison
6796 if (src2 == 0) {
6797 res = src1;
6798 } else {
6799 res = (int32)src1 / (int32)src2;
6801 break;
6803 case 0x0B: // Unsigned modulo
6804 if (src2 == 0) {
6805 res = src1;
6806 } else {
6807 res = src1 % src2;
6809 break;
6811 case 0x0C: // Signed modulo
6812 if (src2 == 0) {
6813 res = src1;
6814 } else {
6815 res = (int32)src1 % (int32)src2;
6817 break;
6819 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6822 switch (target) {
6823 case 0x8E: // Y-Offset for train sprites
6824 _cur.grffile->traininfo_vehicle_pitch = res;
6825 break;
6827 case 0x8F: { // Rail track type cost factors
6828 extern RailtypeInfo _railtypes[RAILTYPE_END];
6829 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6830 if (_settings_game.vehicle.disable_elrails) {
6831 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6832 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6833 } else {
6834 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6835 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6837 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6838 break;
6841 /* @todo implement */
6842 case 0x93: // Tile refresh offset to left
6843 case 0x94: // Tile refresh offset to right
6844 case 0x95: // Tile refresh offset upwards
6845 case 0x96: // Tile refresh offset downwards
6846 case 0x97: // Snow line height
6847 case 0x99: // Global ID offset
6848 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6849 break;
6851 case 0x9E: // Miscellaneous GRF features
6852 /* Set train list engine width */
6853 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6854 /* Remove the local flags from the global flags */
6855 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6857 /* Only copy safe bits for static grfs */
6858 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6859 uint32 safe_bits = 0;
6860 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6862 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6863 } else {
6864 _misc_grf_features = res;
6866 break;
6868 case 0x9F: // locale-dependent settings
6869 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6870 break;
6872 default:
6873 if (target < 0x80) {
6874 _cur.grffile->param[target] = res;
6875 /* param is zeroed by default */
6876 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6877 } else {
6878 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6880 break;
6884 /* Action 0x0E (GLS_SAFETYSCAN) */
6885 static void SafeGRFInhibit(ByteReader *buf)
6887 /* <0E> <num> <grfids...>
6889 * B num Number of GRFIDs that follow
6890 * D grfids GRFIDs of the files to deactivate */
6892 uint8 num = buf->ReadByte();
6894 for (uint i = 0; i < num; i++) {
6895 uint32 grfid = buf->ReadDWord();
6897 /* GRF is unsafe it if tries to deactivate other GRFs */
6898 if (grfid != _cur.grfconfig->ident.grfid) {
6899 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6901 /* Skip remainder of GRF */
6902 _cur.skip_sprites = -1;
6904 return;
6909 /* Action 0x0E */
6910 static void GRFInhibit(ByteReader *buf)
6912 /* <0E> <num> <grfids...>
6914 * B num Number of GRFIDs that follow
6915 * D grfids GRFIDs of the files to deactivate */
6917 uint8 num = buf->ReadByte();
6919 for (uint i = 0; i < num; i++) {
6920 uint32 grfid = buf->ReadDWord();
6921 GRFConfig *file = GetGRFConfig(grfid);
6923 /* Unset activation flag */
6924 if (file != NULL && file != _cur.grfconfig) {
6925 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6926 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6927 error->data = stredup(_cur.grfconfig->GetName());
6932 /** Action 0x0F - Define Town names */
6933 static void FeatureTownName(ByteReader *buf)
6935 /* <0F> <id> <style-name> <num-parts> <parts>
6937 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6938 * V style-name Name of the style (only for final definition)
6939 * B num-parts Number of parts in this definition
6940 * V parts The parts */
6942 uint32 grfid = _cur.grffile->grfid;
6944 GRFTownName *townname = AddGRFTownName(grfid);
6946 byte id = buf->ReadByte();
6947 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6949 if (HasBit(id, 7)) {
6950 /* Final definition */
6951 ClrBit(id, 7);
6952 bool new_scheme = _cur.grffile->grf_version >= 7;
6954 byte lang = buf->ReadByte();
6956 byte nb_gen = townname->nb_gen;
6957 do {
6958 ClrBit(lang, 7);
6960 const char *name = buf->ReadString();
6962 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6963 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6964 free(lang_name);
6966 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6968 lang = buf->ReadByte();
6969 } while (lang != 0);
6970 townname->id[nb_gen] = id;
6971 townname->nb_gen++;
6974 byte nb = buf->ReadByte();
6975 grfmsg(6, "FeatureTownName: %u parts", nb);
6977 townname->nbparts[id] = nb;
6978 townname->partlist[id] = CallocT<NamePartList>(nb);
6980 for (int i = 0; i < nb; i++) {
6981 byte nbtext = buf->ReadByte();
6982 townname->partlist[id][i].bitstart = buf->ReadByte();
6983 townname->partlist[id][i].bitcount = buf->ReadByte();
6984 townname->partlist[id][i].maxprob = 0;
6985 townname->partlist[id][i].partcount = nbtext;
6986 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6987 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);
6989 for (int j = 0; j < nbtext; j++) {
6990 byte prob = buf->ReadByte();
6992 if (HasBit(prob, 7)) {
6993 byte ref_id = buf->ReadByte();
6995 if (townname->nbparts[ref_id] == 0) {
6996 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6997 DelGRFTownName(grfid);
6998 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6999 return;
7002 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7003 townname->partlist[id][i].parts[j].data.id = ref_id;
7004 } else {
7005 const char *text = buf->ReadString();
7006 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7007 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7009 townname->partlist[id][i].parts[j].prob = prob;
7010 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7012 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7016 /** Action 0x10 - Define goto label */
7017 static void DefineGotoLabel(ByteReader *buf)
7019 /* <10> <label> [<comment>]
7021 * B label The label to define
7022 * V comment Optional comment - ignored */
7024 byte nfo_label = buf->ReadByte();
7026 GRFLabel *label = MallocT<GRFLabel>(1);
7027 label->label = nfo_label;
7028 label->nfo_line = _cur.nfo_line;
7029 label->pos = FioGetPos();
7030 label->next = NULL;
7032 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7033 if (_cur.grffile->label == NULL) {
7034 _cur.grffile->label = label;
7035 } else {
7036 /* Attach the label to the end of the list */
7037 GRFLabel *l;
7038 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7039 l->next = label;
7042 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7046 * Process a sound import from another GRF file.
7047 * @param sound Destination for sound.
7049 static void ImportGRFSound(SoundEntry *sound)
7051 const GRFFile *file;
7052 uint32 grfid = FioReadDword();
7053 SoundID sound_id = FioReadWord();
7055 file = GetFileByGRFID(grfid);
7056 if (file == NULL || file->sound_offset == 0) {
7057 grfmsg(1, "ImportGRFSound: Source file not available");
7058 return;
7061 if (sound_id >= file->num_sounds) {
7062 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7063 return;
7066 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7068 *sound = *GetSound(file->sound_offset + sound_id);
7070 /* Reset volume and priority, which TTDPatch doesn't copy */
7071 sound->volume = 128;
7072 sound->priority = 0;
7076 * Load a sound from a file.
7077 * @param offs File offset to read sound from.
7078 * @param sound Destination for sound.
7080 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7082 /* Set default volume and priority */
7083 sound->volume = 0x80;
7084 sound->priority = 0;
7086 if (offs != SIZE_MAX) {
7087 /* Sound is present in the NewGRF. */
7088 sound->file_slot = _cur.file_index;
7089 sound->file_offset = offs;
7090 sound->grf_container_ver = _cur.grf_container_ver;
7094 /* Action 0x11 */
7095 static void GRFSound(ByteReader *buf)
7097 /* <11> <num>
7099 * W num Number of sound files that follow */
7101 uint16 num = buf->ReadWord();
7102 if (num == 0) return;
7104 SoundEntry *sound;
7105 if (_cur.grffile->sound_offset == 0) {
7106 _cur.grffile->sound_offset = GetNumSounds();
7107 _cur.grffile->num_sounds = num;
7108 sound = AllocateSound(num);
7109 } else {
7110 sound = GetSound(_cur.grffile->sound_offset);
7113 for (int i = 0; i < num; i++) {
7114 _cur.nfo_line++;
7116 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7117 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7118 bool invalid = i >= _cur.grffile->num_sounds;
7120 size_t offs = FioGetPos();
7122 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7123 byte type = FioReadByte();
7125 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7126 /* Reference to sprite section. */
7127 if (invalid) {
7128 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7129 FioSkipBytes(len);
7130 } else if (len != 4) {
7131 grfmsg(1, "GRFSound: Invalid sprite section import");
7132 FioSkipBytes(len);
7133 } else {
7134 uint32 id = FioReadDword();
7135 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7137 continue;
7140 if (type != 0xFF) {
7141 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7142 FioSkipBytes(7);
7143 SkipSpriteData(type, len - 8);
7144 continue;
7147 if (invalid) {
7148 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7149 FioSkipBytes(len);
7152 byte action = FioReadByte();
7153 switch (action) {
7154 case 0xFF:
7155 /* Allocate sound only in init stage. */
7156 if (_cur.stage == GLS_INIT) {
7157 if (_cur.grf_container_ver >= 2) {
7158 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7159 } else {
7160 LoadGRFSound(offs, sound + i);
7163 FioSkipBytes(len - 1); // already read <action>
7164 break;
7166 case 0xFE:
7167 if (_cur.stage == GLS_ACTIVATION) {
7168 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7169 * importing sounds, so this is probably all wrong... */
7170 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7171 ImportGRFSound(sound + i);
7172 } else {
7173 FioSkipBytes(len - 1); // already read <action>
7175 break;
7177 default:
7178 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7179 FioSkipBytes(len - 1); // already read <action>
7180 break;
7185 /* Action 0x11 (SKIP) */
7186 static void SkipAct11(ByteReader *buf)
7188 /* <11> <num>
7190 * W num Number of sound files that follow */
7192 _cur.skip_sprites = buf->ReadWord();
7194 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7197 /** Action 0x12 */
7198 static void LoadFontGlyph(ByteReader *buf)
7200 /* <12> <num_def> <font_size> <num_char> <base_char>
7202 * B num_def Number of definitions
7203 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7204 * B num_char Number of consecutive glyphs
7205 * W base_char First character index */
7207 uint8 num_def = buf->ReadByte();
7209 for (uint i = 0; i < num_def; i++) {
7210 FontSize size = (FontSize)buf->ReadByte();
7211 uint8 num_char = buf->ReadByte();
7212 uint16 base_char = buf->ReadWord();
7214 if (size >= FS_END) {
7215 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7218 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7220 for (uint c = 0; c < num_char; c++) {
7221 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7222 _cur.nfo_line++;
7223 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7228 /** Action 0x12 (SKIP) */
7229 static void SkipAct12(ByteReader *buf)
7231 /* <12> <num_def> <font_size> <num_char> <base_char>
7233 * B num_def Number of definitions
7234 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7235 * B num_char Number of consecutive glyphs
7236 * W base_char First character index */
7238 uint8 num_def = buf->ReadByte();
7240 for (uint i = 0; i < num_def; i++) {
7241 /* Ignore 'size' byte */
7242 buf->ReadByte();
7244 /* Sum up number of characters */
7245 _cur.skip_sprites += buf->ReadByte();
7247 /* Ignore 'base_char' word */
7248 buf->ReadWord();
7251 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7254 /** Action 0x13 */
7255 static void TranslateGRFStrings(ByteReader *buf)
7257 /* <13> <grfid> <num-ent> <offset> <text...>
7259 * 4*B grfid The GRFID of the file whose texts are to be translated
7260 * B num-ent Number of strings
7261 * W offset First text ID
7262 * S text... Zero-terminated strings */
7264 uint32 grfid = buf->ReadDWord();
7265 const GRFConfig *c = GetGRFConfig(grfid);
7266 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7267 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7268 return;
7271 if (c->status == GCS_INITIALISED) {
7272 /* If the file is not active but will be activated later, give an error
7273 * and disable this file. */
7274 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7276 char tmp[256];
7277 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7278 error->data = stredup(tmp);
7280 return;
7283 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7284 * to be added as a generic string, thus the language id of 0x7F. For this to work
7285 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7286 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7287 * not change anything if a string has been provided specifically for this language. */
7288 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7289 byte num_strings = buf->ReadByte();
7290 uint16 first_id = buf->ReadWord();
7292 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7293 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7294 return;
7297 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7298 const char *string = buf->ReadString();
7300 if (StrEmpty(string)) {
7301 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7302 continue;
7305 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7309 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7310 static bool ChangeGRFName(byte langid, const char *str)
7312 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7313 return true;
7316 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7317 static bool ChangeGRFDescription(byte langid, const char *str)
7319 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7320 return true;
7323 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7324 static bool ChangeGRFURL(byte langid, const char *str)
7326 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7327 return true;
7330 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7331 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7333 if (len != 1) {
7334 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7335 buf->Skip(len);
7336 } else {
7337 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7339 return true;
7342 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7343 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7345 if (len != 1) {
7346 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7347 buf->Skip(len);
7348 } else {
7349 char data = buf->ReadByte();
7350 GRFPalette pal = GRFP_GRF_UNSET;
7351 switch (data) {
7352 case '*':
7353 case 'A': pal = GRFP_GRF_ANY; break;
7354 case 'W': pal = GRFP_GRF_WINDOWS; break;
7355 case 'D': pal = GRFP_GRF_DOS; break;
7356 default:
7357 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7358 break;
7360 if (pal != GRFP_GRF_UNSET) {
7361 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7362 _cur.grfconfig->palette |= pal;
7365 return true;
7368 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7369 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7371 if (len != 1) {
7372 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7373 buf->Skip(len);
7374 } else {
7375 char data = buf->ReadByte();
7376 GRFPalette pal = GRFP_BLT_UNSET;
7377 switch (data) {
7378 case '8': pal = GRFP_BLT_UNSET; break;
7379 case '3': pal = GRFP_BLT_32BPP; break;
7380 default:
7381 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7382 return true;
7384 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7385 _cur.grfconfig->palette |= pal;
7387 return true;
7390 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7391 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7393 if (len != 4) {
7394 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7395 buf->Skip(len);
7396 } else {
7397 /* Set min_loadable_version as well (default to minimal compatibility) */
7398 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7400 return true;
7403 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7404 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7406 if (len != 4) {
7407 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7408 buf->Skip(len);
7409 } else {
7410 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7411 if (_cur.grfconfig->version == 0) {
7412 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7413 _cur.grfconfig->min_loadable_version = 0;
7415 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7416 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7417 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7420 return true;
7423 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7425 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7426 static bool ChangeGRFParamName(byte langid, const char *str)
7428 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7429 return true;
7432 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7433 static bool ChangeGRFParamDescription(byte langid, const char *str)
7435 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7436 return true;
7439 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7440 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7442 if (len != 1) {
7443 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7444 buf->Skip(len);
7445 } else {
7446 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7447 if (type < PTYPE_END) {
7448 _cur_parameter->type = type;
7449 } else {
7450 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7453 return true;
7456 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7457 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7459 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7460 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7461 buf->Skip(len);
7462 } else if (len != 8) {
7463 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7464 buf->Skip(len);
7465 } else {
7466 _cur_parameter->min_value = buf->ReadDWord();
7467 _cur_parameter->max_value = buf->ReadDWord();
7469 return true;
7472 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7473 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7475 if (len < 1 || len > 3) {
7476 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7477 buf->Skip(len);
7478 } else {
7479 byte param_nr = buf->ReadByte();
7480 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7481 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7482 buf->Skip(len - 1);
7483 } else {
7484 _cur_parameter->param_nr = param_nr;
7485 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7486 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7490 return true;
7493 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7494 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7496 if (len != 4) {
7497 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7498 buf->Skip(len);
7499 } else {
7500 _cur_parameter->def_value = buf->ReadDWord();
7502 _cur.grfconfig->has_param_defaults = true;
7503 return true;
7506 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7507 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7508 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7511 * Data structure to store the allowed id/type combinations for action 14. The
7512 * data can be represented as a tree with 3 types of nodes:
7513 * 1. Branch nodes (identified by 'C' for choice).
7514 * 2. Binary leaf nodes (identified by 'B').
7515 * 3. Text leaf nodes (identified by 'T').
7517 struct AllowedSubtags {
7518 /** Create empty subtags object used to identify the end of a list. */
7519 AllowedSubtags() :
7520 id(0),
7521 type(0)
7525 * Create a binary leaf node.
7526 * @param id The id for this node.
7527 * @param handler The callback function to call.
7529 AllowedSubtags(uint32 id, DataHandler handler) :
7530 id(id),
7531 type('B')
7533 this->handler.data = handler;
7537 * Create a text leaf node.
7538 * @param id The id for this node.
7539 * @param handler The callback function to call.
7541 AllowedSubtags(uint32 id, TextHandler handler) :
7542 id(id),
7543 type('T')
7545 this->handler.text = handler;
7549 * Create a branch node with a callback handler
7550 * @param id The id for this node.
7551 * @param handler The callback function to call.
7553 AllowedSubtags(uint32 id, BranchHandler handler) :
7554 id(id),
7555 type('C')
7557 this->handler.call_handler = true;
7558 this->handler.u.branch = handler;
7562 * Create a branch node with a list of sub-nodes.
7563 * @param id The id for this node.
7564 * @param subtags Array with all valid subtags.
7566 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7567 id(id),
7568 type('C')
7570 this->handler.call_handler = false;
7571 this->handler.u.subtags = subtags;
7574 uint32 id; ///< The identifier for this node
7575 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7576 union {
7577 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7578 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7579 struct {
7580 union {
7581 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7582 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7583 } u;
7584 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7586 } handler;
7589 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7590 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7593 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7594 * of some parameter values (type uint/enum) or the names of some bits
7595 * (type bitmask). In both cases the format is the same:
7596 * Each subnode should be a text node with the value/bit number as id.
7598 static bool ChangeGRFParamValueNames(ByteReader *buf)
7600 byte type = buf->ReadByte();
7601 while (type != 0) {
7602 uint32 id = buf->ReadDWord();
7603 if (type != 'T' || id > _cur_parameter->max_value) {
7604 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7605 if (!SkipUnknownInfo(buf, type)) return false;
7606 type = buf->ReadByte();
7607 continue;
7610 byte langid = buf->ReadByte();
7611 const char *name_string = buf->ReadString();
7613 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7614 if (val_name != _cur_parameter->value_names.End()) {
7615 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7616 } else {
7617 GRFText *list = NULL;
7618 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7619 _cur_parameter->value_names.Insert(id, list);
7622 type = buf->ReadByte();
7624 return true;
7627 /** Action14 parameter tags */
7628 AllowedSubtags _tags_parameters[] = {
7629 AllowedSubtags('NAME', ChangeGRFParamName),
7630 AllowedSubtags('DESC', ChangeGRFParamDescription),
7631 AllowedSubtags('TYPE', ChangeGRFParamType),
7632 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7633 AllowedSubtags('MASK', ChangeGRFParamMask),
7634 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7635 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7636 AllowedSubtags()
7640 * Callback function for 'INFO'->'PARA' to set extra information about the
7641 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7642 * the parameter number as id. The first parameter has id 0. The maximum
7643 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7645 static bool HandleParameterInfo(ByteReader *buf)
7647 byte type = buf->ReadByte();
7648 while (type != 0) {
7649 uint32 id = buf->ReadDWord();
7650 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7651 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7652 if (!SkipUnknownInfo(buf, type)) return false;
7653 type = buf->ReadByte();
7654 continue;
7657 if (id >= _cur.grfconfig->param_info.Length()) {
7658 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7659 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7660 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7662 if (_cur.grfconfig->param_info[id] == NULL) {
7663 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7665 _cur_parameter = _cur.grfconfig->param_info[id];
7666 /* Read all parameter-data and process each node. */
7667 if (!HandleNodes(buf, _tags_parameters)) return false;
7668 type = buf->ReadByte();
7670 return true;
7673 /** Action14 tags for the INFO node */
7674 AllowedSubtags _tags_info[] = {
7675 AllowedSubtags('NAME', ChangeGRFName),
7676 AllowedSubtags('DESC', ChangeGRFDescription),
7677 AllowedSubtags('URL_', ChangeGRFURL),
7678 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7679 AllowedSubtags('PALS', ChangeGRFPalette),
7680 AllowedSubtags('BLTR', ChangeGRFBlitter),
7681 AllowedSubtags('VRSN', ChangeGRFVersion),
7682 AllowedSubtags('MINV', ChangeGRFMinVersion),
7683 AllowedSubtags('PARA', HandleParameterInfo),
7684 AllowedSubtags()
7687 /** Action14 root tags */
7688 AllowedSubtags _tags_root[] = {
7689 AllowedSubtags('INFO', _tags_info),
7690 AllowedSubtags()
7695 * Try to skip the current node and all subnodes (if it's a branch node).
7696 * @param buf Buffer.
7697 * @param type The node type to skip.
7698 * @return True if we could skip the node, false if an error occurred.
7700 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7702 /* type and id are already read */
7703 switch (type) {
7704 case 'C': {
7705 byte new_type = buf->ReadByte();
7706 while (new_type != 0) {
7707 buf->ReadDWord(); // skip the id
7708 if (!SkipUnknownInfo(buf, new_type)) return false;
7709 new_type = buf->ReadByte();
7711 break;
7714 case 'T':
7715 buf->ReadByte(); // lang
7716 buf->ReadString(); // actual text
7717 break;
7719 case 'B': {
7720 uint16 size = buf->ReadWord();
7721 buf->Skip(size);
7722 break;
7725 default:
7726 return false;
7729 return true;
7733 * Handle the nodes of an Action14
7734 * @param type Type of node.
7735 * @param id ID.
7736 * @param buf Buffer.
7737 * @param subtags Allowed subtags.
7738 * @return Whether all tags could be handled.
7740 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7742 uint i = 0;
7743 AllowedSubtags *tag;
7744 while ((tag = &subtags[i++])->type != 0) {
7745 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7746 switch (type) {
7747 default: NOT_REACHED();
7749 case 'T': {
7750 byte langid = buf->ReadByte();
7751 return tag->handler.text(langid, buf->ReadString());
7754 case 'B': {
7755 size_t len = buf->ReadWord();
7756 if (buf->Remaining() < len) return false;
7757 return tag->handler.data(len, buf);
7760 case 'C': {
7761 if (tag->handler.call_handler) {
7762 return tag->handler.u.branch(buf);
7764 return HandleNodes(buf, tag->handler.u.subtags);
7768 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7769 return SkipUnknownInfo(buf, type);
7773 * Handle the contents of a 'C' choice of an Action14
7774 * @param buf Buffer.
7775 * @param subtags List of subtags.
7776 * @return Whether the nodes could all be handled.
7778 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7780 byte type = buf->ReadByte();
7781 while (type != 0) {
7782 uint32 id = buf->ReadDWord();
7783 if (!HandleNode(type, id, buf, subtags)) return false;
7784 type = buf->ReadByte();
7786 return true;
7790 * Handle Action 0x14
7791 * @param buf Buffer.
7793 static void StaticGRFInfo(ByteReader *buf)
7795 /* <14> <type> <id> <text/data...> */
7796 HandleNodes(buf, _tags_root);
7800 * Set the current NewGRF as unsafe for static use
7801 * @param buf Unused.
7802 * @note Used during safety scan on unsafe actions.
7804 static void GRFUnsafe(ByteReader *buf)
7806 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7808 /* Skip remainder of GRF */
7809 _cur.skip_sprites = -1;
7813 /** Initialize the TTDPatch flags */
7814 static void InitializeGRFSpecial()
7816 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7817 | (1 << 0x0D) // newairports
7818 | (1 << 0x0E) // largestations
7819 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7820 | (0 << 0x10) // loadtime
7821 | (1 << 0x12) // presignals
7822 | (1 << 0x13) // extpresignals
7823 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7824 | (1 << 0x1B) // multihead
7825 | (1 << 0x1D) // lowmemory
7826 | (1 << 0x1E); // generalfixes
7828 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7829 | (1 << 0x08) // mammothtrains
7830 | (1 << 0x09) // trainrefit
7831 | (0 << 0x0B) // subsidiaries
7832 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7833 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7834 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7835 | (1 << 0x14) // bridgespeedlimits
7836 | (1 << 0x16) // eternalgame
7837 | (1 << 0x17) // newtrains
7838 | (1 << 0x18) // newrvs
7839 | (1 << 0x19) // newships
7840 | (1 << 0x1A) // newplanes
7841 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7842 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7844 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7845 | (1 << 0x03) // semaphores
7846 | (1 << 0x0A) // newobjects
7847 | (0 << 0x0B) // enhancedgui
7848 | (0 << 0x0C) // newagerating
7849 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7850 | (1 << 0x0E) // fullloadany
7851 | (1 << 0x0F) // planespeed
7852 | (0 << 0x10) // moreindustriesperclimate - obsolete
7853 | (0 << 0x11) // moretoylandfeatures
7854 | (1 << 0x12) // newstations
7855 | (1 << 0x13) // tracktypecostdiff
7856 | (1 << 0x14) // manualconvert
7857 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7858 | (1 << 0x16) // canals
7859 | (1 << 0x17) // newstartyear
7860 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7861 | (1 << 0x19) // newhouses
7862 | (1 << 0x1A) // newbridges
7863 | (1 << 0x1B) // newtownnames
7864 | (1 << 0x1C) // moreanimation
7865 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7866 | (1 << 0x1E) // newshistory
7867 | (0 << 0x1F); // custombridgeheads
7869 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7870 | (1 << 0x01) // windowsnap
7871 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7872 | (1 << 0x03) // pathbasedsignalling
7873 | (0 << 0x04) // aichoosechance
7874 | (1 << 0x05) // resolutionwidth
7875 | (1 << 0x06) // resolutionheight
7876 | (1 << 0x07) // newindustries
7877 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7878 | (0 << 0x09) // townroadbranchprob
7879 | (0 << 0x0A) // tempsnowline
7880 | (1 << 0x0B) // newcargo
7881 | (1 << 0x0C) // enhancemultiplayer
7882 | (1 << 0x0D) // onewayroads
7883 | (1 << 0x0E) // irregularstations
7884 | (1 << 0x0F) // statistics
7885 | (1 << 0x10) // newsounds
7886 | (1 << 0x11) // autoreplace
7887 | (1 << 0x12) // autoslope
7888 | (0 << 0x13) // followvehicle
7889 | (1 << 0x14) // trams
7890 | (0 << 0x15) // enhancetunnels
7891 | (1 << 0x16) // shortrvs
7892 | (1 << 0x17) // articulatedrvs
7893 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7894 | (1 << 0x1E) // variablerunningcosts
7895 | (1 << 0x1F); // any switch is on
7898 /** Reset and clear all NewGRF stations */
7899 static void ResetCustomStations()
7901 const GRFFile * const *end = _grf_files.End();
7902 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7903 StationSpec **&stations = (*file)->stations;
7904 if (stations == NULL) continue;
7905 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7906 if (stations[i] == NULL) continue;
7907 StationSpec *statspec = stations[i];
7909 delete[] statspec->renderdata;
7911 /* Release platforms and layouts */
7912 if (!statspec->copied_layouts) {
7913 for (uint l = 0; l < statspec->lengths; l++) {
7914 for (uint p = 0; p < statspec->platforms[l]; p++) {
7915 free(statspec->layouts[l][p]);
7917 free(statspec->layouts[l]);
7919 free(statspec->layouts);
7920 free(statspec->platforms);
7923 /* Release this station */
7924 free(statspec);
7927 /* Free and reset the station data */
7928 free(stations);
7929 stations = NULL;
7933 /** Reset and clear all NewGRF houses */
7934 static void ResetCustomHouses()
7936 const GRFFile * const *end = _grf_files.End();
7937 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7938 HouseSpec **&housespec = (*file)->housespec;
7939 if (housespec == NULL) continue;
7940 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7941 free(housespec[i]);
7944 free(housespec);
7945 housespec = NULL;
7949 /** Reset and clear all NewGRF airports */
7950 static void ResetCustomAirports()
7952 const GRFFile * const *end = _grf_files.End();
7953 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7954 AirportSpec **aslist = (*file)->airportspec;
7955 if (aslist != NULL) {
7956 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7957 AirportSpec *as = aslist[i];
7959 if (as != NULL) {
7960 /* We need to remove the tiles layouts */
7961 for (int j = 0; j < as->num_table; j++) {
7962 /* remove the individual layouts */
7963 free(as->table[j]);
7965 free(as->table);
7966 free(as->depot_table);
7967 free(as->rotation);
7969 free(as);
7972 free(aslist);
7973 (*file)->airportspec = NULL;
7976 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7977 if (airporttilespec != NULL) {
7978 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7979 free(airporttilespec[i]);
7981 free(airporttilespec);
7982 airporttilespec = NULL;
7987 /** Reset and clear all NewGRF industries */
7988 static void ResetCustomIndustries()
7990 const GRFFile * const *end = _grf_files.End();
7991 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7992 IndustrySpec **&industryspec = (*file)->industryspec;
7993 IndustryTileSpec **&indtspec = (*file)->indtspec;
7995 /* We are verifiying both tiles and industries specs loaded from the grf file
7996 * First, let's deal with industryspec */
7997 if (industryspec != NULL) {
7998 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7999 IndustrySpec *ind = industryspec[i];
8000 if (ind == NULL) continue;
8002 /* We need to remove the sounds array */
8003 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8004 free(ind->random_sounds);
8007 /* We need to remove the tiles layouts */
8008 CleanIndustryTileTable(ind);
8010 free(ind);
8013 free(industryspec);
8014 industryspec = NULL;
8017 if (indtspec == NULL) continue;
8018 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8019 free(indtspec[i]);
8022 free(indtspec);
8023 indtspec = NULL;
8027 /** Reset and clear all NewObjects */
8028 static void ResetCustomObjects()
8030 const GRFFile * const *end = _grf_files.End();
8031 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8032 ObjectSpec **&objectspec = (*file)->objectspec;
8033 if (objectspec == NULL) continue;
8034 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8035 free(objectspec[i]);
8038 free(objectspec);
8039 objectspec = NULL;
8043 /** Reset and clear all NewGRFs */
8044 static void ResetNewGRF()
8046 const GRFFile * const *end = _grf_files.End();
8047 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8048 delete *file;
8051 _grf_files.Clear();
8052 _cur.grffile = NULL;
8055 /** Clear all NewGRF errors */
8056 static void ResetNewGRFErrors()
8058 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8059 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8060 delete c->error;
8061 c->error = NULL;
8067 * Reset all NewGRF loaded data
8068 * TODO
8070 void ResetNewGRFData()
8072 CleanUpStrings();
8073 CleanUpGRFTownNames();
8075 /* Copy/reset original engine info data */
8076 SetupEngines();
8078 /* Copy/reset original bridge info data */
8079 ResetBridges();
8081 /* Reset rail type information */
8082 ResetRailTypes();
8084 /* Allocate temporary refit/cargo class data */
8085 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8087 /* Fill rail type label temporary data for default trains */
8088 Engine *e;
8089 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8090 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8093 /* Reset GRM reservations */
8094 memset(&_grm_engines, 0, sizeof(_grm_engines));
8095 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8097 /* Reset generic feature callback lists */
8098 ResetGenericCallbacks();
8100 /* Reset price base data */
8101 ResetPriceBaseMultipliers();
8103 /* Reset the curencies array */
8104 ResetCurrencies();
8106 /* Reset the house array */
8107 ResetCustomHouses();
8108 ResetHouses();
8110 /* Reset the industries structures*/
8111 ResetCustomIndustries();
8112 ResetIndustries();
8114 /* Reset the objects. */
8115 ObjectClass::Reset();
8116 ResetCustomObjects();
8117 ResetObjects();
8119 /* Reset station classes */
8120 StationClass::Reset();
8121 ResetCustomStations();
8123 /* Reset airport-related structures */
8124 AirportClass::Reset();
8125 ResetCustomAirports();
8126 AirportSpec::ResetAirports();
8127 AirportTileSpec::ResetAirportTiles();
8129 /* Reset canal sprite groups and flags */
8130 memset(_water_feature, 0, sizeof(_water_feature));
8132 /* Reset the snowline table. */
8133 ClearSnowLine();
8135 /* Reset NewGRF files */
8136 ResetNewGRF();
8138 /* Reset NewGRF errors. */
8139 ResetNewGRFErrors();
8141 /* Set up the default cargo types */
8142 SetupCargoForClimate(_settings_game.game_creation.landscape);
8144 /* Reset misc GRF features and train list display variables */
8145 _misc_grf_features = 0;
8147 _loaded_newgrf_features.has_2CC = false;
8148 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8149 _loaded_newgrf_features.has_newhouses = false;
8150 _loaded_newgrf_features.has_newindustries = false;
8151 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8153 /* Clear all GRF overrides */
8154 _grf_id_overrides.clear();
8156 InitializeSoundPool();
8157 _spritegroup_pool.CleanPool();
8161 * Reset NewGRF data which is stored persistently in savegames.
8163 void ResetPersistentNewGRFData()
8165 /* Reset override managers */
8166 _engine_mngr.ResetToDefaultMapping();
8167 _house_mngr.ResetMapping();
8168 _industry_mngr.ResetMapping();
8169 _industile_mngr.ResetMapping();
8170 _airport_mngr.ResetMapping();
8171 _airporttile_mngr.ResetMapping();
8175 * Construct the Cargo Mapping
8176 * @note This is the reverse of a cargo translation table
8178 static void BuildCargoTranslationMap()
8180 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8182 for (CargoID c = 0; c < NUM_CARGO; c++) {
8183 const CargoSpec *cs = CargoSpec::Get(c);
8184 if (!cs->IsValid()) continue;
8186 if (_cur.grffile->cargo_list.Length() == 0) {
8187 /* Default translation table, so just a straight mapping to bitnum */
8188 _cur.grffile->cargo_map[c] = cs->bitnum;
8189 } else {
8190 /* Check the translation table for this cargo's label */
8191 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8192 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8198 * Prepare loading a NewGRF file with its config
8199 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8201 static void InitNewGRFFile(const GRFConfig *config)
8203 GRFFile *newfile = GetFileByFilename(config->filename);
8204 if (newfile != NULL) {
8205 /* We already loaded it once. */
8206 _cur.grffile = newfile;
8207 return;
8210 newfile = new GRFFile(config);
8211 *_grf_files.Append() = _cur.grffile = newfile;
8215 * Constructor for GRFFile
8216 * @param config GRFConfig to copy name, grfid and parameters from.
8218 GRFFile::GRFFile(const GRFConfig *config)
8220 this->filename = stredup(config->filename);
8221 this->grfid = config->ident.grfid;
8223 /* Initialise local settings to defaults */
8224 this->traininfo_vehicle_pitch = 0;
8225 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8227 /* Mark price_base_multipliers as 'not set' */
8228 for (Price i = PR_BEGIN; i < PR_END; i++) {
8229 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8232 /* Initialise rail type map with default rail types */
8233 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8234 this->railtype_map[0] = RAILTYPE_RAIL;
8235 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8236 this->railtype_map[2] = RAILTYPE_MONO;
8237 this->railtype_map[3] = RAILTYPE_MAGLEV;
8239 /* Copy the initial parameter list
8240 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8241 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8243 assert(config->num_params <= lengthof(config->param));
8244 this->param_end = config->num_params;
8245 if (this->param_end > 0) {
8246 MemCpyT(this->param, config->param, this->param_end);
8250 GRFFile::~GRFFile()
8252 free(this->filename);
8253 delete[] this->language_map;
8258 * List of what cargo labels are refittable for the given the vehicle-type.
8259 * Only currently active labels are applied.
8261 static const CargoLabel _default_refitmasks_rail[] = {
8262 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8263 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8264 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8265 'PLST', 'FZDR',
8266 0 };
8268 static const CargoLabel _default_refitmasks_road[] = {
8269 0 };
8271 static const CargoLabel _default_refitmasks_ships[] = {
8272 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8273 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8274 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8275 'PLST', 'FZDR',
8276 0 };
8278 static const CargoLabel _default_refitmasks_aircraft[] = {
8279 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8280 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8281 0 };
8283 static const CargoLabel * const _default_refitmasks[] = {
8284 _default_refitmasks_rail,
8285 _default_refitmasks_road,
8286 _default_refitmasks_ships,
8287 _default_refitmasks_aircraft,
8292 * Precalculate refit masks from cargo classes for all vehicles.
8294 static void CalculateRefitMasks()
8296 Engine *e;
8298 FOR_ALL_ENGINES(e) {
8299 EngineID engine = e->index;
8300 EngineInfo *ei = &e->info;
8301 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8303 /* Did the newgrf specify any refitting? If not, use defaults. */
8304 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8305 uint32 mask = 0;
8306 uint32 not_mask = 0;
8307 uint32 xor_mask = ei->refit_mask;
8309 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8310 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8311 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8313 if (_gted[engine].cargo_allowed != 0) {
8314 /* Build up the list of cargo types from the set cargo classes. */
8315 const CargoSpec *cs;
8316 FOR_ALL_CARGOSPECS(cs) {
8317 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8318 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8322 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8324 /* Apply explicit refit includes/excludes. */
8325 ei->refit_mask |= _gted[engine].ctt_include_mask;
8326 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8327 } else {
8328 uint32 xor_mask = 0;
8330 /* Don't apply default refit mask to wagons nor engines with no capacity */
8331 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8332 const CargoLabel *cl = _default_refitmasks[e->type];
8333 for (uint i = 0;; i++) {
8334 if (cl[i] == 0) break;
8336 CargoID cargo = GetCargoIDByLabel(cl[i]);
8337 if (cargo == CT_INVALID) continue;
8339 SetBit(xor_mask, cargo);
8343 ei->refit_mask = xor_mask & _cargo_mask;
8345 /* If the mask is zero, the vehicle shall only carry the default cargo */
8346 only_defaultcargo = (ei->refit_mask == 0);
8349 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8350 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8352 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8353 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8354 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8355 ei->cargo_type = CT_INVALID;
8358 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8359 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8360 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8361 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8362 const uint8 *cargo_map_for_first_refittable = NULL;
8364 const GRFFile *file = _gted[engine].defaultcargo_grf;
8365 if (file == NULL) file = e->GetGRF();
8366 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8367 cargo_map_for_first_refittable = file->cargo_map;
8371 if (cargo_map_for_first_refittable != NULL) {
8372 /* Use first refittable cargo from cargo translation table */
8373 byte best_local_slot = 0xFF;
8374 CargoID cargo_type;
8375 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8376 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8377 if (local_slot < best_local_slot) {
8378 best_local_slot = local_slot;
8379 ei->cargo_type = cargo_type;
8384 if (ei->cargo_type == CT_INVALID) {
8385 /* Use first refittable cargo slot */
8386 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8389 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8391 /* Clear refit_mask for not refittable ships */
8392 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8393 ei->refit_mask = 0;
8398 /** Set to use the correct action0 properties for each canal feature */
8399 static void FinaliseCanals()
8401 for (uint i = 0; i < CF_END; i++) {
8402 if (_water_feature[i].grffile != NULL) {
8403 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8404 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8409 /** Check for invalid engines */
8410 static void FinaliseEngineArray()
8412 Engine *e;
8414 FOR_ALL_ENGINES(e) {
8415 if (e->GetGRF() == NULL) {
8416 const EngineIDMapping &eid = _engine_mngr[e->index];
8417 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8418 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8422 /* When the train does not set property 27 (misc flags), but it
8423 * is overridden by a NewGRF graphically we want to disable the
8424 * flipping possibility. */
8425 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8426 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8429 /* Skip wagons, there livery is defined via the engine */
8430 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8431 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8432 SetBit(_loaded_newgrf_features.used_liveries, ls);
8433 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8435 if (e->type == VEH_TRAIN) {
8436 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8437 switch (ls) {
8438 case LS_STEAM:
8439 case LS_DIESEL:
8440 case LS_ELECTRIC:
8441 case LS_MONORAIL:
8442 case LS_MAGLEV:
8443 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8444 break;
8446 case LS_DMU:
8447 case LS_EMU:
8448 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8449 break;
8451 default: NOT_REACHED();
8458 /** Check for invalid cargoes */
8459 static void FinaliseCargoArray()
8461 for (CargoID c = 0; c < NUM_CARGO; c++) {
8462 CargoSpec *cs = CargoSpec::Get(c);
8463 if (!cs->IsValid()) {
8464 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8465 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8466 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8472 * Check if a given housespec is valid and disable it if it's not.
8473 * The housespecs that follow it are used to check the validity of
8474 * multitile houses.
8475 * @param hs The housespec to check.
8476 * @param next1 The housespec that follows \c hs.
8477 * @param next2 The housespec that follows \c next1.
8478 * @param next3 The housespec that follows \c next2.
8479 * @param filename The filename of the newgrf this house was defined in.
8480 * @return Whether the given housespec is valid.
8482 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8484 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8485 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8486 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8487 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8488 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8489 hs->enabled = false;
8490 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);
8491 return false;
8494 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8495 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8496 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8497 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8498 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8499 hs->enabled = false;
8500 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);
8501 return false;
8504 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8505 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8506 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8507 hs->enabled = false;
8508 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);
8509 return false;
8512 /* Make sure that additional parts of multitile houses are not available. */
8513 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8514 hs->enabled = false;
8515 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);
8516 return false;
8519 return true;
8523 * Make sure there is at least one house available in the year 0 for the given
8524 * climate / housezone combination.
8525 * @param bitmask The climate and housezone to check for. Exactly one climate
8526 * bit and one housezone bit should be set.
8528 static void EnsureEarlyHouse(HouseZones bitmask)
8530 Year min_year = MAX_YEAR;
8532 for (int i = 0; i < NUM_HOUSES; i++) {
8533 HouseSpec *hs = HouseSpec::Get(i);
8534 if (hs == NULL || !hs->enabled) continue;
8535 if ((hs->building_availability & bitmask) != bitmask) continue;
8536 if (hs->min_year < min_year) min_year = hs->min_year;
8539 if (min_year == 0) return;
8541 for (int i = 0; i < NUM_HOUSES; i++) {
8542 HouseSpec *hs = HouseSpec::Get(i);
8543 if (hs == NULL || !hs->enabled) continue;
8544 if ((hs->building_availability & bitmask) != bitmask) continue;
8545 if (hs->min_year == min_year) hs->min_year = 0;
8550 * Add all new houses to the house array. House properties can be set at any
8551 * time in the GRF file, so we can only add a house spec to the house array
8552 * after the file has finished loading. We also need to check the dates, due to
8553 * the TTDPatch behaviour described below that we need to emulate.
8555 static void FinaliseHouseArray()
8557 /* If there are no houses with start dates before 1930, then all houses
8558 * with start dates of 1930 have them reset to 0. This is in order to be
8559 * compatible with TTDPatch, where if no houses have start dates before
8560 * 1930 and the date is before 1930, the game pretends that this is 1930.
8561 * If there have been any houses defined with start dates before 1930 then
8562 * the dates are left alone.
8563 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8564 * minimum introduction date to 0.
8566 const GRFFile * const *end = _grf_files.End();
8567 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8568 HouseSpec **&housespec = (*file)->housespec;
8569 if (housespec == NULL) continue;
8571 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8572 HouseSpec *hs = housespec[i];
8574 if (hs == NULL) continue;
8576 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8577 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8578 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8580 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8582 _house_mngr.SetEntitySpec(hs);
8586 for (int i = 0; i < NUM_HOUSES; i++) {
8587 HouseSpec *hs = HouseSpec::Get(i);
8588 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8589 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8590 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8592 /* We need to check all houses again to we are sure that multitile houses
8593 * did get consecutive IDs and none of the parts are missing. */
8594 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8595 /* GetHouseNorthPart checks 3 houses that are directly before
8596 * it in the house pool. If any of those houses have multi-tile
8597 * flags set it assumes it's part of a multitile house. Since
8598 * we can have invalid houses in the pool marked as disabled, we
8599 * don't want to have them influencing valid tiles. As such set
8600 * building_flags to zero here to make sure any house following
8601 * this one in the pool is properly handled as 1x1 house. */
8602 hs->building_flags = TILE_NO_FLAG;
8606 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8607 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8608 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8609 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8610 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8611 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8613 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8614 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8615 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8616 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8617 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8618 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8623 * Add all new industries to the industry array. Industry properties can be set at any
8624 * time in the GRF file, so we can only add a industry spec to the industry array
8625 * after the file has finished loading.
8627 static void FinaliseIndustriesArray()
8629 const GRFFile * const *end = _grf_files.End();
8630 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8631 IndustrySpec **&industryspec = (*file)->industryspec;
8632 IndustryTileSpec **&indtspec = (*file)->indtspec;
8633 if (industryspec != NULL) {
8634 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8635 IndustrySpec *indsp = industryspec[i];
8637 if (indsp != NULL && indsp->enabled) {
8638 StringID strid;
8639 /* process the conversion of text at the end, so to be sure everything will be fine
8640 * and available. Check if it does not return undefind marker, which is a very good sign of a
8641 * substitute industry who has not changed the string been examined, thus using it as such */
8642 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8643 if (strid != STR_UNDEFINED) indsp->name = strid;
8645 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8646 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8648 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8649 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8651 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8652 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8654 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8655 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8657 if (indsp->station_name != STR_NULL) {
8658 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8659 * station's name. Don't want to lose the value, therefore, do not process. */
8660 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8661 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8664 _industry_mngr.SetEntitySpec(indsp);
8665 _loaded_newgrf_features.has_newindustries = true;
8670 if (indtspec != NULL) {
8671 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8672 IndustryTileSpec *indtsp = indtspec[i];
8673 if (indtsp != NULL) {
8674 _industile_mngr.SetEntitySpec(indtsp);
8680 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8681 IndustrySpec *indsp = &_industry_specs[j];
8682 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8683 for (uint i = 0; i < 3; i++) {
8684 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8687 if (!indsp->enabled) {
8688 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8694 * Add all new objects to the object array. Object properties can be set at any
8695 * time in the GRF file, so we can only add an object spec to the object array
8696 * after the file has finished loading.
8698 static void FinaliseObjectsArray()
8700 const GRFFile * const *end = _grf_files.End();
8701 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8702 ObjectSpec **&objectspec = (*file)->objectspec;
8703 if (objectspec != NULL) {
8704 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8705 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8706 _object_mngr.SetEntitySpec(objectspec[i]);
8714 * Add all new airports to the airport array. Airport properties can be set at any
8715 * time in the GRF file, so we can only add a airport spec to the airport array
8716 * after the file has finished loading.
8718 static void FinaliseAirportsArray()
8720 const GRFFile * const *end = _grf_files.End();
8721 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8722 AirportSpec **&airportspec = (*file)->airportspec;
8723 if (airportspec != NULL) {
8724 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8725 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8726 _airport_mngr.SetEntitySpec(airportspec[i]);
8731 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8732 if (airporttilespec != NULL) {
8733 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8734 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8735 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8742 /* Here we perform initial decoding of some special sprites (as are they
8743 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8744 * partial implementation yet).
8745 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8746 * a crafted invalid GRF file. We should tell that to the user somehow, or
8747 * better make this more robust in the future. */
8748 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8750 /* XXX: There is a difference between staged loading in TTDPatch and
8751 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8752 * during stage 1, whilst action 3 is carried out during stage 2 (to
8753 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8754 * IDs are valid only within a given set (action 1) block, and may be
8755 * overwritten after action 3 associates them. But overwriting happens
8756 * in an earlier stage than associating, so... We just process actions
8757 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8758 * --pasky
8759 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8760 * is not in memory and scanning the file every time would be too expensive.
8761 * In other stages we skip action 0x10 since it's already dealt with. */
8762 static const SpecialSpriteHandler handlers[][GLS_END] = {
8763 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8764 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8765 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8766 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8767 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8768 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8769 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8770 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8771 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8772 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8773 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8774 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8775 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8776 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8777 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8778 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8779 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8780 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8781 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8782 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8783 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8786 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8788 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8789 if (it == _grf_line_to_action6_sprite_override.end()) {
8790 /* No preloaded sprite to work with; read the
8791 * pseudo sprite content. */
8792 FioReadBlock(buf, num);
8793 } else {
8794 /* Use the preloaded sprite data. */
8795 buf = _grf_line_to_action6_sprite_override[location];
8796 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8798 /* Skip the real (original) content of this action. */
8799 FioSeekTo(num, SEEK_CUR);
8802 ByteReader br(buf, buf + num);
8803 ByteReader *bufp = &br;
8805 try {
8806 byte action = bufp->ReadByte();
8808 if (action == 0xFF) {
8809 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8810 } else if (action == 0xFE) {
8811 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8812 } else if (action >= lengthof(handlers)) {
8813 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8814 } else if (handlers[action][stage] == NULL) {
8815 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8816 } else {
8817 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8818 handlers[action][stage](bufp);
8820 } catch (...) {
8821 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8822 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8827 /** Signature of a container version 2 GRF. */
8828 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8831 * Get the container version of the currently opened GRF file.
8832 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8834 byte GetGRFContainerVersion()
8836 size_t pos = FioGetPos();
8838 if (FioReadWord() == 0) {
8839 /* Check for GRF container version 2, which is identified by the bytes
8840 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8841 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8842 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8845 return 2;
8848 /* Container version 1 has no header, rewind to start. */
8849 FioSeekTo(pos, SEEK_SET);
8850 return 1;
8854 * Load a particular NewGRF.
8855 * @param config The configuration of the to be loaded NewGRF.
8856 * @param file_index The Fio index of the first NewGRF to load.
8857 * @param stage The loading stage of the NewGRF.
8858 * @param subdir The sub directory to find the NewGRF in.
8860 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8862 const char *filename = config->filename;
8864 /* A .grf file is activated only if it was active when the game was
8865 * started. If a game is loaded, only its active .grfs will be
8866 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8867 * considered active if its action 8 has been processed, i.e. its
8868 * action 8 hasn't been skipped using an action 7.
8870 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8871 * carried out. All others are ignored, because they only need to be
8872 * processed once at initialization. */
8873 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8874 _cur.grffile = GetFileByFilename(filename);
8875 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8876 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8877 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8880 if (file_index >= MAX_FILE_SLOTS) {
8881 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
8882 config->status = GCS_DISABLED;
8883 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8884 return;
8887 FioOpenFile(file_index, filename, subdir);
8888 _cur.file_index = file_index; // XXX
8889 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8891 _cur.grfconfig = config;
8893 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8895 _cur.grf_container_ver = GetGRFContainerVersion();
8896 if (_cur.grf_container_ver == 0) {
8897 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8898 return;
8901 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8902 /* We need the sprite offsets in the init stage for NewGRF sounds
8903 * and in the activation stage for real sprites. */
8904 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8905 } else {
8906 /* Skip sprite section offset if present. */
8907 if (_cur.grf_container_ver >= 2) FioReadDword();
8910 if (_cur.grf_container_ver >= 2) {
8911 /* Read compression value. */
8912 byte compression = FioReadByte();
8913 if (compression != 0) {
8914 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8915 return;
8919 /* Skip the first sprite; we don't care about how many sprites this
8920 * does contain; newest TTDPatches and George's longvehicles don't
8921 * neither, apparently. */
8922 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8923 if (num == 4 && FioReadByte() == 0xFF) {
8924 FioReadDword();
8925 } else {
8926 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8927 return;
8930 _cur.ClearDataForNextFile();
8932 ReusableBuffer<byte> buf;
8934 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8935 byte type = FioReadByte();
8936 _cur.nfo_line++;
8938 if (type == 0xFF) {
8939 if (_cur.skip_sprites == 0) {
8940 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8942 /* Stop all processing if we are to skip the remaining sprites */
8943 if (_cur.skip_sprites == -1) break;
8945 continue;
8946 } else {
8947 FioSkipBytes(num);
8949 } else {
8950 if (_cur.skip_sprites == 0) {
8951 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8952 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8953 break;
8956 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8957 /* Reference to data section. Container version >= 2 only. */
8958 FioSkipBytes(num);
8959 } else {
8960 FioSkipBytes(7);
8961 SkipSpriteData(type, num - 8);
8965 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8970 * Relocates the old shore sprites at new positions.
8972 * 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)
8973 * 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)
8974 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8976 static void ActivateOldShore()
8978 /* Use default graphics, if no shore sprites were loaded.
8979 * Should not happen, as the base set's extra grf should include some. */
8980 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8982 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8983 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8984 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8985 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8986 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8987 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8988 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8989 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8990 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8993 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8994 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8995 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8996 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8997 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8998 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8999 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9000 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9001 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9003 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9004 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9005 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9006 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9011 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9013 static void FinalisePriceBaseMultipliers()
9015 extern const PriceBaseSpec _price_base_specs[];
9016 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9017 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9019 /* Evaluate grf overrides */
9020 int num_grfs = _grf_files.Length();
9021 int *grf_overrides = AllocaM(int, num_grfs);
9022 for (int i = 0; i < num_grfs; i++) {
9023 grf_overrides[i] = -1;
9025 GRFFile *source = _grf_files[i];
9026 uint32 override = _grf_id_overrides[source->grfid];
9027 if (override == 0) continue;
9029 GRFFile *dest = GetFileByGRFID(override);
9030 if (dest == NULL) continue;
9032 grf_overrides[i] = _grf_files.FindIndex(dest);
9033 assert(grf_overrides[i] >= 0);
9036 /* Override features and price base multipliers of earlier loaded grfs */
9037 for (int i = 0; i < num_grfs; i++) {
9038 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9039 GRFFile *source = _grf_files[i];
9040 GRFFile *dest = _grf_files[grf_overrides[i]];
9042 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9043 source->grf_features |= features;
9044 dest->grf_features |= features;
9046 for (Price p = PR_BEGIN; p < PR_END; p++) {
9047 /* No price defined -> nothing to do */
9048 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9049 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9050 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9054 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9055 for (int i = num_grfs - 1; i >= 0; i--) {
9056 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9057 GRFFile *source = _grf_files[i];
9058 GRFFile *dest = _grf_files[grf_overrides[i]];
9060 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9061 source->grf_features |= features;
9062 dest->grf_features |= features;
9064 for (Price p = PR_BEGIN; p < PR_END; p++) {
9065 /* Already a price defined -> nothing to do */
9066 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9067 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9068 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9072 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9073 for (int i = 0; i < num_grfs; i++) {
9074 if (grf_overrides[i] < 0) continue;
9075 GRFFile *source = _grf_files[i];
9076 GRFFile *dest = _grf_files[grf_overrides[i]];
9078 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9079 source->grf_features |= features;
9080 dest->grf_features |= features;
9082 for (Price p = PR_BEGIN; p < PR_END; p++) {
9083 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9084 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9085 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9087 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9091 /* Apply fallback prices for grf version < 8 */
9092 const GRFFile * const *end = _grf_files.End();
9093 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9094 if ((*file)->grf_version >= 8) continue;
9095 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9096 for (Price p = PR_BEGIN; p < PR_END; p++) {
9097 Price fallback_price = _price_base_specs[p].fallback_price;
9098 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9099 /* No price multiplier has been set.
9100 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9101 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9106 /* Decide local/global scope of price base multipliers */
9107 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9108 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9109 for (Price p = PR_BEGIN; p < PR_END; p++) {
9110 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9111 /* No multiplier was set; set it to a neutral value */
9112 price_base_multipliers[p] = 0;
9113 } else {
9114 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9115 /* The grf does not define any objects of the feature,
9116 * so it must be a difficulty setting. Apply it globally */
9117 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9118 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9119 price_base_multipliers[p] = 0;
9120 } else {
9121 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9128 extern void InitGRFTownGeneratorNames();
9130 /** Finish loading NewGRFs and execute needed post-processing */
9131 static void AfterLoadGRFs()
9133 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9134 *it->target = MapGRFStringID(it->grfid, it->source);
9136 _string_to_grf_mapping.Clear();
9138 /* Free the action 6 override sprites. */
9139 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9140 free((*it).second);
9142 _grf_line_to_action6_sprite_override.clear();
9144 /* Polish cargoes */
9145 FinaliseCargoArray();
9147 /* Pre-calculate all refit masks after loading GRF files. */
9148 CalculateRefitMasks();
9150 /* Polish engines */
9151 FinaliseEngineArray();
9153 /* Set the actually used Canal properties */
9154 FinaliseCanals();
9156 /* Add all new houses to the house array. */
9157 FinaliseHouseArray();
9159 /* Add all new industries to the industry array. */
9160 FinaliseIndustriesArray();
9162 /* Add all new objects to the object array. */
9163 FinaliseObjectsArray();
9165 InitializeSortedCargoSpecs();
9167 /* Sort the list of industry types. */
9168 SortIndustryTypes();
9170 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9171 BuildIndustriesLegend();
9173 /* Build the routemap legend, based on the available cargos */
9174 BuildLinkStatsLegend();
9176 /* Add all new airports to the airports array. */
9177 FinaliseAirportsArray();
9178 BindAirportSpecs();
9180 /* Update the townname generators list */
9181 InitGRFTownGeneratorNames();
9183 /* Run all queued vehicle list order changes */
9184 CommitVehicleListOrderChanges();
9186 /* Load old shore sprites in new position, if they were replaced by ActionA */
9187 ActivateOldShore();
9189 /* Set up custom rail types */
9190 InitRailTypes();
9192 Engine *e;
9193 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9194 if (_gted[e->index].rv_max_speed != 0) {
9195 /* Set RV maximum speed from the mph/0.8 unit value */
9196 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9200 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9201 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9202 if (railtype == INVALID_RAILTYPE) {
9203 /* Rail type is not available, so disable this engine */
9204 e->info.climates = 0;
9205 } else {
9206 e->u.rail.railtype = railtype;
9210 SetYearEngineAgingStops();
9212 FinalisePriceBaseMultipliers();
9214 /* Deallocate temporary loading data */
9215 free(_gted);
9216 _grm_sprites.clear();
9220 * Load all the NewGRFs.
9221 * @param load_index The offset for the first sprite to add.
9222 * @param file_index The Fio index of the first NewGRF to load.
9223 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9225 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9227 /* In case of networking we need to "sync" the start values
9228 * so all NewGRFs are loaded equally. For this we use the
9229 * start date of the game and we set the counters, etc. to
9230 * 0 so they're the same too. */
9231 Date date = _date;
9232 Year year = _cur_year;
9233 DateFract date_fract = _date_fract;
9234 uint16 tick_counter = _tick_counter;
9235 byte display_opt = _display_opt;
9237 if (_networking) {
9238 _cur_year = _settings_game.game_creation.starting_year;
9239 _date = ConvertYMDToDate(_cur_year, 0, 1);
9240 _date_fract = 0;
9241 _tick_counter = 0;
9242 _display_opt = 0;
9245 InitializeGRFSpecial();
9247 ResetNewGRFData();
9250 * Reset the status of all files, so we can 'retry' to load them.
9251 * This is needed when one for example rearranges the NewGRFs in-game
9252 * and a previously disabled NewGRF becomes useable. If it would not
9253 * be reset, the NewGRF would remain disabled even though it should
9254 * have been enabled.
9256 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9257 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9260 _cur.spriteid = load_index;
9262 /* Load newgrf sprites
9263 * in each loading stage, (try to) open each file specified in the config
9264 * and load information from it. */
9265 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9266 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9267 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9268 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9269 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9272 if (stage == GLS_RESERVE) {
9273 static const uint32 overrides[][2] = {
9274 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9275 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9276 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9278 for (size_t i = 0; i < lengthof(overrides); i++) {
9279 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9283 uint slot = file_index;
9284 uint num_non_static = 0;
9286 _cur.stage = stage;
9287 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9288 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9289 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9291 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9292 if (!FioCheckFileExists(c->filename, subdir)) {
9293 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9294 c->status = GCS_NOT_FOUND;
9295 continue;
9298 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9300 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9301 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9302 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9303 c->status = GCS_DISABLED;
9304 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9305 continue;
9307 num_non_static++;
9309 LoadNewGRFFile(c, slot++, stage, subdir);
9310 if (stage == GLS_RESERVE) {
9311 SetBit(c->flags, GCF_RESERVED);
9312 } else if (stage == GLS_ACTIVATION) {
9313 ClrBit(c->flags, GCF_RESERVED);
9314 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9315 ClearTemporaryNewGRFData(_cur.grffile);
9316 BuildCargoTranslationMap();
9317 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9318 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9319 /* We're not going to activate this, so free whatever data we allocated */
9320 ClearTemporaryNewGRFData(_cur.grffile);
9325 /* Pseudo sprite processing is finished; free temporary stuff */
9326 _cur.ClearDataForNextFile();
9328 /* Call any functions that should be run after GRFs have been loaded. */
9329 AfterLoadGRFs();
9331 /* Now revert back to the original situation */
9332 _cur_year = year;
9333 _date = date;
9334 _date_fract = date_fract;
9335 _tick_counter = tick_counter;
9336 _display_opt = display_opt;