Add ByteReader::GetData to avoid copying data
[openttd/fttd.git] / src / newgrf.cpp
blobe0b29ad67ab455234b5b2cfcb9b1e432a5d30a32
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
10 /** @file newgrf.cpp Base of all NewGRF support. */
12 #include "stdafx.h"
14 #include <stdarg.h>
16 #include "debug.h"
17 #include "fileio_func.h"
18 #include "engine_func.h"
19 #include "engine_base.h"
20 #include "bridge.h"
21 #include "town.h"
22 #include "newgrf_engine.h"
23 #include "newgrf_text.h"
24 #include "font.h"
25 #include "currency.h"
26 #include "landscape.h"
27 #include "newgrf_cargo.h"
28 #include "newgrf_house.h"
29 #include "newgrf_sound.h"
30 #include "newgrf_station.h"
31 #include "industrytype.h"
32 #include "newgrf_canal.h"
33 #include "newgrf_townname.h"
34 #include "newgrf_industries.h"
35 #include "newgrf_airporttiles.h"
36 #include "newgrf_airport.h"
37 #include "newgrf_object.h"
38 #include "rev.h"
39 #include "fios.h"
40 #include "strings_func.h"
41 #include "date_func.h"
42 #include "string.h"
43 #include "network/network.h"
44 #include <map>
45 #include "smallmap_gui.h"
46 #include "genworld.h"
47 #include "error.h"
48 #include "vehicle_func.h"
49 #include "language.h"
50 #include "vehicle_base.h"
51 #include "rail.h"
52 #include "core/pointer.h"
54 #include "table/strings.h"
55 #include "table/build_industry.h"
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
66 /** List of all loaded GRF files */
67 static SmallVector<GRFFile *, 16> _grf_files;
69 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
70 byte _misc_grf_features = 0;
72 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
73 static uint32 _ttdpatch_flags[8];
75 /** Indicates which are the newgrf features currently loaded ingame */
76 GRFLoadedFeatures _loaded_newgrf_features;
78 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
80 /** Temporary data during loading of GRFs */
81 struct GrfProcessingState {
82 private:
83 /** Definition of a single Action1 spriteset */
84 struct SpriteSet {
85 SpriteID sprite; ///< SpriteID of the first sprite of the set.
86 uint num_sprites; ///< Number of sprites in the set.
89 /** Currently referenceable spritesets */
90 std::map<uint, SpriteSet> spritesets[GSF_END];
92 public:
93 /* Global state */
94 GrfLoadingStage stage; ///< Current loading stage
95 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
97 /* Local state in the file */
98 uint file_index; ///< File index of currently processed GRF file.
99 GRFFile *grffile; ///< Currently processed GRF file.
100 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
101 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
102 byte grf_container_ver; ///< Container format of the current GRF file.
104 /* Currently referenceable spritegroups */
105 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
107 /** Clear temporary data before processing the next file in the current loading stage */
108 void ClearDataForNextFile()
110 this->nfo_line = 0;
112 for (uint i = 0; i < GSF_END; i++) {
113 this->spritesets[i].clear();
116 memset(this->spritegroups, 0, sizeof(this->spritegroups));
120 * Records new spritesets.
121 * @param feature GrfSpecFeature the set is defined for.
122 * @param first_sprite SpriteID of the first sprite in the set.
123 * @param first_set First spriteset to define.
124 * @param numsets Number of sets to define.
125 * @param numents Number of sprites per set to define.
127 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
129 assert(feature < GSF_END);
130 for (uint i = 0; i < numsets; i++) {
131 SpriteSet &set = this->spritesets[feature][first_set + i];
132 set.sprite = first_sprite + i * numents;
133 set.num_sprites = numents;
138 * Check whether there are any valid spritesets for a feature.
139 * @param feature GrfSpecFeature to check.
140 * @return true if there are any valid sets.
141 * @note Spritesets with zero sprites are valid to allow callback-failures.
143 bool HasValidSpriteSets(byte feature) const
145 assert(feature < GSF_END);
146 return !this->spritesets[feature].empty();
150 * Check whether a specific set is defined.
151 * @param feature GrfSpecFeature to check.
152 * @param set Set to check.
153 * @return true if the set is valid.
154 * @note Spritesets with zero sprites are valid to allow callback-failures.
156 bool IsValidSpriteSet(byte feature, uint set) const
158 assert(feature < GSF_END);
159 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
163 * Returns the first sprite of a spriteset.
164 * @param feature GrfSpecFeature to query.
165 * @param set Set to query.
166 * @return First sprite of the set.
168 SpriteID GetSprite(byte feature, uint set) const
170 assert(IsValidSpriteSet(feature, set));
171 return this->spritesets[feature].find(set)->second.sprite;
175 * Returns the number of sprites in a spriteset
176 * @param feature GrfSpecFeature to query.
177 * @param set Set to query.
178 * @return Number of sprites in the set.
180 uint GetNumEnts(byte feature, uint set) const
182 assert(IsValidSpriteSet(feature, set));
183 return this->spritesets[feature].find(set)->second.num_sprites;
187 static GrfProcessingState _cur;
191 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
192 * @param <T> The type of vehicle.
193 * @param image_index The image index to check.
194 * @return True iff the image index is valid, or 0xFD (use new graphics).
196 template <VehicleType T>
197 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
199 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
202 /** Class to read from a NewGRF file */
203 class ByteReader {
204 protected:
205 byte *data;
206 byte *end;
208 public:
209 ByteReader(byte *data, byte *end) : data(data), end(end) { }
211 class out_of_data { };
213 inline byte ReadByte()
215 if (data < end) return *(data)++;
216 throw out_of_data();
219 uint16 ReadWord()
221 uint16 val = ReadByte();
222 return val | (ReadByte() << 8);
225 uint16 ReadExtendedByte()
227 uint16 val = ReadByte();
228 return val == 0xFF ? ReadWord() : val;
231 uint32 ReadDWord()
233 uint32 val = ReadWord();
234 return val | (ReadWord() << 16);
237 uint32 ReadLabel (void)
239 return BSWAP32(this->ReadDWord());
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 (void);
256 inline size_t Remaining() const
258 return end - data;
261 inline bool HasData(size_t count = 1) const
263 return Remaining() >= count;
266 uint32 PeekDWord() const
268 if (!HasData (4)) throw out_of_data();
269 return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
272 const byte *GetData (size_t n)
274 if (!HasData (n)) throw out_of_data();
275 const byte *p = data;
276 data += n;
277 return p;
280 inline void Skip(size_t len)
282 data += len;
283 /* It is valid to move the buffer to exactly the end of the data,
284 * as there may not be any more data read. */
285 if (data > end) throw out_of_data();
288 byte *Dup (size_t len)
290 if (!HasData (len)) throw out_of_data();
292 byte *p = xmemdupt (data, len);
293 data += len;
294 return p;
298 const char *ByteReader::ReadString (void)
300 const char *string = reinterpret_cast<char *>(data);
302 size_t remaining = Remaining();
303 size_t string_length = ttd_strnlen (string, remaining);
305 if (string_length == remaining) {
306 /* String was not NUL terminated, so make sure it is now. */
307 grfmsg(7, "String was not terminated with a zero byte.");
308 data = end;
309 data[-1] = 0;
310 } else {
311 /* Increase the string length to include the NUL byte. */
312 string_length++;
313 data += string_length;
316 return string;
319 typedef int (*SpecialSpriteHandler) (ByteReader *buf);
321 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.
323 /** Temporary engine data used when loading only */
324 struct GRFTempEngineData {
325 /** Summary state of refittability properties */
326 enum Refittability {
327 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
328 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
329 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
332 uint16 cargo_allowed;
333 uint16 cargo_disallowed;
334 RailTypeLabel railtypelabel;
335 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
336 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
337 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
338 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
339 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
340 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
343 * Update the summary refittability on setting a refittability property.
344 * @param non_empty true if the GRF sets the vehicle to be refittable.
346 void UpdateRefittability(bool non_empty)
348 if (non_empty) {
349 this->refittability = NONEMPTY;
350 } else if (this->refittability == UNSET) {
351 this->refittability = EMPTY;
356 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
359 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
360 * GRM for vehicles is only used if dynamic engine allocation is disabled,
361 * so 256 is the number of original engines. */
362 static uint32 _grm_engines[256];
364 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
365 static uint32 _grm_cargoes[NUM_CARGO * 2];
367 struct GRFLocation {
368 uint32 grfid;
369 uint32 nfoline;
371 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
373 bool operator<(const GRFLocation &other) const
375 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
378 bool operator == (const GRFLocation &other) const
380 return this->grfid == other.grfid && this->nfoline == other.nfoline;
384 static std::map<GRFLocation, SpriteID> _grm_sprites;
385 typedef std::map <GRFLocation, ttd_unique_free_ptr <byte> > GRFLineToSpriteOverride;
386 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
389 * DEBUG() function dedicated to newGRF debugging messages
390 * Function is essentially the same as DEBUG(grf, severity, ...) with the
391 * addition of file:line information when parsing grf files.
392 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
393 * loading/parsing grf files, not for runtime debug messages as there
394 * is no file information available during that time.
395 * @param severity debugging severity level, see debug.h
396 * @param str message in printf() format
398 void CDECL grfmsg(int severity, const char *str, ...)
400 char buf[1024];
401 va_list va;
403 va_start(va, str);
404 bstrvfmt (buf, str, va);
405 va_end(va);
407 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
411 * Obtain a NewGRF file by its grfID
412 * @param grfid The grfID to obtain the file for
413 * @return The file.
415 static GRFFile *GetFileByGRFID(uint32 grfid)
417 const GRFFile * const *end = _grf_files.End();
418 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
419 if ((*file)->grfid == grfid) return *file;
421 return NULL;
425 * Obtain a NewGRF file by its filename
426 * @param filename The filename to obtain the file for.
427 * @return The file.
429 static GRFFile *GetFileByFilename(const char *filename)
431 const GRFFile * const *end = _grf_files.End();
432 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
433 if (strcmp((*file)->filename, filename) == 0) return *file;
435 return NULL;
438 /** Reset all NewGRFData that was used only while processing data */
439 static void ClearTemporaryNewGRFData(GRFFile *gf)
441 /* Clear the GOTO labels used for GRF processing */
442 for (GRFLabel *l = gf->label; l != NULL;) {
443 GRFLabel *l2 = l->next;
444 free(l);
445 l = l2;
447 gf->label = NULL;
451 * Disable the GRF being loaded
452 * @param message Error message or STR_NULL.
453 * @return Error message of the GRF for further customisation.
455 static GRFError *DisableCur (StringID message = STR_NULL)
457 GRFConfig *config = _cur.grfconfig;
459 config->status = GCS_DISABLED;
460 if (_cur.grffile != NULL) ClearTemporaryNewGRFData (_cur.grffile);
462 if (message != STR_NULL) {
463 delete config->error;
464 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
465 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
468 return config->error;
472 * Disable a GRF
473 * @param message Error message.
474 * @param config GRFConfig to disable.
476 static void DisableGrf (StringID message, GRFConfig *config)
478 assert (config != NULL);
479 assert (config != _cur.grfconfig);
481 config->status = GCS_DISABLED;
483 GRFFile *file = GetFileByGRFID (config->ident.grfid);
484 if (file != NULL) ClearTemporaryNewGRFData(file);
486 delete config->error;
487 config->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, message);
488 config->error->data = xstrdup (_cur.grfconfig->GetName());
492 * Information for mapping static StringIDs.
494 struct StringIDMapping {
495 uint32 grfid; ///< Source NewGRF.
496 StringID source; ///< Source StringID (GRF local).
497 StringID *target; ///< Destination for mapping result.
499 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
500 static StringIDMappingVector _string_to_grf_mapping;
503 * Record a static StringID for getting translated later.
504 * @param source Source StringID (GRF local).
505 * @param target Destination for the mapping result.
507 static void AddStringForMapping(StringID source, StringID *target)
509 *target = STR_UNDEFINED;
510 StringIDMapping *item = _string_to_grf_mapping.Append();
511 item->grfid = _cur.grffile->grfid;
512 item->source = source;
513 item->target = target;
517 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
518 * string IDs, but only for the ones we are aware off; the rest
519 * like likely unused and will show a warning.
520 * @param str the string ID to convert
521 * @return the converted string ID
523 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
525 /* StringID table for TextIDs 0x4E->0x6D */
526 static const StringID units_volume[] = {
527 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
528 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
529 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
530 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
531 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
532 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
533 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
534 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
537 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
538 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
540 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
541 assert_compile(stringend - stringid == end - begin); \
542 if (str >= begin && str <= end) return str + (stringid - begin)
544 /* We have some changes in our cargo strings, resulting in some missing. */
545 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
546 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
547 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
548 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
549 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
550 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
552 /* Map building names according to our lang file changes. There are several
553 * ranges of house ids, all of which need to be remapped to allow newgrfs
554 * to use original house names. */
555 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
556 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
557 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
559 /* Same thing for industries */
560 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
561 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
562 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
563 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
564 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
566 switch (str) {
567 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
568 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
569 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
571 #undef TEXTID_TO_STRINGID
573 if (str == STR_NULL) return STR_EMPTY;
575 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
577 return STR_EMPTY;
581 * Used when setting an object's property to map to the GRF's strings
582 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
583 * @param grfid Id of the grf file.
584 * @param str StringID that we want to have the equivalent in OoenTTD.
585 * @return The properly adjusted StringID.
587 StringID MapGRFStringID(uint32 grfid, StringID str)
589 if (IsInsideMM(str, 0xD800, 0xE000)) {
590 /* General text provided by NewGRF.
591 * In the specs this is called the 0xDCxx range (misc presistent texts),
592 * but we meanwhile extended the range to 0xD800-0xDFFF.
593 * Note: We are not involved in the "persistent" business, since we do not store
594 * any NewGRF strings in savegames. */
595 return GetGRFStringID(grfid, str);
596 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
597 /* Callback text provided by NewGRF.
598 * In the specs this is called the 0xD0xx range (misc graphics texts).
599 * These texts can be returned by various callbacks.
601 * Due to how TTDP implements the GRF-local- to global-textid translation
602 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
603 * We do not care about that difference and just mask out the 0x400 bit.
605 str &= ~0x400;
606 return GetGRFStringID(grfid, str);
607 } else {
608 /* The NewGRF wants to include/reference an original TTD string.
609 * Try our best to find an equivalent one. */
610 return TTDPStringIDToOTTDStringIDMapping(str);
614 static std::map<uint32, uint32> _grf_id_overrides;
617 * Set the override for a NewGRF
618 * @param source_grfid The grfID which wants to override another NewGRF.
619 * @param target_grfid The grfID which is being overridden.
621 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
623 _grf_id_overrides[source_grfid] = target_grfid;
624 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
628 * Returns the engine associated to a certain internal_id, resp. allocates it.
629 * @param file NewGRF that wants to change the engine.
630 * @param type Vehicle type.
631 * @param internal_id Engine ID inside the NewGRF.
632 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
633 * @return The requested engine.
635 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
637 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
638 * them use the same engine slots. */
639 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
640 if (_settings_game.vehicle.dynamic_engines) {
641 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
642 scope_grfid = file->grfid;
643 uint32 override = _grf_id_overrides[file->grfid];
644 if (override != 0) {
645 scope_grfid = override;
646 const GRFFile *grf_match = GetFileByGRFID(override);
647 if (grf_match == NULL) {
648 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
649 } else {
650 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
654 /* Check if the engine is registered in the override manager */
655 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
656 if (engine != INVALID_ENGINE) {
657 Engine *e = Engine::Get(engine);
658 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
659 return e;
663 /* Check if there is an unreserved slot */
664 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
665 if (engine != INVALID_ENGINE) {
666 Engine *e = Engine::Get(engine);
668 if (e->grf_prop.grffile == NULL) {
669 e->grf_prop.grffile = file;
670 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
673 /* Reserve the engine slot */
674 if (!static_access) {
675 EngineIDMapping *eid = _engine_mngr.Get(engine);
676 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
679 return e;
682 if (static_access) return NULL;
684 if (!Engine::CanAllocateItem()) {
685 grfmsg(0, "Can't allocate any more engines");
686 return NULL;
689 size_t engine_pool_size = Engine::GetPoolSize();
691 /* ... it's not, so create a new one based off an existing engine */
692 Engine *e = new Engine(type, internal_id);
693 e->grf_prop.grffile = file;
695 /* Reserve the engine slot */
696 assert(_engine_mngr.Length() == e->index);
697 EngineIDMapping *eid = _engine_mngr.Append();
698 eid->type = type;
699 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
700 eid->internal_id = internal_id;
701 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
703 if (engine_pool_size != Engine::GetPoolSize()) {
704 /* Resize temporary engine data ... */
705 _gted = xrealloct (_gted, Engine::GetPoolSize());
707 /* and blank the new block. */
708 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
709 memset(_gted + engine_pool_size, 0, len);
711 if (type == VEH_TRAIN) {
712 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
715 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
717 return e;
721 * Return the ID of a new engine
722 * @param file The NewGRF file providing the engine.
723 * @param type The Vehicle type.
724 * @param internal_id NewGRF-internal ID of the engine.
725 * @return The new EngineID.
726 * @note depending on the dynamic_engine setting and a possible override
727 * property the grfID may be unique or overwriting or partially re-defining
728 * properties of an existing engine.
730 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
732 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
733 if (_settings_game.vehicle.dynamic_engines) {
734 scope_grfid = file->grfid;
735 uint32 override = _grf_id_overrides[file->grfid];
736 if (override != 0) scope_grfid = override;
739 return _engine_mngr.GetID(type, internal_id, scope_grfid);
743 * Read a sprite and paletteD from the GRF and map the colour modifiers
744 * of TTDPatch to those that Open is using.
745 * @param buf Input stream.
746 * @param grf_sprite Pointer to the structure to read.
748 static void ReadPalSprite (ByteReader *buf, PalSpriteID *grf_sprite)
750 SpriteID sprite = buf->ReadWord();
751 PaletteID pal = buf->ReadWord();
753 if (HasBit(pal, 14)) {
754 ClrBit(pal, 14);
755 SetBit(sprite, SPRITE_MODIFIER_OPAQUE);
758 if (HasBit(sprite, 14)) {
759 ClrBit(sprite, 14);
760 SetBit(sprite, PALETTE_MODIFIER_TRANSPARENT);
763 if (HasBit(sprite, 15)) {
764 ClrBit(sprite, 15);
765 SetBit(sprite, PALETTE_MODIFIER_COLOUR);
768 grf_sprite->sprite = sprite;
769 grf_sprite->pal = pal;
773 * Read a sprite and a palette from the GRF and convert them into a format
774 * suitable to OpenTTD.
775 * @param buf Input stream.
776 * @param read_flags Whether to read TileLayoutFlags.
777 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
778 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
779 * @param feature GrfSpecFeature to use spritesets from.
780 * @param [out] grf_sprite Read sprite and palette.
781 * @param [out] pflags Read TileLayoutFlags.
782 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
783 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
784 * @return Whether reading succeeded.
786 static bool ReadSpriteLayoutSprite (ByteReader *buf, bool read_flags,
787 bool invert_action1_flag, bool use_cur_spritesets, int feature,
788 PalSpriteID *grf_sprite, TileLayoutFlags *pflags = NULL,
789 uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
791 ReadPalSprite (buf, grf_sprite);
793 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
794 if (pflags != NULL) *pflags = flags;
796 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
797 ClrBit(grf_sprite->pal, 15);
798 if (custom_sprite) {
799 /* Use sprite from Action 1 */
800 uint index = GB(grf_sprite->sprite, 0, 14);
801 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
802 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
803 grf_sprite->sprite = SPR_IMG_QUERY;
804 grf_sprite->pal = PAL_NONE;
805 } else {
806 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
807 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
808 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
809 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
811 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
812 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
813 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
814 return false;
817 if (flags & TLF_CUSTOM_PALETTE) {
818 /* Use palette from Action 1 */
819 uint index = GB(grf_sprite->pal, 0, 14);
820 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
821 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
822 grf_sprite->pal = PAL_NONE;
823 } else {
824 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
825 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
826 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
827 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
829 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
830 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
831 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
832 return false;
835 return true;
839 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
840 * @param buf Input stream.
841 * @param flags TileLayoutFlags to process.
842 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
843 * @param dts Sprite layout to insert data into.
844 * @param index Sprite index to process; 0 for ground sprite.
845 * @return Whether reading succeeded.
847 static bool ReadSpriteLayoutRegisters (ByteReader *buf, TileLayoutFlags flags,
848 bool is_parent, NewGRFSpriteLayout *dts, uint index)
850 if (!(flags & TLF_DRAWING_FLAGS)) return true;
852 if (dts->registers == NULL) dts->AllocateRegisters();
853 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
854 regs.flags = flags & TLF_DRAWING_FLAGS;
856 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
857 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
858 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
860 if (is_parent) {
861 if (flags & TLF_BB_XY_OFFSET) {
862 regs.delta.parent[0] = buf->ReadByte();
863 regs.delta.parent[1] = buf->ReadByte();
865 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
866 } else {
867 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
868 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
871 if (flags & TLF_SPRITE_VAR10) {
872 regs.sprite_var10 = buf->ReadByte();
873 if (regs.sprite_var10 > TLR_MAX_VAR10) {
874 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
875 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
876 return false;
880 if (flags & TLF_PALETTE_VAR10) {
881 regs.palette_var10 = buf->ReadByte();
882 if (regs.palette_var10 > TLR_MAX_VAR10) {
883 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
884 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
885 return false;
889 return true;
893 * Read a spritelayout from the GRF.
894 * @param buf Input
895 * @param num_building_sprites Number of building sprites to read
896 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
897 * @param feature GrfSpecFeature to use spritesets from.
898 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
899 * @param no_z_position Whether bounding boxes have no Z offset
900 * @param dts Layout container to output into
901 * @return True on error (GRF was disabled).
903 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
905 uint16 max_sprite_offset[256];
906 uint16 max_palette_offset[256];
907 assert (num_building_sprites < lengthof(max_sprite_offset));
908 assert (num_building_sprites < lengthof(max_palette_offset));
909 MemSetT (max_sprite_offset, 0, num_building_sprites + 1);
910 MemSetT (max_palette_offset, 0, num_building_sprites + 1);
912 bool has_flags = HasBit(num_building_sprites, 6);
913 ClrBit(num_building_sprites, 6);
914 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
915 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
916 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
918 /* Groundsprite */
919 TileLayoutFlags flags;
920 if (!ReadSpriteLayoutSprite (buf, has_flags, false,
921 use_cur_spritesets, feature, &dts->ground, &flags,
922 max_sprite_offset, max_palette_offset)) {
923 return true;
926 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
927 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
928 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
929 return true;
932 if (!ReadSpriteLayoutRegisters (buf, flags, false, dts, 0)) {
933 return true;
936 for (uint i = 0; i < num_building_sprites; i++) {
937 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
939 if (!ReadSpriteLayoutSprite (buf, has_flags, false,
940 use_cur_spritesets, feature, &seq->image, &flags,
941 max_sprite_offset + i + 1, max_palette_offset + i + 1)) {
942 return true;
945 if (flags & ~valid_flags) {
946 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
947 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
948 return true;
951 seq->delta_x = buf->ReadByte();
952 seq->delta_y = buf->ReadByte();
954 if (!no_z_position) seq->delta_z = buf->ReadByte();
956 if (seq->IsParentSprite()) {
957 seq->size_x = buf->ReadByte();
958 seq->size_y = buf->ReadByte();
959 seq->size_z = buf->ReadByte();
962 if (!ReadSpriteLayoutRegisters (buf, flags, seq->IsParentSprite(), dts, i + 1)) {
963 return true;
967 /* Check if the number of sprites per spriteset is consistent */
968 bool is_consistent = true;
969 dts->consistent_max_offset = 0;
970 for (uint i = 0; i < num_building_sprites + 1; i++) {
971 if (max_sprite_offset[i] > 0) {
972 if (dts->consistent_max_offset == 0) {
973 dts->consistent_max_offset = max_sprite_offset[i];
974 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
975 is_consistent = false;
976 break;
979 if (max_palette_offset[i] > 0) {
980 if (dts->consistent_max_offset == 0) {
981 dts->consistent_max_offset = max_palette_offset[i];
982 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
983 is_consistent = false;
984 break;
989 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
990 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
992 if (!is_consistent || dts->registers != NULL) {
993 dts->consistent_max_offset = 0;
994 if (dts->registers == NULL) dts->AllocateRegisters();
996 for (uint i = 0; i < num_building_sprites + 1; i++) {
997 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
998 regs.max_sprite_offset = max_sprite_offset[i];
999 regs.max_palette_offset = max_palette_offset[i];
1003 return false;
1007 * Translate the refit mask.
1009 static uint32 TranslateRefitMask(uint32 refit_mask)
1011 uint32 result = 0;
1012 uint8 bit;
1013 FOR_EACH_SET_BIT(bit, refit_mask) {
1014 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
1015 if (cargo != CT_INVALID) SetBit(result, cargo);
1017 return result;
1021 * Converts TTD(P) Base Price pointers into the enum used by OTTD
1022 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
1023 * @param base_pointer TTD(P) Base Price Pointer
1024 * @param error_location Function name for grf error messages
1025 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
1027 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
1029 /* Special value for 'none' */
1030 if (base_pointer == 0) {
1031 *index = INVALID_PRICE;
1032 return;
1035 static const uint32 start = 0x4B34; ///< Position of first base price
1036 static const uint32 size = 6; ///< Size of each base price record
1038 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
1039 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
1040 return;
1043 *index = (Price)((base_pointer - start) / size);
1046 /** Possible return values for the FeatureChangeInfo functions */
1047 enum ChangeInfoResult {
1048 CIR_SUCCESS, ///< Variable was parsed and read
1049 CIR_DISABLED, ///< GRF was disabled due to error
1050 CIR_UNHANDLED, ///< Variable was parsed but unread
1051 CIR_UNKNOWN, ///< Variable is unknown
1052 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
1055 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
1058 * Define properties common to all vehicles
1059 * @param ei Engine info.
1060 * @param prop The property to change.
1061 * @param buf The property value.
1062 * @return ChangeInfoResult.
1064 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1066 switch (prop) {
1067 case 0x00: // Introduction date
1068 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1069 break;
1071 case 0x02: // Decay speed
1072 ei->decay_speed = buf->ReadByte();
1073 break;
1075 case 0x03: // Vehicle life
1076 ei->lifelength = buf->ReadByte();
1077 break;
1079 case 0x04: // Model life
1080 ei->base_life = buf->ReadByte();
1081 break;
1083 case 0x06: // Climates available
1084 ei->climates = buf->ReadByte();
1085 break;
1087 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1088 /* Amount of cargo loaded during a vehicle's "loading tick" */
1089 ei->load_amount = buf->ReadByte();
1090 break;
1092 default:
1093 return CIR_UNKNOWN;
1096 return CIR_SUCCESS;
1100 * Define properties for rail vehicles
1101 * @param engine :ocal ID of the first vehicle.
1102 * @param numinfo Number of subsequent IDs to change the property for.
1103 * @param prop The property to change.
1104 * @param buf The property value.
1105 * @return ChangeInfoResult.
1107 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1109 ChangeInfoResult ret = CIR_SUCCESS;
1111 for (int i = 0; i < numinfo; i++) {
1112 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1113 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1115 EngineInfo *ei = &e->info;
1116 RailVehicleInfo *rvi = &e->u.rail;
1118 switch (prop) {
1119 case 0x05: { // Track type
1120 uint8 tracktype = buf->ReadByte();
1122 if (tracktype < _cur.grffile->railtype_list.Length()) {
1123 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1124 break;
1127 switch (tracktype) {
1128 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1129 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1130 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1131 default:
1132 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1133 break;
1135 break;
1138 case 0x08: // AI passenger service
1139 /* Tells the AI that this engine is designed for
1140 * passenger services and shouldn't be used for freight. */
1141 rvi->ai_passenger_only = buf->ReadByte();
1142 break;
1144 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1145 uint16 speed = buf->ReadWord();
1146 if (speed == 0xFFFF) speed = 0;
1148 rvi->max_speed = speed;
1149 break;
1152 case PROP_TRAIN_POWER: // 0x0B Power
1153 rvi->power = buf->ReadWord();
1155 /* Set engine / wagon state based on power */
1156 if (rvi->power != 0) {
1157 if (rvi->railveh_type == RAILVEH_WAGON) {
1158 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1160 } else {
1161 rvi->railveh_type = RAILVEH_WAGON;
1163 break;
1165 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1166 rvi->running_cost = buf->ReadByte();
1167 break;
1169 case 0x0E: // Running cost base
1170 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1171 break;
1173 case 0x12: { // Sprite ID
1174 uint8 spriteid = buf->ReadByte();
1175 uint8 orig_spriteid = spriteid;
1177 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1178 * as an array index, so we need it to be half the original value. */
1179 if (spriteid < 0xFD) spriteid >>= 1;
1181 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1182 rvi->image_index = spriteid;
1183 } else {
1184 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1185 rvi->image_index = 0;
1187 break;
1190 case 0x13: { // Dual-headed
1191 uint8 dual = buf->ReadByte();
1193 if (dual != 0) {
1194 rvi->railveh_type = RAILVEH_MULTIHEAD;
1195 } else {
1196 rvi->railveh_type = rvi->power == 0 ?
1197 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1199 break;
1202 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1203 rvi->capacity = buf->ReadByte();
1204 break;
1206 case 0x15: { // Cargo type
1207 _gted[e->index].defaultcargo_grf = _cur.grffile;
1208 uint8 ctype = buf->ReadByte();
1210 if (ctype == 0xFF) {
1211 /* 0xFF is specified as 'use first refittable' */
1212 ei->cargo_type = CT_INVALID;
1213 } else if (_cur.grffile->grf_version >= 8) {
1214 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1215 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1216 } else if (ctype < NUM_CARGO) {
1217 /* Use untranslated cargo. */
1218 ei->cargo_type = ctype;
1219 } else {
1220 ei->cargo_type = CT_INVALID;
1221 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1223 break;
1226 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1227 SB(rvi->weight, 0, 8, buf->ReadByte());
1228 break;
1230 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1231 rvi->cost_factor = buf->ReadByte();
1232 break;
1234 case 0x18: // AI rank
1235 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1236 buf->ReadByte();
1237 break;
1239 case 0x19: { // Engine traction type
1240 /* What do the individual numbers mean?
1241 * 0x00 .. 0x07: Steam
1242 * 0x08 .. 0x27: Diesel
1243 * 0x28 .. 0x31: Electric
1244 * 0x32 .. 0x37: Monorail
1245 * 0x38 .. 0x41: Maglev
1247 uint8 traction = buf->ReadByte();
1248 EngineClass engclass;
1250 if (traction <= 0x07) {
1251 engclass = EC_STEAM;
1252 } else if (traction <= 0x27) {
1253 engclass = EC_DIESEL;
1254 } else if (traction <= 0x31) {
1255 engclass = EC_ELECTRIC;
1256 } else if (traction <= 0x37) {
1257 engclass = EC_MONORAIL;
1258 } else if (traction <= 0x41) {
1259 engclass = EC_MAGLEV;
1260 } else {
1261 break;
1264 if (_cur.grffile->railtype_list.Length() == 0) {
1265 /* Use traction type to select between normal and electrified
1266 * rail only when no translation list is in place. */
1267 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1268 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1271 rvi->engclass = engclass;
1272 break;
1275 case 0x1A: // Alter purchase list sort order
1276 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1277 break;
1279 case 0x1B: // Powered wagons power bonus
1280 rvi->pow_wag_power = buf->ReadWord();
1281 break;
1283 case 0x1C: // Refit cost
1284 ei->refit_cost = buf->ReadByte();
1285 break;
1287 case 0x1D: { // Refit cargo
1288 uint32 mask = buf->ReadDWord();
1289 _gted[e->index].UpdateRefittability(mask != 0);
1290 ei->refit_mask = TranslateRefitMask(mask);
1291 _gted[e->index].defaultcargo_grf = _cur.grffile;
1292 break;
1295 case 0x1E: // Callback
1296 ei->callback_mask = buf->ReadByte();
1297 break;
1299 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1300 rvi->tractive_effort = buf->ReadByte();
1301 break;
1303 case 0x20: // Air drag
1304 rvi->air_drag = buf->ReadByte();
1305 break;
1307 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1308 rvi->shorten_factor = buf->ReadByte();
1309 break;
1311 case 0x22: // Visual effect
1312 rvi->visual_effect = buf->ReadByte();
1313 /* Avoid accidentally setting visual_effect to the default value
1314 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1315 if (rvi->visual_effect == VE_DEFAULT) {
1316 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1317 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1319 break;
1321 case 0x23: // Powered wagons weight bonus
1322 rvi->pow_wag_weight = buf->ReadByte();
1323 break;
1325 case 0x24: { // High byte of vehicle weight
1326 byte weight = buf->ReadByte();
1328 if (weight > 4) {
1329 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1330 } else {
1331 SB(rvi->weight, 8, 8, weight);
1333 break;
1336 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1337 rvi->user_def_data = buf->ReadByte();
1338 break;
1340 case 0x26: // Retire vehicle early
1341 ei->retire_early = buf->ReadByte();
1342 break;
1344 case 0x27: // Miscellaneous flags
1345 ei->misc_flags = buf->ReadByte();
1346 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1347 _gted[e->index].prop27_set = true;
1348 break;
1350 case 0x28: // Cargo classes allowed
1351 _gted[e->index].cargo_allowed = buf->ReadWord();
1352 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1353 _gted[e->index].defaultcargo_grf = _cur.grffile;
1354 break;
1356 case 0x29: // Cargo classes disallowed
1357 _gted[e->index].cargo_disallowed = buf->ReadWord();
1358 _gted[e->index].UpdateRefittability(false);
1359 break;
1361 case 0x2A: // Long format introduction date (days since year 0)
1362 ei->base_intro = buf->ReadDWord();
1363 break;
1365 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1366 ei->cargo_age_period = buf->ReadWord();
1367 break;
1369 case 0x2C: // CTT refit include list
1370 case 0x2D: { // CTT refit exclude list
1371 uint8 count = buf->ReadByte();
1372 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1373 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1374 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1375 ctt = 0;
1376 while (count--) {
1377 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1378 if (ctype == CT_INVALID) continue;
1379 SetBit(ctt, ctype);
1381 break;
1384 default:
1385 ret = CommonVehicleChangeInfo(ei, prop, buf);
1386 break;
1390 return ret;
1394 * Define properties for road vehicles
1395 * @param engine Local ID of the first vehicle.
1396 * @param numinfo Number of subsequent IDs to change the property for.
1397 * @param prop The property to change.
1398 * @param buf The property value.
1399 * @return ChangeInfoResult.
1401 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1403 ChangeInfoResult ret = CIR_SUCCESS;
1405 for (int i = 0; i < numinfo; i++) {
1406 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1407 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1409 EngineInfo *ei = &e->info;
1410 RoadVehicleInfo *rvi = &e->u.road;
1412 switch (prop) {
1413 case 0x08: // Speed (1 unit is 0.5 kmh)
1414 rvi->max_speed = buf->ReadByte();
1415 break;
1417 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1418 rvi->running_cost = buf->ReadByte();
1419 break;
1421 case 0x0A: // Running cost base
1422 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1423 break;
1425 case 0x0E: { // Sprite ID
1426 uint8 spriteid = buf->ReadByte();
1427 uint8 orig_spriteid = spriteid;
1429 /* cars have different custom id in the GRF file */
1430 if (spriteid == 0xFF) spriteid = 0xFD;
1432 if (spriteid < 0xFD) spriteid >>= 1;
1434 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1435 rvi->image_index = spriteid;
1436 } else {
1437 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1438 rvi->image_index = 0;
1440 break;
1443 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1444 rvi->capacity = buf->ReadByte();
1445 break;
1447 case 0x10: { // Cargo type
1448 _gted[e->index].defaultcargo_grf = _cur.grffile;
1449 uint8 ctype = buf->ReadByte();
1451 if (ctype == 0xFF) {
1452 /* 0xFF is specified as 'use first refittable' */
1453 ei->cargo_type = CT_INVALID;
1454 } else if (_cur.grffile->grf_version >= 8) {
1455 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1456 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1457 } else if (ctype < NUM_CARGO) {
1458 /* Use untranslated cargo. */
1459 ei->cargo_type = ctype;
1460 } else {
1461 ei->cargo_type = CT_INVALID;
1462 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1464 break;
1467 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1468 rvi->cost_factor = buf->ReadByte();
1469 break;
1471 case 0x12: // SFX
1472 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1473 break;
1475 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1476 rvi->power = buf->ReadByte();
1477 break;
1479 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1480 rvi->weight = buf->ReadByte();
1481 break;
1483 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1484 _gted[e->index].rv_max_speed = buf->ReadByte();
1485 break;
1487 case 0x16: { // Cargoes available for refitting
1488 uint32 mask = buf->ReadDWord();
1489 _gted[e->index].UpdateRefittability(mask != 0);
1490 ei->refit_mask = TranslateRefitMask(mask);
1491 _gted[e->index].defaultcargo_grf = _cur.grffile;
1492 break;
1495 case 0x17: // Callback mask
1496 ei->callback_mask = buf->ReadByte();
1497 break;
1499 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1500 rvi->tractive_effort = buf->ReadByte();
1501 break;
1503 case 0x19: // Air drag
1504 rvi->air_drag = buf->ReadByte();
1505 break;
1507 case 0x1A: // Refit cost
1508 ei->refit_cost = buf->ReadByte();
1509 break;
1511 case 0x1B: // Retire vehicle early
1512 ei->retire_early = buf->ReadByte();
1513 break;
1515 case 0x1C: // Miscellaneous flags
1516 ei->misc_flags = buf->ReadByte();
1517 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1518 break;
1520 case 0x1D: // Cargo classes allowed
1521 _gted[e->index].cargo_allowed = buf->ReadWord();
1522 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1523 _gted[e->index].defaultcargo_grf = _cur.grffile;
1524 break;
1526 case 0x1E: // Cargo classes disallowed
1527 _gted[e->index].cargo_disallowed = buf->ReadWord();
1528 _gted[e->index].UpdateRefittability(false);
1529 break;
1531 case 0x1F: // Long format introduction date (days since year 0)
1532 ei->base_intro = buf->ReadDWord();
1533 break;
1535 case 0x20: // Alter purchase list sort order
1536 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1537 break;
1539 case 0x21: // Visual effect
1540 rvi->visual_effect = buf->ReadByte();
1541 /* Avoid accidentally setting visual_effect to the default value
1542 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1543 if (rvi->visual_effect == VE_DEFAULT) {
1544 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1545 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1547 break;
1549 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1550 ei->cargo_age_period = buf->ReadWord();
1551 break;
1553 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1554 rvi->shorten_factor = buf->ReadByte();
1555 break;
1557 case 0x24: // CTT refit include list
1558 case 0x25: { // CTT refit exclude list
1559 uint8 count = buf->ReadByte();
1560 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1561 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1562 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1563 ctt = 0;
1564 while (count--) {
1565 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1566 if (ctype == CT_INVALID) continue;
1567 SetBit(ctt, ctype);
1569 break;
1572 default:
1573 ret = CommonVehicleChangeInfo(ei, prop, buf);
1574 break;
1578 return ret;
1582 * Define properties for ships
1583 * @param engine Local ID of the first vehicle.
1584 * @param numinfo Number of subsequent IDs to change the property for.
1585 * @param prop The property to change.
1586 * @param buf The property value.
1587 * @return ChangeInfoResult.
1589 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1591 ChangeInfoResult ret = CIR_SUCCESS;
1593 for (int i = 0; i < numinfo; i++) {
1594 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1595 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1597 EngineInfo *ei = &e->info;
1598 ShipVehicleInfo *svi = &e->u.ship;
1600 switch (prop) {
1601 case 0x08: { // Sprite ID
1602 uint8 spriteid = buf->ReadByte();
1603 uint8 orig_spriteid = spriteid;
1605 /* ships have different custom id in the GRF file */
1606 if (spriteid == 0xFF) spriteid = 0xFD;
1608 if (spriteid < 0xFD) spriteid >>= 1;
1610 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1611 svi->image_index = spriteid;
1612 } else {
1613 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1614 svi->image_index = 0;
1616 break;
1619 case 0x09: // Refittable
1620 svi->old_refittable = (buf->ReadByte() != 0);
1621 break;
1623 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1624 svi->cost_factor = buf->ReadByte();
1625 break;
1627 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1628 svi->max_speed = buf->ReadByte();
1629 break;
1631 case 0x0C: { // Cargo type
1632 _gted[e->index].defaultcargo_grf = _cur.grffile;
1633 uint8 ctype = buf->ReadByte();
1635 if (ctype == 0xFF) {
1636 /* 0xFF is specified as 'use first refittable' */
1637 ei->cargo_type = CT_INVALID;
1638 } else if (_cur.grffile->grf_version >= 8) {
1639 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1640 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1641 } else if (ctype < NUM_CARGO) {
1642 /* Use untranslated cargo. */
1643 ei->cargo_type = ctype;
1644 } else {
1645 ei->cargo_type = CT_INVALID;
1646 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1648 break;
1651 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1652 svi->capacity = buf->ReadWord();
1653 break;
1655 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1656 svi->running_cost = buf->ReadByte();
1657 break;
1659 case 0x10: // SFX
1660 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1661 break;
1663 case 0x11: { // Cargoes available for refitting
1664 uint32 mask = buf->ReadDWord();
1665 _gted[e->index].UpdateRefittability(mask != 0);
1666 ei->refit_mask = TranslateRefitMask(mask);
1667 _gted[e->index].defaultcargo_grf = _cur.grffile;
1668 break;
1671 case 0x12: // Callback mask
1672 ei->callback_mask = buf->ReadByte();
1673 break;
1675 case 0x13: // Refit cost
1676 ei->refit_cost = buf->ReadByte();
1677 break;
1679 case 0x14: // Ocean speed fraction
1680 svi->ocean_speed_frac = buf->ReadByte();
1681 break;
1683 case 0x15: // Canal speed fraction
1684 svi->canal_speed_frac = buf->ReadByte();
1685 break;
1687 case 0x16: // Retire vehicle early
1688 ei->retire_early = buf->ReadByte();
1689 break;
1691 case 0x17: // Miscellaneous flags
1692 ei->misc_flags = buf->ReadByte();
1693 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1694 break;
1696 case 0x18: // Cargo classes allowed
1697 _gted[e->index].cargo_allowed = buf->ReadWord();
1698 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1699 _gted[e->index].defaultcargo_grf = _cur.grffile;
1700 break;
1702 case 0x19: // Cargo classes disallowed
1703 _gted[e->index].cargo_disallowed = buf->ReadWord();
1704 _gted[e->index].UpdateRefittability(false);
1705 break;
1707 case 0x1A: // Long format introduction date (days since year 0)
1708 ei->base_intro = buf->ReadDWord();
1709 break;
1711 case 0x1B: // Alter purchase list sort order
1712 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1713 break;
1715 case 0x1C: // Visual effect
1716 svi->visual_effect = buf->ReadByte();
1717 /* Avoid accidentally setting visual_effect to the default value
1718 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1719 if (svi->visual_effect == VE_DEFAULT) {
1720 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1721 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1723 break;
1725 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1726 ei->cargo_age_period = buf->ReadWord();
1727 break;
1729 case 0x1E: // CTT refit include list
1730 case 0x1F: { // CTT refit exclude list
1731 uint8 count = buf->ReadByte();
1732 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1733 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1734 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1735 ctt = 0;
1736 while (count--) {
1737 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1738 if (ctype == CT_INVALID) continue;
1739 SetBit(ctt, ctype);
1741 break;
1744 default:
1745 ret = CommonVehicleChangeInfo(ei, prop, buf);
1746 break;
1750 return ret;
1754 * Define properties for aircraft
1755 * @param engine Local ID of the aircraft.
1756 * @param numinfo Number of subsequent IDs to change the property for.
1757 * @param prop The property to change.
1758 * @param buf The property value.
1759 * @return ChangeInfoResult.
1761 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1763 ChangeInfoResult ret = CIR_SUCCESS;
1765 for (int i = 0; i < numinfo; i++) {
1766 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1767 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1769 EngineInfo *ei = &e->info;
1770 AircraftVehicleInfo *avi = &e->u.air;
1772 switch (prop) {
1773 case 0x08: { // Sprite ID
1774 uint8 spriteid = buf->ReadByte();
1775 uint8 orig_spriteid = spriteid;
1777 /* aircraft have different custom id in the GRF file */
1778 if (spriteid == 0xFF) spriteid = 0xFD;
1780 if (spriteid < 0xFD) spriteid >>= 1;
1782 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1783 avi->image_index = spriteid;
1784 } else {
1785 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1786 avi->image_index = 0;
1788 break;
1791 case 0x09: // Helicopter
1792 if (buf->ReadByte() == 0) {
1793 avi->subtype = AIR_HELI;
1794 } else {
1795 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1797 break;
1799 case 0x0A: // Large
1800 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1801 break;
1803 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1804 avi->cost_factor = buf->ReadByte();
1805 break;
1807 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1808 avi->max_speed = (buf->ReadByte() * 128) / 10;
1809 break;
1811 case 0x0D: // Acceleration
1812 avi->acceleration = buf->ReadByte();
1813 break;
1815 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1816 avi->running_cost = buf->ReadByte();
1817 break;
1819 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1820 avi->passenger_capacity = buf->ReadWord();
1821 break;
1823 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1824 avi->mail_capacity = buf->ReadByte();
1825 break;
1827 case 0x12: // SFX
1828 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1829 break;
1831 case 0x13: { // Cargoes available for refitting
1832 uint32 mask = buf->ReadDWord();
1833 _gted[e->index].UpdateRefittability(mask != 0);
1834 ei->refit_mask = TranslateRefitMask(mask);
1835 _gted[e->index].defaultcargo_grf = _cur.grffile;
1836 break;
1839 case 0x14: // Callback mask
1840 ei->callback_mask = buf->ReadByte();
1841 break;
1843 case 0x15: // Refit cost
1844 ei->refit_cost = buf->ReadByte();
1845 break;
1847 case 0x16: // Retire vehicle early
1848 ei->retire_early = buf->ReadByte();
1849 break;
1851 case 0x17: // Miscellaneous flags
1852 ei->misc_flags = buf->ReadByte();
1853 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1854 break;
1856 case 0x18: // Cargo classes allowed
1857 _gted[e->index].cargo_allowed = buf->ReadWord();
1858 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1859 _gted[e->index].defaultcargo_grf = _cur.grffile;
1860 break;
1862 case 0x19: // Cargo classes disallowed
1863 _gted[e->index].cargo_disallowed = buf->ReadWord();
1864 _gted[e->index].UpdateRefittability(false);
1865 break;
1867 case 0x1A: // Long format introduction date (days since year 0)
1868 ei->base_intro = buf->ReadDWord();
1869 break;
1871 case 0x1B: // Alter purchase list sort order
1872 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1873 break;
1875 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1876 ei->cargo_age_period = buf->ReadWord();
1877 break;
1879 case 0x1D: // CTT refit include list
1880 case 0x1E: { // CTT refit exclude list
1881 uint8 count = buf->ReadByte();
1882 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1883 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1884 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1885 ctt = 0;
1886 while (count--) {
1887 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1888 if (ctype == CT_INVALID) continue;
1889 SetBit(ctt, ctype);
1891 break;
1894 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1895 avi->max_range = buf->ReadWord();
1896 break;
1898 default:
1899 ret = CommonVehicleChangeInfo(ei, prop, buf);
1900 break;
1904 return ret;
1908 * Define properties for stations
1909 * @param stdid StationID of the first station tile.
1910 * @param numinfo Number of subsequent station tiles to change the property for.
1911 * @param prop The property to change.
1912 * @param buf The property value.
1913 * @return ChangeInfoResult.
1915 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1917 ChangeInfoResult ret = CIR_SUCCESS;
1919 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1920 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1921 return CIR_INVALID_ID;
1924 /* Allocate station specs if necessary */
1925 if (_cur.grffile->stations == NULL) _cur.grffile->stations = xcalloct<StationSpec*>(NUM_STATIONS_PER_GRF);
1927 for (int i = 0; i < numinfo; i++) {
1928 StationSpec *statspec = _cur.grffile->stations[stid + i];
1930 /* Check that the station we are modifying is defined. */
1931 if (statspec == NULL && prop != 0x08) {
1932 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1933 return CIR_INVALID_ID;
1936 switch (prop) {
1937 case 0x08: { // Class ID
1938 StationSpec **spec = &_cur.grffile->stations[stid + i];
1940 /* Property 0x08 is special; it is where the station is allocated */
1941 if (*spec == NULL) *spec = xcalloct<StationSpec>();
1943 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1944 uint32 classid = buf->ReadLabel();
1945 (*spec)->cls_id = StationClass::Allocate (classid);
1946 break;
1949 case 0x09: // Define sprite layout
1950 statspec->tiles = buf->ReadExtendedByte();
1951 delete[] statspec->renderdata; // delete earlier loaded stuff
1952 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1954 for (uint t = 0; t < statspec->tiles; t++) {
1955 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1956 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1958 if (buf->HasData(4) && buf->PeekDWord() == 0) {
1959 buf->Skip(4);
1960 extern const DrawTileSprites _station_display_datas_rail[8];
1961 dts->Clone(&_station_display_datas_rail[t % 8]);
1962 continue;
1965 /* On error, bail out immediately. Temporary GRF data was already freed */
1966 if (!ReadSpriteLayoutSprite (buf, false, false, false, GSF_STATIONS, &dts->ground)) {
1967 return CIR_DISABLED;
1970 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1971 tmp_layout.Clear();
1972 for (;;) {
1973 /* no relative bounding box support */
1974 DrawTileSeqStruct *dtss = tmp_layout.Append();
1975 MemSetT(dtss, 0);
1977 dtss->delta_x = buf->ReadByte();
1978 if (dtss->IsTerminator()) break;
1979 dtss->delta_y = buf->ReadByte();
1980 dtss->delta_z = buf->ReadByte();
1981 dtss->size_x = buf->ReadByte();
1982 dtss->size_y = buf->ReadByte();
1983 dtss->size_z = buf->ReadByte();
1985 /* On error, bail out immediately. Temporary GRF data was already freed */
1986 if (!ReadSpriteLayoutSprite (buf, false, true, false, GSF_STATIONS, &dtss->image)) {
1987 return CIR_DISABLED;
1990 dts->Clone(tmp_layout.Begin());
1992 break;
1994 case 0x0A: { // Copy sprite layout
1995 byte srcid = buf->ReadByte();
1996 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1998 if (srcstatspec == NULL) {
1999 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
2000 continue;
2003 delete[] statspec->renderdata; // delete earlier loaded stuff
2005 statspec->tiles = srcstatspec->tiles;
2006 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2007 for (uint t = 0; t < statspec->tiles; t++) {
2008 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
2010 break;
2013 case 0x0B: // Callback mask
2014 statspec->callback_mask = buf->ReadByte();
2015 break;
2017 case 0x0C: // Disallowed number of platforms
2018 statspec->disallowed_platforms = buf->ReadByte();
2019 break;
2021 case 0x0D: // Disallowed platform lengths
2022 statspec->disallowed_lengths = buf->ReadByte();
2023 break;
2025 case 0x0E: // Define custom layout
2026 statspec->copied_layouts = false;
2028 while (buf->HasData()) {
2029 byte length = buf->ReadByte();
2030 byte number = buf->ReadByte();
2032 if (length == 0 || number == 0) break;
2034 if (length > statspec->lengths) {
2035 statspec->platforms = xrealloct (statspec->platforms, length);
2036 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
2038 statspec->layouts = xrealloct (statspec->layouts, length);
2039 memset(statspec->layouts + statspec->lengths, 0,
2040 (length - statspec->lengths) * sizeof(*statspec->layouts));
2042 statspec->lengths = length;
2045 uint l = length - 1; // index is zero-based
2047 if (number > statspec->platforms[l]) {
2048 statspec->layouts[l] = xrealloct (statspec->layouts[l], number);
2049 /* We expect NULL being 0 here, but C99 guarantees that. */
2050 memset(statspec->layouts[l] + statspec->platforms[l], 0,
2051 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
2053 statspec->platforms[l] = number;
2056 StationLayout layout = buf->Dup (length * number);
2058 StationLayout *p = &statspec->layouts[l][number - 1];
2059 free (*p);
2060 *p = layout;
2062 break;
2064 case 0x0F: { // Copy custom layout
2065 byte srcid = buf->ReadByte();
2066 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2068 if (srcstatspec == NULL) {
2069 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2070 continue;
2073 statspec->lengths = srcstatspec->lengths;
2074 statspec->platforms = srcstatspec->platforms;
2075 statspec->layouts = srcstatspec->layouts;
2076 statspec->copied_layouts = true;
2077 break;
2080 case 0x10: // Little/lots cargo threshold
2081 statspec->cargo_threshold = buf->ReadWord();
2082 break;
2084 case 0x11: // Pylon placement
2085 statspec->pylons = buf->ReadByte();
2086 break;
2088 case 0x12: // Cargo types for random triggers
2089 statspec->cargo_triggers = buf->ReadDWord();
2090 if (_cur.grffile->grf_version >= 7) {
2091 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2093 break;
2095 case 0x13: // General flags
2096 statspec->flags = buf->ReadByte();
2097 break;
2099 case 0x14: // Overhead wire placement
2100 statspec->wires = buf->ReadByte();
2101 break;
2103 case 0x15: // Blocked tiles
2104 statspec->blocked = buf->ReadByte();
2105 break;
2107 case 0x16: // Animation info
2108 statspec->animation.frames = buf->ReadByte();
2109 statspec->animation.status = buf->ReadByte();
2110 break;
2112 case 0x17: // Animation speed
2113 statspec->animation.speed = buf->ReadByte();
2114 break;
2116 case 0x18: // Animation triggers
2117 statspec->animation.triggers = buf->ReadWord();
2118 break;
2120 case 0x1A: // Advanced sprite layout
2121 statspec->tiles = buf->ReadExtendedByte();
2122 delete[] statspec->renderdata; // delete earlier loaded stuff
2123 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2125 for (uint t = 0; t < statspec->tiles; t++) {
2126 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2127 uint num_building_sprites = buf->ReadByte();
2128 /* On error, bail out immediately. Temporary GRF data was already freed */
2129 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) {
2130 return CIR_DISABLED;
2133 break;
2135 default:
2136 ret = CIR_UNKNOWN;
2137 break;
2141 return ret;
2145 * Define properties for water features
2146 * @param id Type of the first water feature.
2147 * @param numinfo Number of subsequent water feature ids to change the property for.
2148 * @param prop The property to change.
2149 * @param buf The property value.
2150 * @return ChangeInfoResult.
2152 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2154 ChangeInfoResult ret = CIR_SUCCESS;
2156 if (id + numinfo > CF_END) {
2157 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2158 return CIR_INVALID_ID;
2161 for (int i = 0; i < numinfo; i++) {
2162 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2164 switch (prop) {
2165 case 0x08:
2166 cp->callback_mask = buf->ReadByte();
2167 break;
2169 case 0x09:
2170 cp->flags = buf->ReadByte();
2171 break;
2173 default:
2174 ret = CIR_UNKNOWN;
2175 break;
2179 return ret;
2183 * Define properties for bridges
2184 * @param brid BridgeID of the bridge.
2185 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2186 * @param prop The property to change.
2187 * @param buf The property value.
2188 * @return ChangeInfoResult.
2190 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2192 ChangeInfoResult ret = CIR_SUCCESS;
2194 if (brid + numinfo > MAX_BRIDGES) {
2195 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2196 return CIR_INVALID_ID;
2199 for (int i = 0; i < numinfo; i++) {
2200 BridgeSpec *bridge = &_bridge[brid + i];
2202 switch (prop) {
2203 case 0x08: { // Year of availability
2204 /* We treat '0' as always available */
2205 byte year = buf->ReadByte();
2206 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2207 break;
2210 case 0x09: // Minimum length
2211 bridge->min_length = buf->ReadByte();
2212 break;
2214 case 0x0A: // Maximum length
2215 bridge->max_length = buf->ReadByte();
2216 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2217 break;
2219 case 0x0B: // Cost factor
2220 bridge->price = buf->ReadByte();
2221 break;
2223 case 0x0C: // Maximum speed
2224 bridge->speed = buf->ReadWord();
2225 break;
2227 case 0x0D: { // Bridge sprite tables
2228 byte tableid = buf->ReadByte();
2229 byte numtables = buf->ReadByte();
2231 if (bridge->sprite_table == NULL) {
2232 /* Allocate memory for sprite table pointers and zero out */
2233 bridge->sprite_table = xcalloct<PalSpriteID*>(7);
2236 for (; numtables-- != 0; tableid++) {
2237 if (tableid >= 7) { // skip invalid data
2238 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2239 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2240 continue;
2243 if (bridge->sprite_table[tableid] == NULL) {
2244 bridge->sprite_table[tableid] = xmalloct<PalSpriteID>(32);
2247 for (byte sprite = 0; sprite < 32; sprite++) {
2248 ReadPalSprite (buf, &bridge->sprite_table[tableid][sprite]);
2251 break;
2254 case 0x0E: // Flags; bit 0 - disable far pillars
2255 bridge->flags = buf->ReadByte();
2256 break;
2258 case 0x0F: // Long format year of availability (year since year 0)
2259 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2260 break;
2262 case 0x10: { // purchase string
2263 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2264 if (newone != STR_UNDEFINED) bridge->material = newone;
2265 break;
2268 case 0x11: // description of bridge with rails or roads
2269 case 0x12: {
2270 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2271 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2272 break;
2275 case 0x13: // 16 bits cost multiplier
2276 bridge->price = buf->ReadWord();
2277 break;
2279 case 0x14: // purchase sprite
2280 bridge->sprite = buf->ReadWord();
2281 bridge->pal = buf->ReadWord();
2282 break;
2284 default:
2285 ret = CIR_UNKNOWN;
2286 break;
2290 return ret;
2294 * Ignore a house property
2295 * @param prop Property to read.
2296 * @param buf Property value.
2297 * @return ChangeInfoResult.
2299 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2301 ChangeInfoResult ret = CIR_SUCCESS;
2303 switch (prop) {
2304 case 0x09:
2305 case 0x0B:
2306 case 0x0C:
2307 case 0x0D:
2308 case 0x0E:
2309 case 0x0F:
2310 case 0x11:
2311 case 0x14:
2312 case 0x15:
2313 case 0x16:
2314 case 0x18:
2315 case 0x19:
2316 case 0x1A:
2317 case 0x1B:
2318 case 0x1C:
2319 case 0x1D:
2320 case 0x1F:
2321 buf->ReadByte();
2322 break;
2324 case 0x0A:
2325 case 0x10:
2326 case 0x12:
2327 case 0x13:
2328 case 0x21:
2329 case 0x22:
2330 buf->ReadWord();
2331 break;
2333 case 0x1E:
2334 buf->ReadDWord();
2335 break;
2337 case 0x17:
2338 for (uint j = 0; j < 4; j++) buf->ReadByte();
2339 break;
2341 case 0x20: {
2342 byte count = buf->ReadByte();
2343 for (byte j = 0; j < count; j++) buf->ReadByte();
2344 break;
2347 default:
2348 ret = CIR_UNKNOWN;
2349 break;
2351 return ret;
2355 * Define properties for houses
2356 * @param hid HouseID of the house.
2357 * @param numinfo Number of subsequent houseIDs to change the property for.
2358 * @param prop The property to change.
2359 * @param buf The property value.
2360 * @return ChangeInfoResult.
2362 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2364 ChangeInfoResult ret = CIR_SUCCESS;
2366 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2367 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2368 return CIR_INVALID_ID;
2371 /* Allocate house specs if they haven't been allocated already. */
2372 if (_cur.grffile->housespec == NULL) {
2373 _cur.grffile->housespec = xcalloct<HouseSpec*>(NUM_HOUSES_PER_GRF);
2376 for (int i = 0; i < numinfo; i++) {
2377 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2379 if (prop != 0x08 && housespec == NULL) {
2380 /* If the house property 08 is not yet set, ignore this property */
2381 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2382 if (cir > ret) ret = cir;
2383 continue;
2386 switch (prop) {
2387 case 0x08: { // Substitute building type, and definition of a new house
2388 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2389 byte subs_id = buf->ReadByte();
2391 if (subs_id == 0xFF) {
2392 /* Instead of defining a new house, a substitute house id
2393 * of 0xFF disables the old house with the current id. */
2394 HouseSpec::Get(hid + i)->enabled = false;
2395 continue;
2396 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2397 /* The substitute id must be one of the original houses. */
2398 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2399 continue;
2402 /* Allocate space for this house. */
2403 if (*house == NULL) *house = xcalloct<HouseSpec>();
2405 housespec = *house;
2407 MemCpyT(housespec, HouseSpec::Get(subs_id));
2409 housespec->enabled = true;
2410 housespec->grf_prop.local_id = hid + i;
2411 housespec->grf_prop.subst_id = subs_id;
2412 housespec->grf_prop.grffile = _cur.grffile;
2413 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2414 housespec->random_colour[1] = 0x08; // for all new houses
2415 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2416 housespec->random_colour[3] = 0x06;
2418 /* Make sure that the third cargo type is valid in this
2419 * climate. This can cause problems when copying the properties
2420 * of a house that accepts food, where the new house is valid
2421 * in the temperate climate. */
2422 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2423 housespec->cargo_acceptance[2] = 0;
2426 _loaded_newgrf_features.has_newhouses = true;
2427 break;
2430 case 0x09: // Building flags
2431 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2432 break;
2434 case 0x0A: { // Availability years
2435 uint16 years = buf->ReadWord();
2436 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2437 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2438 break;
2441 case 0x0B: // Population
2442 housespec->population = buf->ReadByte();
2443 break;
2445 case 0x0C: // Mail generation multiplier
2446 housespec->mail_generation = buf->ReadByte();
2447 break;
2449 case 0x0D: // Passenger acceptance
2450 case 0x0E: // Mail acceptance
2451 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2452 break;
2454 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2455 int8 goods = buf->ReadByte();
2457 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2458 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2459 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2460 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2462 /* Make sure the cargo type is valid in this climate. */
2463 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2465 housespec->accepts_cargo[2] = cid;
2466 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2467 break;
2470 case 0x10: // Local authority rating decrease on removal
2471 housespec->remove_rating_decrease = buf->ReadWord();
2472 break;
2474 case 0x11: // Removal cost multiplier
2475 housespec->removal_cost = buf->ReadByte();
2476 break;
2478 case 0x12: // Building name ID
2479 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2480 break;
2482 case 0x13: // Building availability mask
2483 housespec->building_availability = (HouseZones)buf->ReadWord();
2484 break;
2486 case 0x14: // House callback mask
2487 housespec->callback_mask |= buf->ReadByte();
2488 break;
2490 case 0x15: { // House override byte
2491 byte override = buf->ReadByte();
2493 /* The house being overridden must be an original house. */
2494 if (override >= NEW_HOUSE_OFFSET) {
2495 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2496 continue;
2499 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2500 break;
2503 case 0x16: // Periodic refresh multiplier
2504 housespec->processing_time = min(buf->ReadByte(), 63);
2505 break;
2507 case 0x17: // Four random colours to use
2508 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2509 break;
2511 case 0x18: // Relative probability of appearing
2512 housespec->probability = buf->ReadByte();
2513 break;
2515 case 0x19: // Extra flags
2516 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2517 break;
2519 case 0x1A: // Animation frames
2520 housespec->animation.frames = buf->ReadByte();
2521 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2522 SB(housespec->animation.frames, 7, 1, 0);
2523 break;
2525 case 0x1B: // Animation speed
2526 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2527 break;
2529 case 0x1C: // Class of the building type
2530 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2531 break;
2533 case 0x1D: // Callback mask part 2
2534 housespec->callback_mask |= (buf->ReadByte() << 8);
2535 break;
2537 case 0x1E: { // Accepted cargo types
2538 uint32 cargotypes = buf->ReadDWord();
2540 /* Check if the cargo types should not be changed */
2541 if (cargotypes == 0xFFFFFFFF) break;
2543 for (uint j = 0; j < 3; j++) {
2544 /* Get the cargo number from the 'list' */
2545 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2546 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2548 if (cargo == CT_INVALID) {
2549 /* Disable acceptance of invalid cargo type */
2550 housespec->cargo_acceptance[j] = 0;
2551 } else {
2552 housespec->accepts_cargo[j] = cargo;
2555 break;
2558 case 0x1F: // Minimum life span
2559 housespec->minimum_life = buf->ReadByte();
2560 break;
2562 case 0x20: { // Cargo acceptance watch list
2563 byte count = buf->ReadByte();
2564 for (byte j = 0; j < count; j++) {
2565 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2566 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2568 break;
2571 case 0x21: // long introduction year
2572 housespec->min_year = buf->ReadWord();
2573 break;
2575 case 0x22: // long maximum year
2576 housespec->max_year = buf->ReadWord();
2577 break;
2579 default:
2580 ret = CIR_UNKNOWN;
2581 break;
2585 return ret;
2589 * Get the language map associated with a given NewGRF and language.
2590 * @param grfid The NewGRF to get the map for.
2591 * @param language_id The (NewGRF) language ID to get the map for.
2592 * @return The LanguageMap, or NULL if it couldn't be found.
2594 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2596 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2597 const GRFFile *grffile = GetFileByGRFID(grfid);
2598 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2602 * Load a cargo- or railtype-translation table.
2603 * @param gvid ID of the global variable. This is basically only checked for zerones.
2604 * @param numinfo Number of subsequent IDs to change the property for.
2605 * @param buf The property value.
2606 * @param [in,out] translation_table Storage location for the translation table.
2607 * @param name Name of the table for debug output.
2608 * @return ChangeInfoResult.
2610 template <typename T>
2611 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2613 if (gvid != 0) {
2614 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2615 return CIR_INVALID_ID;
2618 translation_table.Clear();
2619 for (int i = 0; i < numinfo; i++) {
2620 *translation_table.Append() = buf->ReadLabel();
2623 return CIR_SUCCESS;
2627 * Define properties for global variables
2628 * @param gvid ID of the global variable.
2629 * @param numinfo Number of subsequent IDs to change the property for.
2630 * @param prop The property to change.
2631 * @param buf The property value.
2632 * @return ChangeInfoResult.
2634 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2636 /* Properties which are handled as a whole */
2637 switch (prop) {
2638 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2639 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2641 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2642 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2644 default:
2645 break;
2648 /* Properties which are handled per item */
2649 ChangeInfoResult ret = CIR_SUCCESS;
2650 for (int i = 0; i < numinfo; i++) {
2651 switch (prop) {
2652 case 0x08: { // Cost base factor
2653 int factor = buf->ReadByte();
2654 uint price = gvid + i;
2656 if (price < PR_END) {
2657 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2658 } else {
2659 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2661 break;
2664 case 0x0A: { // Currency display names
2665 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2666 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2668 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2669 _currency_specs[curidx].name = newone;
2671 break;
2674 case 0x0B: { // Currency multipliers
2675 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2676 uint32 rate = buf->ReadDWord();
2678 if (curidx < CURRENCY_END) {
2679 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2680 * which OTTD does not. For this reason, divide grf value by 1000,
2681 * to be compatible */
2682 _currency_specs[curidx].rate = rate / 1000;
2683 } else {
2684 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2686 break;
2689 case 0x0C: { // Currency options
2690 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2691 uint16 options = buf->ReadWord();
2693 if (curidx < CURRENCY_END) {
2694 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2695 _currency_specs[curidx].separator[1] = '\0';
2696 /* By specifying only one bit, we prevent errors,
2697 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2698 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2699 } else {
2700 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2702 break;
2705 case 0x0D: { // Currency prefix symbol
2706 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2707 uint32 tempfix = buf->ReadDWord();
2709 if (curidx < CURRENCY_END) {
2710 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2711 _currency_specs[curidx].prefix[4] = 0;
2712 } else {
2713 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2715 break;
2718 case 0x0E: { // Currency suffix symbol
2719 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2720 uint32 tempfix = buf->ReadDWord();
2722 if (curidx < CURRENCY_END) {
2723 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2724 _currency_specs[curidx].suffix[4] = 0;
2725 } else {
2726 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2728 break;
2731 case 0x0F: { // Euro introduction dates
2732 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2733 Year year_euro = buf->ReadWord();
2735 if (curidx < CURRENCY_END) {
2736 _currency_specs[curidx].to_euro = year_euro;
2737 } else {
2738 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2740 break;
2743 case 0x10: // Snow line height table
2744 if (numinfo > 1 || IsSnowLineSet()) {
2745 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2746 } else if (!buf->HasData (SNOW_LINE_MONTHS * SNOW_LINE_DAYS)) {
2747 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2748 } else {
2749 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2751 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2752 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2753 table[i][j] = buf->ReadByte();
2754 if (_cur.grffile->grf_version >= 8) {
2755 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2756 } else {
2757 if (table[i][j] >= 128) {
2758 /* no snow */
2759 table[i][j] = 0xFF;
2760 } else {
2761 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2766 SetSnowLine(table);
2768 break;
2770 case 0x11: // GRF match for engine allocation
2771 /* This is loaded during the reservation stage, so just skip it here. */
2772 /* Each entry is 8 bytes. */
2773 buf->Skip(8);
2774 break;
2776 case 0x13: // Gender translation table
2777 case 0x14: // Case translation table
2778 case 0x15: { // Plural form translation
2779 uint curidx = gvid + i; // The current index, i.e. language.
2780 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2781 if (lang == NULL) {
2782 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2783 /* Skip over the data. */
2784 if (prop == 0x15) {
2785 buf->ReadByte();
2786 } else {
2787 while (buf->ReadByte() != 0) {
2788 buf->ReadString();
2791 break;
2794 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2796 if (prop == 0x15) {
2797 uint plural_form = buf->ReadByte();
2798 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2799 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2800 } else {
2801 _cur.grffile->language_map[curidx].plural_form = plural_form;
2803 break;
2806 for (;;) {
2807 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2808 if (newgrf_id == 0) break;
2810 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2812 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2813 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2814 * is just a subset of UTF8, or they need the bigger UTF8 characters
2815 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2816 WChar c;
2817 size_t len = Utf8Decode(&c, name);
2818 if (c == NFO_UTF8_IDENTIFIER) name += len;
2820 LanguageMap::Mapping map;
2821 map.newgrf_id = newgrf_id;
2822 if (prop == 0x13) {
2823 map.openttd_id = lang->GetGenderIndex(name);
2824 if (map.openttd_id >= MAX_NUM_GENDERS) {
2825 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2826 } else {
2827 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2829 } else {
2830 map.openttd_id = lang->GetCaseIndex(name);
2831 if (map.openttd_id >= MAX_NUM_CASES) {
2832 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2833 } else {
2834 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2838 break;
2841 default:
2842 ret = CIR_UNKNOWN;
2843 break;
2847 return ret;
2850 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2852 /* Properties which are handled as a whole */
2853 switch (prop) {
2854 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2855 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2857 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2858 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2860 default:
2861 break;
2864 /* Properties which are handled per item */
2865 ChangeInfoResult ret = CIR_SUCCESS;
2866 for (int i = 0; i < numinfo; i++) {
2867 switch (prop) {
2868 case 0x08: // Cost base factor
2869 case 0x15: // Plural form translation
2870 buf->ReadByte();
2871 break;
2873 case 0x0A: // Currency display names
2874 case 0x0C: // Currency options
2875 case 0x0F: // Euro introduction dates
2876 buf->ReadWord();
2877 break;
2879 case 0x0B: // Currency multipliers
2880 case 0x0D: // Currency prefix symbol
2881 case 0x0E: // Currency suffix symbol
2882 buf->ReadDWord();
2883 break;
2885 case 0x10: // Snow line height table
2886 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2887 break;
2889 case 0x11: { // GRF match for engine allocation
2890 uint32 s = buf->ReadDWord();
2891 uint32 t = buf->ReadDWord();
2892 SetNewGRFOverride(s, t);
2893 break;
2896 case 0x13: // Gender translation table
2897 case 0x14: // Case translation table
2898 while (buf->ReadByte() != 0) {
2899 buf->ReadString();
2901 break;
2903 default:
2904 ret = CIR_UNKNOWN;
2905 break;
2909 return ret;
2914 * Define properties for cargoes
2915 * @param cid Local ID of the cargo.
2916 * @param numinfo Number of subsequent IDs to change the property for.
2917 * @param prop The property to change.
2918 * @param buf The property value.
2919 * @return ChangeInfoResult.
2921 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2923 ChangeInfoResult ret = CIR_SUCCESS;
2925 if (cid + numinfo > NUM_CARGO) {
2926 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2927 return CIR_INVALID_ID;
2930 for (int i = 0; i < numinfo; i++) {
2931 CargoSpec *cs = CargoSpec::Get(cid + i);
2933 switch (prop) {
2934 case 0x08: // Bit number of cargo
2935 cs->bitnum = buf->ReadByte();
2936 if (cs->IsValid()) {
2937 cs->grffile = _cur.grffile;
2938 SetBit(_cargo_mask, cid + i);
2939 } else {
2940 ClrBit(_cargo_mask, cid + i);
2942 break;
2944 case 0x09: // String ID for cargo type name
2945 AddStringForMapping(buf->ReadWord(), &cs->name);
2946 break;
2948 case 0x0A: // String for 1 unit of cargo
2949 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2950 break;
2952 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2953 case 0x1B: // String for cargo units
2954 /* String for units of cargo. This is different in OpenTTD
2955 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2956 * Property 1B is used to set OpenTTD's behaviour. */
2957 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2958 break;
2960 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2961 case 0x1C: // String for any amount of cargo
2962 /* Strings for an amount of cargo. This is different in OpenTTD
2963 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2964 * Property 1C is used to set OpenTTD's behaviour. */
2965 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2966 break;
2968 case 0x0D: // String for two letter cargo abbreviation
2969 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2970 break;
2972 case 0x0E: // Sprite ID for cargo icon
2973 cs->sprite = buf->ReadWord();
2974 break;
2976 case 0x0F: // Weight of one unit of cargo
2977 cs->weight = buf->ReadByte();
2978 break;
2980 case 0x10: // Used for payment calculation
2981 cs->transit_days[0] = buf->ReadByte();
2982 break;
2984 case 0x11: // Used for payment calculation
2985 cs->transit_days[1] = buf->ReadByte();
2986 break;
2988 case 0x12: // Base cargo price
2989 cs->initial_payment = buf->ReadDWord();
2990 break;
2992 case 0x13: // Colour for station rating bars
2993 cs->rating_colour = buf->ReadByte();
2994 break;
2996 case 0x14: // Colour for cargo graph
2997 cs->legend_colour = buf->ReadByte();
2998 break;
3000 case 0x15: // Freight status
3001 cs->is_freight = (buf->ReadByte() != 0);
3002 break;
3004 case 0x16: // Cargo classes
3005 cs->classes = buf->ReadWord();
3006 break;
3008 case 0x17: // Cargo label
3009 cs->label = buf->ReadLabel();
3010 break;
3012 case 0x18: { // Town growth substitute type
3013 uint8 substitute_type = buf->ReadByte();
3015 switch (substitute_type) {
3016 case 0x00: cs->town_effect = TE_PASSENGERS; break;
3017 case 0x02: cs->town_effect = TE_MAIL; break;
3018 case 0x05: cs->town_effect = TE_GOODS; break;
3019 case 0x09: cs->town_effect = TE_WATER; break;
3020 case 0x0B: cs->town_effect = TE_FOOD; break;
3021 default:
3022 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3023 /* FALL THROUGH */
3024 case 0xFF: cs->town_effect = TE_NONE; break;
3026 break;
3029 case 0x19: // Town growth coefficient
3030 cs->multipliertowngrowth = buf->ReadWord();
3031 break;
3033 case 0x1A: // Bitmask of callbacks to use
3034 cs->callback_mask = buf->ReadByte();
3035 break;
3037 case 0x1D: // Vehicle capacity muliplier
3038 cs->multiplier = max<uint16>(1u, buf->ReadWord());
3039 break;
3041 default:
3042 ret = CIR_UNKNOWN;
3043 break;
3047 return ret;
3052 * Define properties for sound effects
3053 * @param sid Local ID of the sound.
3054 * @param numinfo Number of subsequent IDs to change the property for.
3055 * @param prop The property to change.
3056 * @param buf The property value.
3057 * @return ChangeInfoResult.
3059 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3061 ChangeInfoResult ret = CIR_SUCCESS;
3063 if (_cur.grffile->sound_offset == 0) {
3064 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3065 return CIR_INVALID_ID;
3068 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3069 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3070 return CIR_INVALID_ID;
3073 for (int i = 0; i < numinfo; i++) {
3074 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3076 switch (prop) {
3077 case 0x08: // Relative volume
3078 sound->volume = buf->ReadByte();
3079 break;
3081 case 0x09: // Priority
3082 sound->priority = buf->ReadByte();
3083 break;
3085 case 0x0A: { // Override old sound
3086 SoundID orig_sound = buf->ReadByte();
3088 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3089 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3090 } else {
3091 SoundEntry *old_sound = GetSound(orig_sound);
3093 /* Literally copy the data of the new sound over the original */
3094 *old_sound = *sound;
3096 break;
3099 default:
3100 ret = CIR_UNKNOWN;
3101 break;
3105 return ret;
3109 * Ignore an industry tile property
3110 * @param prop The property to ignore.
3111 * @param buf The property value.
3112 * @return ChangeInfoResult.
3114 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3116 ChangeInfoResult ret = CIR_SUCCESS;
3118 switch (prop) {
3119 case 0x09:
3120 case 0x0D:
3121 case 0x0E:
3122 case 0x10:
3123 case 0x11:
3124 case 0x12:
3125 buf->ReadByte();
3126 break;
3128 case 0x0A:
3129 case 0x0B:
3130 case 0x0C:
3131 case 0x0F:
3132 buf->ReadWord();
3133 break;
3135 default:
3136 ret = CIR_UNKNOWN;
3137 break;
3139 return ret;
3143 * Define properties for industry tiles
3144 * @param indtid Local ID of the industry tile.
3145 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3146 * @param prop The property to change.
3147 * @param buf The property value.
3148 * @return ChangeInfoResult.
3150 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3152 ChangeInfoResult ret = CIR_SUCCESS;
3154 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3155 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3156 return CIR_INVALID_ID;
3159 /* Allocate industry tile specs if they haven't been allocated already. */
3160 if (_cur.grffile->indtspec == NULL) {
3161 _cur.grffile->indtspec = xcalloct<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3164 for (int i = 0; i < numinfo; i++) {
3165 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3167 if (prop != 0x08 && tsp == NULL) {
3168 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3169 if (cir > ret) ret = cir;
3170 continue;
3173 switch (prop) {
3174 case 0x08: { // Substitute industry tile type
3175 byte subs_id = buf->ReadByte();
3177 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3178 /* The substitute id must be one of the original industry tile. */
3179 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3180 continue;
3183 /* Allocate space for this industry. */
3184 if (tsp == NULL) {
3185 tsp = xmemdupt (&_industry_tile_specs[subs_id]);
3186 _cur.grffile->indtspec[indtid + i] = tsp;
3188 tsp->enabled = true;
3190 /* A copied tile should not have the animation infos copied too.
3191 * The anim_state should be left untouched, though
3192 * It is up to the author to animate them himself */
3193 tsp->anim_production = INDUSTRYTILE_NOANIM;
3194 tsp->anim_next = INDUSTRYTILE_NOANIM;
3196 tsp->grf_prop.local_id = indtid + i;
3197 tsp->grf_prop.subst_id = subs_id;
3198 tsp->grf_prop.grffile = _cur.grffile;
3199 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3201 break;
3204 case 0x09: { // Industry tile override
3205 byte ovrid = buf->ReadByte();
3207 /* The industry being overridden must be an original industry. */
3208 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3209 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3210 continue;
3213 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3214 break;
3217 case 0x0A: // Tile acceptance
3218 case 0x0B:
3219 case 0x0C: {
3220 uint16 acctp = buf->ReadWord();
3221 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3222 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3223 break;
3226 case 0x0D: // Land shape flags
3227 tsp->slopes_refused = (Slope)buf->ReadByte();
3228 break;
3230 case 0x0E: // Callback mask
3231 tsp->callback_mask = buf->ReadByte();
3232 break;
3234 case 0x0F: // Animation information
3235 tsp->animation.frames = buf->ReadByte();
3236 tsp->animation.status = buf->ReadByte();
3237 break;
3239 case 0x10: // Animation speed
3240 tsp->animation.speed = buf->ReadByte();
3241 break;
3243 case 0x11: // Triggers for callback 25
3244 tsp->animation.triggers = buf->ReadByte();
3245 break;
3247 case 0x12: // Special flags
3248 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3249 break;
3251 default:
3252 ret = CIR_UNKNOWN;
3253 break;
3257 return ret;
3261 * Ignore an industry property
3262 * @param prop The property to ignore.
3263 * @param buf The property value.
3264 * @return ChangeInfoResult.
3266 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3268 ChangeInfoResult ret = CIR_SUCCESS;
3270 switch (prop) {
3271 case 0x09:
3272 case 0x0B:
3273 case 0x0F:
3274 case 0x12:
3275 case 0x13:
3276 case 0x14:
3277 case 0x17:
3278 case 0x18:
3279 case 0x19:
3280 case 0x21:
3281 case 0x22:
3282 buf->ReadByte();
3283 break;
3285 case 0x0C:
3286 case 0x0D:
3287 case 0x0E:
3288 case 0x10:
3289 case 0x1B:
3290 case 0x1F:
3291 case 0x24:
3292 buf->ReadWord();
3293 break;
3295 case 0x11:
3296 case 0x1A:
3297 case 0x1C:
3298 case 0x1D:
3299 case 0x1E:
3300 case 0x20:
3301 case 0x23:
3302 buf->ReadDWord();
3303 break;
3305 case 0x0A: {
3306 byte num_table = buf->ReadByte();
3307 for (byte j = 0; j < num_table; j++) {
3308 for (uint k = 0;; k++) {
3309 byte x = buf->ReadByte();
3310 if (x == 0xFE && k == 0) {
3311 buf->ReadByte();
3312 buf->ReadByte();
3313 break;
3316 byte y = buf->ReadByte();
3317 if (x == 0 && y == 0x80) break;
3319 byte gfx = buf->ReadByte();
3320 if (gfx == 0xFE) buf->ReadWord();
3323 break;
3326 case 0x16:
3327 for (byte j = 0; j < 3; j++) buf->ReadByte();
3328 break;
3330 case 0x15: {
3331 byte number_of_sounds = buf->ReadByte();
3332 for (uint8 j = 0; j < number_of_sounds; j++) {
3333 buf->ReadByte();
3335 break;
3338 default:
3339 ret = CIR_UNKNOWN;
3340 break;
3342 return ret;
3346 * Validate the industry layout; e.g. to prevent duplicate tiles.
3347 * @param layout The layout to check.
3348 * @param size The size of the layout.
3349 * @return True if the layout is deemed valid.
3351 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3353 for (int i = 0; i < size - 1; i++) {
3354 for (int j = i + 1; j < size; j++) {
3355 if (layout[i].ti.x == layout[j].ti.x &&
3356 layout[i].ti.y == layout[j].ti.y) {
3357 return false;
3361 return true;
3364 /** Clean the tile table of the IndustrySpec if it's needed. */
3365 static void CleanIndustryTileTable(IndustrySpec *ind)
3367 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3368 for (int j = 0; j < ind->num_table; j++) {
3369 /* remove the individual layouts */
3370 free(ind->table[j]);
3372 /* remove the layouts pointers */
3373 free(ind->table);
3374 ind->table = NULL;
3379 * Define properties for industries
3380 * @param indid Local ID of the industry.
3381 * @param numinfo Number of subsequent industry IDs to change the property for.
3382 * @param prop The property to change.
3383 * @param buf The property value.
3384 * @return ChangeInfoResult.
3386 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3388 ChangeInfoResult ret = CIR_SUCCESS;
3390 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3391 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3392 return CIR_INVALID_ID;
3395 /* Allocate industry specs if they haven't been allocated already. */
3396 if (_cur.grffile->industryspec == NULL) {
3397 _cur.grffile->industryspec = xcalloct<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3400 for (int i = 0; i < numinfo; i++) {
3401 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3403 if (prop != 0x08 && indsp == NULL) {
3404 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3405 if (cir > ret) ret = cir;
3406 continue;
3409 switch (prop) {
3410 case 0x08: { // Substitute industry type
3411 byte subs_id = buf->ReadByte();
3413 if (subs_id == 0xFF) {
3414 /* Instead of defining a new industry, a substitute industry id
3415 * of 0xFF disables the old industry with the current id. */
3416 _industry_specs[indid + i].enabled = false;
3417 continue;
3418 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3419 /* The substitute id must be one of the original industry. */
3420 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3421 continue;
3424 /* Allocate space for this industry.
3425 * Only need to do it once. If ever it is called again, it should not
3426 * do anything */
3427 if (indsp == NULL) {
3428 indsp = xmemdupt (&_origin_industry_specs[subs_id]);
3429 _cur.grffile->industryspec[indid + i] = indsp;
3431 indsp->enabled = true;
3432 indsp->grf_prop.local_id = indid + i;
3433 indsp->grf_prop.subst_id = subs_id;
3434 indsp->grf_prop.grffile = _cur.grffile;
3435 /* If the grf industry needs to check its surounding upon creation, it should
3436 * rely on callbacks, not on the original placement functions */
3437 indsp->check_proc = CHECK_NOTHING;
3439 break;
3442 case 0x09: { // Industry type override
3443 byte ovrid = buf->ReadByte();
3445 /* The industry being overridden must be an original industry. */
3446 if (ovrid >= NEW_INDUSTRYOFFSET) {
3447 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3448 continue;
3450 indsp->grf_prop.override = ovrid;
3451 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3452 break;
3455 case 0x0A: { // Set industry layout(s)
3456 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3457 /* We read the total size in bytes, but we can't rely on the
3458 * newgrf to provide a sane value. First assume the value is
3459 * sane but later on we make sure we enlarge the array if the
3460 * newgrf contains more data. Each tile uses either 3 or 5
3461 * bytes, so to play it safe we assume 3. */
3462 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3463 IndustryTileTable **tile_table = xcalloct<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3464 IndustryTileTable *itt = xcalloct<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3465 uint size;
3466 const IndustryTileTable *copy_from;
3468 try {
3469 for (byte j = 0; j < new_num_layouts; j++) {
3470 for (uint k = 0;; k++) {
3471 if (k >= def_num_tiles) {
3472 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3473 /* Size reported by newgrf was not big enough so enlarge the array. */
3474 def_num_tiles *= 2;
3475 itt = xrealloct<IndustryTileTable>(itt, def_num_tiles);
3478 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3480 if (itt[k].ti.x == 0xFE && k == 0) {
3481 /* This means we have to borrow the layout from an old industry */
3482 IndustryType type = buf->ReadByte(); // industry holding required layout
3483 byte laynbr = buf->ReadByte(); // layout number to borrow
3485 copy_from = _origin_industry_specs[type].table[laynbr];
3486 for (size = 1;; size++) {
3487 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3489 break;
3492 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3494 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3495 /* Not the same terminator. The one we are using is rather
3496 x = -80, y = x . So, adjust it. */
3497 itt[k].ti.x = -0x80;
3498 itt[k].ti.y = 0;
3499 itt[k].gfx = 0;
3501 size = k + 1;
3502 copy_from = itt;
3503 break;
3506 itt[k].gfx = buf->ReadByte();
3508 if (itt[k].gfx == 0xFE) {
3509 /* Use a new tile from this GRF */
3510 int local_tile_id = buf->ReadWord();
3512 /* Read the ID from the _industile_mngr. */
3513 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3515 if (tempid == INVALID_INDUSTRYTILE) {
3516 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3517 } else {
3518 /* Declared as been valid, can be used */
3519 itt[k].gfx = tempid;
3520 size = k + 1;
3521 copy_from = itt;
3523 } else if (itt[k].gfx == 0xFF) {
3524 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3525 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3527 /* When there were only 256x256 maps, TileIndex was a uint16 and
3528 * itt[k].ti was just a TileIndexDiff that was added to it.
3529 * As such negative "x" values were shifted into the "y" position.
3530 * x = -1, y = 1 -> x = 255, y = 0
3531 * Since GRF version 8 the position is interpreted as pair of independent int8.
3532 * For GRF version < 8 we need to emulate the old shifting behaviour.
3534 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3538 if (!ValidateIndustryLayout(copy_from, size)) {
3539 /* The industry layout was not valid, so skip this one. */
3540 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3541 new_num_layouts--;
3542 j--;
3543 } else {
3544 tile_table[j] = xmemdupt (copy_from, size);
3547 } catch (...) {
3548 for (int i = 0; i < new_num_layouts; i++) {
3549 free(tile_table[i]);
3551 free(tile_table);
3552 free(itt);
3553 throw;
3556 /* Clean the tile table if it was already set by a previous prop A. */
3557 CleanIndustryTileTable(indsp);
3558 /* Install final layout construction in the industry spec */
3559 indsp->num_table = new_num_layouts;
3560 indsp->table = tile_table;
3561 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3562 free(itt);
3563 break;
3566 case 0x0B: // Industry production flags
3567 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3568 break;
3570 case 0x0C: // Industry closure message
3571 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3572 break;
3574 case 0x0D: // Production increase message
3575 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3576 break;
3578 case 0x0E: // Production decrease message
3579 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3580 break;
3582 case 0x0F: // Fund cost multiplier
3583 indsp->cost_multiplier = buf->ReadByte();
3584 break;
3586 case 0x10: // Production cargo types
3587 for (byte j = 0; j < 2; j++) {
3588 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3590 break;
3592 case 0x11: // Acceptance cargo types
3593 for (byte j = 0; j < 3; j++) {
3594 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3596 buf->ReadByte(); // Unnused, eat it up
3597 break;
3599 case 0x12: // Production multipliers
3600 case 0x13:
3601 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3602 break;
3604 case 0x14: // Minimal amount of cargo distributed
3605 indsp->minimal_cargo = buf->ReadByte();
3606 break;
3608 case 0x15: { // Random sound effects
3609 indsp->number_of_sounds = buf->ReadByte();
3610 uint8 *sounds = buf->Dup (indsp->number_of_sounds);
3612 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3613 free(indsp->random_sounds);
3615 indsp->random_sounds = sounds;
3616 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3617 break;
3620 case 0x16: // Conflicting industry types
3621 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3622 break;
3624 case 0x17: // Probability in random game
3625 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3626 break;
3628 case 0x18: // Probability during gameplay
3629 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3630 break;
3632 case 0x19: // Map colour
3633 indsp->map_colour = buf->ReadByte();
3634 break;
3636 case 0x1A: // Special industry flags to define special behavior
3637 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3638 break;
3640 case 0x1B: // New industry text ID
3641 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3642 break;
3644 case 0x1C: // Input cargo multipliers for the three input cargo types
3645 case 0x1D:
3646 case 0x1E: {
3647 uint32 multiples = buf->ReadDWord();
3648 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3649 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3650 break;
3653 case 0x1F: // Industry name
3654 AddStringForMapping(buf->ReadWord(), &indsp->name);
3655 break;
3657 case 0x20: // Prospecting success chance
3658 indsp->prospecting_chance = buf->ReadDWord();
3659 break;
3661 case 0x21: // Callback mask
3662 case 0x22: { // Callback additional mask
3663 byte aflag = buf->ReadByte();
3664 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3665 break;
3668 case 0x23: // removal cost multiplier
3669 indsp->removal_cost_multiplier = buf->ReadDWord();
3670 break;
3672 case 0x24: { // name for nearby station
3673 uint16 str = buf->ReadWord();
3674 if (str == 0) {
3675 indsp->station_name = STR_NULL;
3676 } else {
3677 AddStringForMapping(str, &indsp->station_name);
3679 break;
3682 default:
3683 ret = CIR_UNKNOWN;
3684 break;
3688 return ret;
3692 * Clone an AirportSpec.
3693 * @param src The AirportSpec to clone.
3694 * @return A fresh copy of the AirportSpec
3696 static AirportSpec *CloneAirportSpec (const AirportSpec *src)
3698 AirportSpec *as = xmemdupt (src);
3700 AirportTileTable **table_list = xmalloct<AirportTileTable*> (src->num_table);
3701 for (uint i = 0; i < src->num_table; i++) {
3702 uint num_tiles = 1;
3703 const AirportTileTable *it = src->table[i];
3704 do {
3705 num_tiles++;
3706 } while ((++it)->ti.x != -0x80);
3707 table_list[i] = xmemdupt (src->table[i], num_tiles);
3709 as->table = table_list;
3711 as->depot_table = xmemdupt (src->depot_table, src->nof_depots);
3713 return as;
3717 * Define properties for airports
3718 * @param airport Local ID of the airport.
3719 * @param numinfo Number of subsequent airport IDs to change the property for.
3720 * @param prop The property to change.
3721 * @param buf The property value.
3722 * @return ChangeInfoResult.
3724 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3726 ChangeInfoResult ret = CIR_SUCCESS;
3728 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3729 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3730 return CIR_INVALID_ID;
3733 /* Allocate industry specs if they haven't been allocated already. */
3734 if (_cur.grffile->airportspec == NULL) {
3735 _cur.grffile->airportspec = xcalloct<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3738 for (int i = 0; i < numinfo; i++) {
3739 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3741 if (as == NULL && prop != 0x08 && prop != 0x09) {
3742 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3743 return CIR_INVALID_ID;
3746 switch (prop) {
3747 case 0x08: { // Modify original airport
3748 byte subs_id = buf->ReadByte();
3750 if (subs_id == 0xFF) {
3751 /* Instead of defining a new airport, an airport id
3752 * of 0xFF disables the old airport with the current id. */
3753 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3754 continue;
3755 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3756 /* The substitute id must be one of the original airports. */
3757 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3758 continue;
3761 /* Allocate space for this airport.
3762 * Only need to do it once. If ever it is called again, it should not
3763 * do anything */
3764 if (as == NULL) {
3765 as = CloneAirportSpec (AirportSpec::GetWithoutOverride(subs_id));
3766 _cur.grffile->airportspec[airport + i] = as;
3768 as->enabled = true;
3769 as->grf_prop.local_id = airport + i;
3770 as->grf_prop.subst_id = subs_id;
3771 as->grf_prop.grffile = _cur.grffile;
3772 /* override the default airport */
3773 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3775 break;
3778 case 0x0A: { // Set airport layout
3779 as->num_table = buf->ReadByte(); // Number of layaouts
3780 as->rotation = xmalloct<Direction>(as->num_table);
3781 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3782 AirportTileTable **tile_table = xcalloct<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3783 AirportTileTable *att = xcalloct<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3784 int size;
3785 const AirportTileTable *copy_from;
3786 try {
3787 for (byte j = 0; j < as->num_table; j++) {
3788 as->rotation[j] = (Direction)buf->ReadByte();
3789 for (int k = 0;; k++) {
3790 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3791 att[k].ti.y = buf->ReadByte();
3793 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3794 /* Not the same terminator. The one we are using is rather
3795 * x = -80, y = 0 . So, adjust it. */
3796 att[k].ti.x = -0x80;
3797 att[k].ti.y = 0;
3798 att[k].gfx = 0;
3800 size = k + 1;
3801 copy_from = att;
3802 break;
3805 att[k].gfx = buf->ReadByte();
3807 if (att[k].gfx == 0xFE) {
3808 /* Use a new tile from this GRF */
3809 int local_tile_id = buf->ReadWord();
3811 /* Read the ID from the _airporttile_mngr. */
3812 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3814 if (tempid == INVALID_AIRPORTTILE) {
3815 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3816 } else {
3817 /* Declared as been valid, can be used */
3818 att[k].gfx = tempid;
3819 size = k + 1;
3820 copy_from = att;
3822 } else if (att[k].gfx == 0xFF) {
3823 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3824 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3827 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3828 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3829 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3830 } else {
3831 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3832 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3835 tile_table[j] = xmemdupt (copy_from, size);
3837 /* Install final layout construction in the airport spec */
3838 as->table = tile_table;
3839 free(att);
3840 } catch (...) {
3841 for (int i = 0; i < as->num_table; i++) {
3842 free(tile_table[i]);
3844 free(tile_table);
3845 free(att);
3846 throw;
3848 break;
3851 case 0x0C:
3852 as->min_year = buf->ReadWord();
3853 as->max_year = buf->ReadWord();
3854 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3855 break;
3857 case 0x0D:
3858 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3859 break;
3861 case 0x0E:
3862 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3863 break;
3865 case 0x0F:
3866 as->noise_level = buf->ReadByte();
3867 break;
3869 case 0x10:
3870 AddStringForMapping(buf->ReadWord(), &as->name);
3871 break;
3873 case 0x11: // Maintenance cost factor
3874 as->maintenance_cost = buf->ReadWord();
3875 break;
3877 default:
3878 ret = CIR_UNKNOWN;
3879 break;
3883 return ret;
3887 * Ignore properties for objects
3888 * @param prop The property to ignore.
3889 * @param buf The property value.
3890 * @return ChangeInfoResult.
3892 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3894 ChangeInfoResult ret = CIR_SUCCESS;
3896 switch (prop) {
3897 case 0x0B:
3898 case 0x0C:
3899 case 0x0D:
3900 case 0x12:
3901 case 0x14:
3902 case 0x16:
3903 case 0x17:
3904 buf->ReadByte();
3905 break;
3907 case 0x09:
3908 case 0x0A:
3909 case 0x10:
3910 case 0x11:
3911 case 0x13:
3912 case 0x15:
3913 buf->ReadWord();
3914 break;
3916 case 0x08:
3917 case 0x0E:
3918 case 0x0F:
3919 buf->ReadDWord();
3920 break;
3922 default:
3923 ret = CIR_UNKNOWN;
3924 break;
3927 return ret;
3931 * Define properties for objects
3932 * @param id Local ID of the object.
3933 * @param numinfo Number of subsequent objectIDs to change the property for.
3934 * @param prop The property to change.
3935 * @param buf The property value.
3936 * @return ChangeInfoResult.
3938 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3940 ChangeInfoResult ret = CIR_SUCCESS;
3942 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3943 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3944 return CIR_INVALID_ID;
3947 /* Allocate object specs if they haven't been allocated already. */
3948 if (_cur.grffile->objectspec == NULL) {
3949 _cur.grffile->objectspec = xcalloct<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3952 for (int i = 0; i < numinfo; i++) {
3953 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3955 if (prop != 0x08 && spec == NULL) {
3956 /* If the object property 08 is not yet set, ignore this property */
3957 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3958 if (cir > ret) ret = cir;
3959 continue;
3962 switch (prop) {
3963 case 0x08: { // Class ID
3964 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3966 /* Allocate space for this object. */
3967 if (*ospec == NULL) {
3968 *ospec = xcalloct<ObjectSpec>();
3969 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3972 /* Swap classid because we read it in BE. */
3973 uint32 classid = buf->ReadLabel();
3974 (*ospec)->cls_id = ObjectClass::Allocate (classid);
3975 (*ospec)->enabled = true;
3976 break;
3979 case 0x09: { // Class name
3980 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3981 AddStringForMapping(buf->ReadWord(), &objclass->name);
3982 break;
3985 case 0x0A: // Object name
3986 AddStringForMapping(buf->ReadWord(), &spec->name);
3987 break;
3989 case 0x0B: // Climate mask
3990 spec->climate = buf->ReadByte();
3991 break;
3993 case 0x0C: // Size
3994 spec->size = buf->ReadByte();
3995 break;
3997 case 0x0D: // Build cost multipler
3998 spec->build_cost_multiplier = buf->ReadByte();
3999 spec->clear_cost_multiplier = spec->build_cost_multiplier;
4000 break;
4002 case 0x0E: // Introduction date
4003 spec->introduction_date = buf->ReadDWord();
4004 break;
4006 case 0x0F: // End of life
4007 spec->end_of_life_date = buf->ReadDWord();
4008 break;
4010 case 0x10: // Flags
4011 spec->flags = (ObjectFlags)buf->ReadWord();
4012 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
4013 break;
4015 case 0x11: // Animation info
4016 spec->animation.frames = buf->ReadByte();
4017 spec->animation.status = buf->ReadByte();
4018 break;
4020 case 0x12: // Animation speed
4021 spec->animation.speed = buf->ReadByte();
4022 break;
4024 case 0x13: // Animation triggers
4025 spec->animation.triggers = buf->ReadWord();
4026 break;
4028 case 0x14: // Removal cost multiplier
4029 spec->clear_cost_multiplier = buf->ReadByte();
4030 break;
4032 case 0x15: // Callback mask
4033 spec->callback_mask = buf->ReadWord();
4034 break;
4036 case 0x16: // Building height
4037 spec->height = buf->ReadByte();
4038 break;
4040 case 0x17: // Views
4041 spec->views = buf->ReadByte();
4042 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4043 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4044 spec->views = 1;
4046 break;
4048 case 0x18: // Amount placed on 256^2 map on map creation
4049 spec->generate_amount = buf->ReadByte();
4050 break;
4052 default:
4053 ret = CIR_UNKNOWN;
4054 break;
4058 return ret;
4062 * Define properties for railtypes
4063 * @param id ID of the railtype.
4064 * @param numinfo Number of subsequent IDs to change the property for.
4065 * @param prop The property to change.
4066 * @param buf The property value.
4067 * @return ChangeInfoResult.
4069 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4071 ChangeInfoResult ret = CIR_SUCCESS;
4073 extern RailtypeInfo _railtypes[RAILTYPE_END];
4075 if (id + numinfo > RAILTYPE_END) {
4076 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4077 return CIR_INVALID_ID;
4080 for (int i = 0; i < numinfo; i++) {
4081 RailType rt = _cur.grffile->railtype_map[id + i];
4082 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4084 RailtypeInfo *rti = &_railtypes[rt];
4086 switch (prop) {
4087 case 0x08: // Label of rail type
4088 /* Skipped here as this is loaded during reservation stage. */
4089 buf->ReadDWord();
4090 break;
4092 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4093 uint16 str = buf->ReadWord();
4094 AddStringForMapping(str, &rti->strings.toolbar_caption);
4095 if (_cur.grffile->grf_version < 8) {
4096 AddStringForMapping(str, &rti->strings.name);
4098 break;
4101 case 0x0A: // Menu text of railtype
4102 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4103 break;
4105 case 0x0B: // Build window caption
4106 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4107 break;
4109 case 0x0C: // Autoreplace text
4110 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4111 break;
4113 case 0x0D: // New locomotive text
4114 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4115 break;
4117 case 0x0E: // Compatible railtype list
4118 case 0x0F: // Powered railtype list
4119 case 0x18: // Railtype list required for date introduction
4120 case 0x19: // Introduced railtype list
4122 /* Rail type compatibility bits are added to the existing bits
4123 * to allow multiple GRFs to modify compatibility with the
4124 * default rail types. */
4125 int n = buf->ReadByte();
4126 for (int j = 0; j != n; j++) {
4127 RailTypeLabel label = buf->ReadLabel();
4128 RailType rt = GetRailTypeByLabel (label, false);
4129 if (rt != INVALID_RAILTYPE) {
4130 switch (prop) {
4131 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4132 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4133 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4134 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4138 break;
4141 case 0x10: // Rail Type flags
4142 rti->flags = (RailTypeFlags)buf->ReadByte();
4143 break;
4145 case 0x11: // Curve speed advantage
4146 rti->curve_speed = buf->ReadByte();
4147 break;
4149 case 0x12: // Station graphic
4150 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4151 break;
4153 case 0x13: // Construction cost factor
4154 rti->cost_multiplier = buf->ReadWord();
4155 break;
4157 case 0x14: // Speed limit
4158 rti->max_speed = buf->ReadWord();
4159 break;
4161 case 0x15: // Acceleration model
4162 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4163 break;
4165 case 0x16: // Map colour
4166 rti->map_colour = buf->ReadByte();
4167 break;
4169 case 0x17: // Introduction date
4170 rti->introduction_date = buf->ReadDWord();
4171 break;
4173 case 0x1A: // Sort order
4174 rti->sorting_order = buf->ReadByte();
4175 break;
4177 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4178 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4179 break;
4181 case 0x1C: // Maintenance cost factor
4182 rti->maintenance_multiplier = buf->ReadWord();
4183 break;
4185 case 0x1D: // Alternate rail type label list
4186 /* Skipped here as this is loaded during reservation stage. */
4187 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4188 break;
4190 default:
4191 ret = CIR_UNKNOWN;
4192 break;
4196 return ret;
4199 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4201 ChangeInfoResult ret = CIR_SUCCESS;
4203 extern RailtypeInfo _railtypes[RAILTYPE_END];
4205 if (id + numinfo > RAILTYPE_END) {
4206 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4207 return CIR_INVALID_ID;
4210 for (int i = 0; i < numinfo; i++) {
4211 switch (prop) {
4212 case 0x08: // Label of rail type
4214 RailTypeLabel rtl = buf->ReadLabel();
4216 RailType rt = GetRailTypeByLabel(rtl, false);
4217 if (rt == INVALID_RAILTYPE) {
4218 /* Set up new rail type */
4219 rt = AllocateRailType(rtl);
4222 _cur.grffile->railtype_map[id + i] = rt;
4223 break;
4226 case 0x09: // Toolbar caption of railtype
4227 case 0x0A: // Menu text
4228 case 0x0B: // Build window caption
4229 case 0x0C: // Autoreplace text
4230 case 0x0D: // New loco
4231 case 0x13: // Construction cost
4232 case 0x14: // Speed limit
4233 case 0x1B: // Name of railtype
4234 case 0x1C: // Maintenance cost factor
4235 buf->ReadWord();
4236 break;
4238 case 0x1D: // Alternate rail type label list
4239 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4240 int n = buf->ReadByte();
4241 for (int j = 0; j != n; j++) {
4242 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = buf->ReadLabel();
4244 break;
4246 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4247 /* FALL THROUGH */
4249 case 0x0E: // Compatible railtype list
4250 case 0x0F: // Powered railtype list
4251 case 0x18: // Railtype list required for date introduction
4252 case 0x19: // Introduced railtype list
4253 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4254 break;
4256 case 0x10: // Rail Type flags
4257 case 0x11: // Curve speed advantage
4258 case 0x12: // Station graphic
4259 case 0x15: // Acceleration model
4260 case 0x16: // Map colour
4261 case 0x1A: // Sort order
4262 buf->ReadByte();
4263 break;
4265 case 0x17: // Introduction date
4266 buf->ReadDWord();
4267 break;
4269 default:
4270 ret = CIR_UNKNOWN;
4271 break;
4275 return ret;
4278 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4280 ChangeInfoResult ret = CIR_SUCCESS;
4282 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4283 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4284 return CIR_INVALID_ID;
4287 /* Allocate airport tile specs if they haven't been allocated already. */
4288 if (_cur.grffile->airtspec == NULL) {
4289 _cur.grffile->airtspec = xcalloct<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4292 for (int i = 0; i < numinfo; i++) {
4293 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4295 if (prop != 0x08 && tsp == NULL) {
4296 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4297 return CIR_INVALID_ID;
4300 switch (prop) {
4301 case 0x08: { // Substitute airport tile type
4302 byte subs_id = buf->ReadByte();
4304 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4305 /* The substitute id must be one of the original airport tiles. */
4306 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4307 continue;
4310 /* Allocate space for this airport tile. */
4311 if (tsp == NULL) {
4312 tsp = xmemdupt (AirportTileSpec::Get(subs_id));
4313 _cur.grffile->airtspec[airtid + i] = tsp;
4315 tsp->enabled = true;
4317 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4319 tsp->grf_prop.local_id = airtid + i;
4320 tsp->grf_prop.subst_id = subs_id;
4321 tsp->grf_prop.grffile = _cur.grffile;
4322 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4324 break;
4327 case 0x09: { // Airport tile override
4328 byte override = buf->ReadByte();
4330 /* The airport tile being overridden must be an original airport tile. */
4331 if (override >= NEW_AIRPORTTILE_OFFSET) {
4332 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4333 continue;
4336 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4337 break;
4340 case 0x0E: // Callback mask
4341 tsp->callback_mask = buf->ReadByte();
4342 break;
4344 case 0x0F: // Animation information
4345 tsp->animation.frames = buf->ReadByte();
4346 tsp->animation.status = buf->ReadByte();
4347 break;
4349 case 0x10: // Animation speed
4350 tsp->animation.speed = buf->ReadByte();
4351 break;
4353 case 0x11: // Animation triggers
4354 tsp->animation.triggers = buf->ReadByte();
4355 break;
4357 default:
4358 ret = CIR_UNKNOWN;
4359 break;
4363 return ret;
4366 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4368 switch (cir) {
4369 default: NOT_REACHED();
4371 case CIR_DISABLED:
4372 /* Error has already been printed; just stop parsing */
4373 return true;
4375 case CIR_SUCCESS:
4376 return false;
4378 case CIR_UNHANDLED:
4379 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4380 return false;
4382 case CIR_UNKNOWN:
4383 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4384 /* FALL THROUGH */
4386 case CIR_INVALID_ID: {
4387 /* No debug message for an invalid ID, as it has already been output */
4388 GRFError *error = DisableCur (cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4389 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4390 return true;
4395 /* Action 0x00 */
4396 static int FeatureChangeInfo (ByteReader *buf)
4398 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4400 * B feature
4401 * B num-props how many properties to change per vehicle/station
4402 * B num-info how many vehicles/stations to change
4403 * E id ID of first vehicle/station to change, if num-info is
4404 * greater than one, this one and the following
4405 * vehicles/stations will be changed
4406 * B property what property to change, depends on the feature
4407 * V new-info new bytes of info (variable size; depends on properties) */
4409 static const VCI_Handler handler[] = {
4410 /* GSF_TRAINS */ RailVehicleChangeInfo,
4411 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4412 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4413 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4414 /* GSF_STATIONS */ StationChangeInfo,
4415 /* GSF_CANALS */ CanalChangeInfo,
4416 /* GSF_BRIDGES */ BridgeChangeInfo,
4417 /* GSF_HOUSES */ TownHouseChangeInfo,
4418 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4419 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4420 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4421 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4422 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4423 /* GSF_AIRPORTS */ AirportChangeInfo,
4424 /* GSF_SIGNALS */ NULL,
4425 /* GSF_OBJECTS */ ObjectChangeInfo,
4426 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4427 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4430 uint8 feature = buf->ReadByte();
4431 uint8 numprops = buf->ReadByte();
4432 uint numinfo = buf->ReadByte();
4433 uint engine = buf->ReadExtendedByte();
4435 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4436 feature, numprops, engine, numinfo);
4438 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4439 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4440 return 0;
4443 /* Mark the feature as used by the grf */
4444 SetBit(_cur.grffile->grf_features, feature);
4446 while (numprops-- && buf->HasData()) {
4447 uint8 prop = buf->ReadByte();
4449 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4450 if (HandleChangeInfoResult ("FeatureChangeInfo", cir, feature, prop)) {
4451 return -1;
4455 return 0;
4458 /* Action 0x00 (GLS_SAFETYSCAN) */
4459 static int SafeChangeInfo (ByteReader *buf)
4461 uint8 feature = buf->ReadByte();
4462 uint8 numprops = buf->ReadByte();
4463 uint numinfo = buf->ReadByte();
4464 buf->ReadExtendedByte(); // id
4466 if (feature == GSF_BRIDGES && numprops == 1) {
4467 uint8 prop = buf->ReadByte();
4468 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4469 * is considered safe. */
4470 if (prop == 0x0D) return 0;
4471 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4472 uint8 prop = buf->ReadByte();
4473 /* Engine ID Mappings are safe, if the source is static */
4474 if (prop == 0x11) {
4475 bool is_safe = true;
4476 for (uint i = 0; i < numinfo; i++) {
4477 uint32 s = buf->ReadDWord();
4478 buf->ReadDWord(); // dest
4479 const GRFConfig *grfconfig = GetGRFConfig(s);
4480 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4481 is_safe = false;
4482 break;
4485 if (is_safe) return 0;
4489 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4491 /* Skip remainder of GRF */
4492 return -1;
4495 /* Action 0x00 (GLS_RESERVE) */
4496 static int ReserveChangeInfo (ByteReader *buf)
4498 uint8 feature = buf->ReadByte();
4500 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return 0;
4502 uint8 numprops = buf->ReadByte();
4503 uint8 numinfo = buf->ReadByte();
4504 uint8 index = buf->ReadExtendedByte();
4506 while (numprops-- && buf->HasData()) {
4507 uint8 prop = buf->ReadByte();
4508 ChangeInfoResult cir = CIR_SUCCESS;
4510 switch (feature) {
4511 default: NOT_REACHED();
4512 case GSF_CARGOES:
4513 cir = CargoChangeInfo(index, numinfo, prop, buf);
4514 break;
4516 case GSF_GLOBALVAR:
4517 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4518 break;
4520 case GSF_RAILTYPES:
4521 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4522 break;
4525 if (HandleChangeInfoResult ("ReserveChangeInfo", cir, feature, prop)) {
4526 return -1;
4530 return 0;
4533 /* Action 0x01 */
4534 static int NewSpriteSet (ByteReader *buf)
4536 /* Basic format: <01> <feature> <num-sets> <num-ent>
4537 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4539 * B feature feature to define sprites for
4540 * 0, 1, 2, 3: veh-type, 4: train stations
4541 * E first-set first sprite set to define
4542 * B num-sets number of sprite sets (extended byte in extended format)
4543 * E num-ent how many entries per sprite set
4544 * For vehicles, this is the number of different
4545 * vehicle directions in each sprite set
4546 * Set num-dirs=8, unless your sprites are symmetric.
4547 * In that case, use num-dirs=4.
4550 uint8 feature = buf->ReadByte();
4551 uint16 num_sets = buf->ReadByte();
4552 uint16 first_set = 0;
4554 if (num_sets == 0 && buf->HasData(3)) {
4555 /* Extended Action1 format.
4556 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4557 first_set = buf->ReadExtendedByte();
4558 num_sets = buf->ReadExtendedByte();
4560 uint16 num_ents = buf->ReadExtendedByte();
4562 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4564 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4565 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4568 for (int i = 0; i < num_sets * num_ents; i++) {
4569 _cur.nfo_line++;
4570 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4573 return 0;
4576 /* Action 0x01 (SKIP) */
4577 static int SkipAct1 (ByteReader *buf)
4579 buf->ReadByte();
4580 uint16 num_sets = buf->ReadByte();
4582 if (num_sets == 0 && buf->HasData(3)) {
4583 /* Extended Action1 format.
4584 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4585 buf->ReadExtendedByte(); // first_set
4586 num_sets = buf->ReadExtendedByte();
4588 uint16 num_ents = buf->ReadExtendedByte();
4590 int skip = num_sets * num_ents;
4591 grfmsg (3, "SkipAct1: Skipping %d sprites", skip);
4592 return skip;
4595 /* Helper function to either create a callback or link to a previously
4596 * defined spritegroup. */
4597 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4599 if (HasBit(groupid, 15)) {
4600 return CallbackResultSpriteGroup::create (groupid, _cur.grffile->grf_version >= 8);
4603 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4604 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4605 return NULL;
4608 return _cur.spritegroups[groupid];
4612 * Helper function to either create a callback or a result sprite group.
4613 * @param feature GrfSpecFeature to define spritegroup for.
4614 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4615 * @param type Type of the currently being parsed Action2. (only for debug output)
4616 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4617 * @return Created spritegroup.
4619 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4621 if (HasBit(spriteid, 15)) {
4622 return CallbackResultSpriteGroup::create (spriteid, _cur.grffile->grf_version >= 8);
4625 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4626 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4627 return NULL;
4630 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4631 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4633 /* Ensure that the sprites are loeded */
4634 assert(spriteset_start + num_sprites <= _cur.spriteid);
4636 return ResultSpriteGroup::create (spriteset_start, num_sprites);
4639 /* Action 0x02 */
4640 static int NewSpriteGroup (ByteReader *buf)
4642 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4644 * B feature see action 1
4645 * B set-id ID of this particular definition
4646 * B type/num-entries
4647 * if 80 or greater, this is a randomized or variational
4648 * list definition, see below
4649 * otherwise it specifies a number of entries, the exact
4650 * meaning depends on the feature
4651 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4652 SpriteGroup *act_group = NULL;
4654 uint8 feature = buf->ReadByte();
4655 uint8 setid = buf->ReadByte();
4656 uint8 type = buf->ReadByte();
4658 /* Sprite Groups are created here but they are allocated from a pool, so
4659 * we do not need to delete anything if there is an exception from the
4660 * ByteReader. */
4662 switch (type) {
4663 /* Deterministic Sprite Group */
4664 case 0x81: // Self scope, byte
4665 case 0x82: // Parent scope, byte
4666 case 0x85: // Self scope, word
4667 case 0x86: // Parent scope, word
4668 case 0x89: // Self scope, dword
4669 case 0x8A: // Parent scope, dword
4671 byte varsize = (1 << GB(type, 2, 2));
4673 byte varadjust;
4675 static SmallVector <DeterministicSpriteGroup::Adjust, 16> adjusts;
4676 adjusts.Clear();
4678 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4679 * from the outset, so we shall have to keep reallocing. */
4680 do {
4681 DeterministicSpriteGroup::Adjust *adjust = adjusts.Append();
4683 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4684 adjust->operation = adjusts.Length() == 1 ? 0 : buf->ReadByte();
4685 adjust->variable = buf->ReadByte();
4686 if (adjust->variable == 0x7E) {
4687 /* Link subroutine group */
4688 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4689 } else {
4690 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4693 varadjust = buf->ReadByte();
4694 adjust->shift_num = GB(varadjust, 0, 5);
4695 adjust->type = GB(varadjust, 6, 2);
4696 adjust->and_mask = buf->ReadVarSize(varsize);
4698 if (adjust->type != 0) {
4699 adjust->add_val = buf->ReadVarSize(varsize);
4700 adjust->divmod_val = buf->ReadVarSize(varsize);
4701 } else {
4702 adjust->add_val = 0;
4703 adjust->divmod_val = 0;
4706 /* Continue reading var adjusts while bit 5 is set. */
4707 } while (HasBit(varadjust, 5));
4709 byte num_ranges = buf->ReadByte();
4711 DeterministicSpriteGroup *group = DeterministicSpriteGroup::create (HasBit(type, 1),
4712 GB(type, 2, 2), adjusts.Length(),
4713 num_ranges, adjusts.Begin());
4714 act_group = group;
4716 for (uint i = 0; i < num_ranges; i++) {
4717 const SpriteGroup *g = GetGroupFromGroupID (setid, type, buf->ReadWord());
4718 uint32 low = buf->ReadVarSize (varsize);
4719 uint32 high = buf->ReadVarSize (varsize);
4720 group->set_range (i, g, low, high);
4723 group->set_default (GetGroupFromGroupID (setid, type, buf->ReadWord()));
4724 break;
4727 /* Randomized Sprite Group */
4728 case 0x80: // Self scope
4729 case 0x83: // Parent scope
4730 case 0x84: // Relative scope
4732 VarSpriteGroupScope scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4733 byte count;
4734 if (HasBit(type, 2)) {
4735 if (feature <= GSF_AIRCRAFT) scope = VSG_SCOPE_RELATIVE;
4736 count = buf->ReadByte();
4737 } else {
4738 count = 0;
4741 uint8 triggers = buf->ReadByte();
4742 uint8 bit = buf->ReadByte();
4743 uint8 num = buf->ReadByte();
4745 RandomizedSpriteGroup *group = RandomizedSpriteGroup::create (scope,
4746 HasBit(triggers, 7), GB(triggers, 0, 7),
4747 count, bit, num);
4748 act_group = group;
4750 for (uint i = 0; i < num; i++) {
4751 group->set_group (i, GetGroupFromGroupID (setid, type, buf->ReadWord()));
4754 break;
4757 /* Neither a variable or randomized sprite group... must be a real group */
4758 default:
4760 switch (feature) {
4761 case GSF_TRAINS:
4762 case GSF_ROADVEHICLES:
4763 case GSF_SHIPS:
4764 case GSF_AIRCRAFT:
4765 case GSF_STATIONS:
4766 case GSF_CANALS:
4767 case GSF_CARGOES:
4768 case GSF_AIRPORTS:
4769 case GSF_RAILTYPES:
4771 byte num_loaded = type;
4772 byte num_loading = buf->ReadByte();
4774 if (!_cur.HasValidSpriteSets(feature)) {
4775 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4776 return 0;
4779 RealSpriteGroup *group = RealSpriteGroup::create (num_loaded, num_loading);
4780 act_group = group;
4782 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4783 setid, num_loaded, num_loading);
4785 uint total = (uint)num_loaded + (uint)num_loading;
4786 for (uint i = 0; i < total; i++) {
4787 uint16 spriteid = buf->ReadWord();
4788 group->set (i, CreateGroupFromGroupID (feature, setid, type, spriteid));
4789 grfmsg(8, "NewSpriteGroup: + rg->groups[%i] = subset %u", i, spriteid);
4792 break;
4795 case GSF_HOUSES:
4796 case GSF_AIRPORTTILES:
4797 case GSF_OBJECTS:
4798 case GSF_INDUSTRYTILES: {
4799 byte num_building_sprites = max((uint8)1, type);
4801 TileLayoutSpriteGroup *group = TileLayoutSpriteGroup::create();
4802 act_group = group;
4804 /* On error, bail out immediately. Temporary GRF data was already freed */
4805 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) {
4806 return -1;
4808 break;
4811 case GSF_INDUSTRIES: {
4812 if (type > 1) {
4813 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4814 break;
4817 IndustryProductionSpriteGroup *group = IndustryProductionSpriteGroup::create (type);
4818 act_group = group;
4819 if (type == 0) {
4820 for (uint i = 0; i < 3; i++) {
4821 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4823 for (uint i = 0; i < 2; i++) {
4824 group->add_output[i] = buf->ReadWord(); // unsigned
4826 } else {
4827 for (uint i = 0; i < 3; i++) {
4828 group->subtract_input[i] = buf->ReadByte();
4830 for (uint i = 0; i < 2; i++) {
4831 group->add_output[i] = buf->ReadByte();
4834 group->again = buf->ReadByte();
4835 break;
4838 /* Loading of Tile Layout and Production Callback groups would happen here */
4839 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4844 _cur.spritegroups[setid] = act_group;
4846 return 0;
4849 static CargoID TranslateCargo (uint8 ctype)
4851 /* Special cargo type for purchase list */
4852 if (ctype == 0xFF) return CT_PURCHASE;
4854 if (_cur.grffile->cargo_list.Length() == 0) {
4855 /* No cargo table, so use bitnum values */
4856 if (ctype >= 32) {
4857 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4858 return CT_INVALID;
4861 const CargoSpec *cs;
4862 FOR_ALL_CARGOSPECS(cs) {
4863 if (cs->bitnum == ctype) {
4864 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4865 return cs->Index();
4869 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4870 return CT_INVALID;
4873 /* Check if the cargo type is out of bounds of the cargo translation table */
4874 if (ctype >= _cur.grffile->cargo_list.Length()) {
4875 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4876 return CT_INVALID;
4879 /* Look up the cargo label from the translation table */
4880 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4881 if (cl == 0) {
4882 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4883 return CT_INVALID;
4886 ctype = GetCargoIDByLabel(cl);
4887 if (ctype == CT_INVALID) {
4888 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));
4889 return CT_INVALID;
4892 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);
4893 return ctype;
4897 static bool IsValidGroupID(uint16 groupid, const char *function)
4899 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4900 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4901 return false;
4904 return true;
4907 static bool VehicleMapSpriteGroup (ByteReader *buf, byte feature, uint8 idcount)
4909 static EngineID *last_engines;
4910 static uint last_engines_count;
4911 bool wagover = false;
4913 /* Test for 'wagon override' flag */
4914 if (HasBit(idcount, 7)) {
4915 wagover = true;
4916 /* Strip off the flag */
4917 idcount = GB(idcount, 0, 7);
4919 if (last_engines_count == 0) {
4920 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4921 return true;
4924 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4925 last_engines_count, idcount);
4926 } else {
4927 if (last_engines_count != idcount) {
4928 last_engines = xrealloct (last_engines, idcount);
4929 last_engines_count = idcount;
4933 EngineID engines[128];
4934 assert (idcount < lengthof(engines));
4936 for (uint i = 0; i < idcount; i++) {
4937 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4938 if (e == NULL) {
4939 /* No engine could be allocated?!? Deal with it. Okay,
4940 * this might look bad. Also make sure this NewGRF
4941 * gets disabled, as a half loaded one is bad. */
4942 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4943 return false;
4946 engines[i] = e->index;
4947 if (!wagover) last_engines[i] = engines[i];
4950 uint8 cidcount = buf->ReadByte();
4951 for (uint c = 0; c < cidcount; c++) {
4952 uint8 ctype = buf->ReadByte();
4953 uint16 groupid = buf->ReadWord();
4954 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4956 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4958 ctype = TranslateCargo (ctype);
4959 if (ctype == CT_INVALID) continue;
4961 for (uint i = 0; i < idcount; i++) {
4962 EngineID engine = engines[i];
4964 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4966 if (wagover) {
4967 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4968 } else {
4969 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4974 uint16 groupid = buf->ReadWord();
4975 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return true;
4977 grfmsg(8, "-- Default group id 0x%04X", groupid);
4979 for (uint i = 0; i < idcount; i++) {
4980 EngineID engine = engines[i];
4982 if (wagover) {
4983 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4984 } else {
4985 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4986 SetEngineGRF(engine, _cur.grffile);
4990 return true;
4994 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4996 const byte *cfs = buf->GetData (idcount);
4998 uint8 cidcount = buf->ReadByte();
4999 buf->Skip(cidcount * 3);
5001 uint16 groupid = buf->ReadWord();
5002 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5004 for (uint i = 0; i < idcount; i++) {
5005 CanalFeature cf = (CanalFeature)cfs[i];
5007 if (cf >= CF_END) {
5008 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5009 continue;
5012 _water_feature[cf].grffile = _cur.grffile;
5013 _water_feature[cf].group = _cur.spritegroups[groupid];
5018 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5020 const byte *stations = buf->GetData (idcount);
5022 uint8 cidcount = buf->ReadByte();
5023 for (uint c = 0; c < cidcount; c++) {
5024 uint8 ctype = buf->ReadByte();
5025 uint16 groupid = buf->ReadWord();
5026 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5028 if (ctype == 0xFE) {
5029 ctype = CT_DEFAULT_NA;
5030 } else {
5031 ctype = TranslateCargo (ctype);
5032 if (ctype == CT_INVALID) continue;
5035 for (uint i = 0; i < idcount; i++) {
5036 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5038 if (statspec == NULL) {
5039 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5040 continue;
5043 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5047 uint16 groupid = buf->ReadWord();
5048 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5050 for (uint i = 0; i < idcount; i++) {
5051 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5053 if (statspec == NULL) {
5054 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5055 continue;
5058 if (statspec->grf_prop.grffile != NULL) {
5059 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5060 continue;
5063 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5064 statspec->grf_prop.grffile = _cur.grffile;
5065 statspec->grf_prop.local_id = stations[i];
5066 StationClass::Assign(statspec);
5071 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5073 const byte *houses = buf->GetData (idcount);
5075 /* Skip the cargo type section, we only care about the default group */
5076 uint8 cidcount = buf->ReadByte();
5077 buf->Skip(cidcount * 3);
5079 uint16 groupid = buf->ReadWord();
5080 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5082 if (_cur.grffile->housespec == NULL) {
5083 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5084 return;
5087 for (uint i = 0; i < idcount; i++) {
5088 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5090 if (hs == NULL) {
5091 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5092 continue;
5095 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5099 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5101 const byte *industries = buf->GetData (idcount);
5103 /* Skip the cargo type section, we only care about the default group */
5104 uint8 cidcount = buf->ReadByte();
5105 buf->Skip(cidcount * 3);
5107 uint16 groupid = buf->ReadWord();
5108 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5110 if (_cur.grffile->industryspec == NULL) {
5111 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5112 return;
5115 for (uint i = 0; i < idcount; i++) {
5116 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5118 if (indsp == NULL) {
5119 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5120 continue;
5123 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5127 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5129 const byte *indtiles = buf->GetData (idcount);
5131 /* Skip the cargo type section, we only care about the default group */
5132 uint8 cidcount = buf->ReadByte();
5133 buf->Skip(cidcount * 3);
5135 uint16 groupid = buf->ReadWord();
5136 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5138 if (_cur.grffile->indtspec == NULL) {
5139 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5140 return;
5143 for (uint i = 0; i < idcount; i++) {
5144 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5146 if (indtsp == NULL) {
5147 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5148 continue;
5151 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5155 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5157 const byte *cargoes = buf->GetData (idcount);
5159 /* Skip the cargo type section, we only care about the default group */
5160 uint8 cidcount = buf->ReadByte();
5161 buf->Skip(cidcount * 3);
5163 uint16 groupid = buf->ReadWord();
5164 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5166 for (uint i = 0; i < idcount; i++) {
5167 CargoID cid = (CargoID)cargoes[i];
5169 if (cid >= NUM_CARGO) {
5170 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5171 continue;
5174 CargoSpec *cs = CargoSpec::Get(cid);
5175 cs->grffile = _cur.grffile;
5176 cs->group = _cur.spritegroups[groupid];
5180 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5182 if (_cur.grffile->objectspec == NULL) {
5183 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5184 return;
5187 const byte *objects = buf->GetData (idcount);
5189 uint8 cidcount = buf->ReadByte();
5190 for (uint c = 0; c < cidcount; c++) {
5191 uint8 ctype = buf->ReadByte();
5192 uint16 groupid = buf->ReadWord();
5193 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5195 switch (ctype) {
5196 case 0: break;
5197 case 0xFF: ctype = CT_PURCHASE_OBJECT; break;
5198 default:
5199 grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype);
5200 continue;
5203 for (uint i = 0; i < idcount; i++) {
5204 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5206 if (spec == NULL) {
5207 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5208 continue;
5211 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5215 uint16 groupid = buf->ReadWord();
5216 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5218 for (uint i = 0; i < idcount; i++) {
5219 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5221 if (spec == NULL) {
5222 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5223 continue;
5226 if (spec->grf_prop.grffile != NULL) {
5227 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5228 continue;
5231 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5232 spec->grf_prop.grffile = _cur.grffile;
5233 spec->grf_prop.local_id = objects[i];
5237 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5239 const byte *railtypes = buf->GetData (idcount);
5241 uint8 cidcount = buf->ReadByte();
5242 for (uint c = 0; c < cidcount; c++) {
5243 uint8 ctype = buf->ReadByte();
5244 uint16 groupid = buf->ReadWord();
5245 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5247 if (ctype >= RTSG_END) continue;
5249 extern RailtypeInfo _railtypes[RAILTYPE_END];
5250 for (uint i = 0; i < idcount; i++) {
5251 RailType rt = _cur.grffile->railtype_map[railtypes[i]];
5252 if (rt != INVALID_RAILTYPE) {
5253 RailtypeInfo *rti = &_railtypes[rt];
5255 rti->grffile[ctype] = _cur.grffile;
5256 rti->group[ctype] = _cur.spritegroups[groupid];
5261 /* Railtypes do not use the default group. */
5262 buf->ReadWord();
5265 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5267 const byte *airports = buf->GetData (idcount);
5269 /* Skip the cargo type section, we only care about the default group */
5270 uint8 cidcount = buf->ReadByte();
5271 buf->Skip(cidcount * 3);
5273 uint16 groupid = buf->ReadWord();
5274 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5276 if (_cur.grffile->airportspec == NULL) {
5277 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5278 return;
5281 for (uint i = 0; i < idcount; i++) {
5282 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5284 if (as == NULL) {
5285 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5286 continue;
5289 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5293 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5295 const byte *airptiles = buf->GetData (idcount);
5297 /* Skip the cargo type section, we only care about the default group */
5298 uint8 cidcount = buf->ReadByte();
5299 buf->Skip(cidcount * 3);
5301 uint16 groupid = buf->ReadWord();
5302 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5304 if (_cur.grffile->airtspec == NULL) {
5305 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5306 return;
5309 for (uint i = 0; i < idcount; i++) {
5310 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5312 if (airtsp == NULL) {
5313 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5314 continue;
5317 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5322 /* Action 0x03 */
5323 static int FeatureMapSpriteGroup (ByteReader *buf)
5325 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5326 * id-list := [<id>] [id-list]
5327 * cargo-list := <cargo-type> <cid> [cargo-list]
5329 * B feature see action 0
5330 * B n-id bits 0-6: how many IDs this definition applies to
5331 * bit 7: if set, this is a wagon override definition (see below)
5332 * B ids the IDs for which this definition applies
5333 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5334 * can be zero, in that case the def-cid is used always
5335 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5336 * W cid cargo ID (sprite group ID) for this type of cargo
5337 * W def-cid default cargo ID (sprite group ID) */
5339 uint8 feature = buf->ReadByte();
5340 uint8 idcount = buf->ReadByte();
5342 /* If idcount is zero, this is a feature callback */
5343 if (idcount == 0) {
5344 /* Skip number of cargo ids? */
5345 buf->ReadByte();
5346 uint16 groupid = buf->ReadWord();
5347 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return 0;
5349 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5351 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5352 return 0;
5355 /* Mark the feature as used by the grf (generic callbacks do not count) */
5356 SetBit(_cur.grffile->grf_features, feature);
5358 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5360 switch (feature) {
5361 case GSF_TRAINS:
5362 case GSF_ROADVEHICLES:
5363 case GSF_SHIPS:
5364 case GSF_AIRCRAFT:
5365 return VehicleMapSpriteGroup (buf, feature, idcount) ? 0 : -1;
5367 case GSF_CANALS:
5368 CanalMapSpriteGroup(buf, idcount);
5369 return 0;
5371 case GSF_STATIONS:
5372 StationMapSpriteGroup(buf, idcount);
5373 return 0;
5375 case GSF_HOUSES:
5376 TownHouseMapSpriteGroup(buf, idcount);
5377 return 0;
5379 case GSF_INDUSTRIES:
5380 IndustryMapSpriteGroup(buf, idcount);
5381 return 0;
5383 case GSF_INDUSTRYTILES:
5384 IndustrytileMapSpriteGroup(buf, idcount);
5385 return 0;
5387 case GSF_CARGOES:
5388 CargoMapSpriteGroup(buf, idcount);
5389 return 0;
5391 case GSF_AIRPORTS:
5392 AirportMapSpriteGroup(buf, idcount);
5393 return 0;
5395 case GSF_OBJECTS:
5396 ObjectMapSpriteGroup(buf, idcount);
5397 return 0;
5399 case GSF_RAILTYPES:
5400 RailTypeMapSpriteGroup(buf, idcount);
5401 return 0;
5403 case GSF_AIRPORTTILES:
5404 AirportTileMapSpriteGroup(buf, idcount);
5405 return 0;
5407 default:
5408 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5409 return 0;
5413 /* Action 0x04 */
5414 static int FeatureNewName (ByteReader *buf)
5416 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5418 * B veh-type see action 0 (as 00..07, + 0A
5419 * But IF veh-type = 48, then generic text
5420 * B language-id If bit 6 is set, This is the extended language scheme,
5421 * with up to 64 language.
5422 * Otherwise, it is a mapping where set bits have meaning
5423 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5424 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5425 * B num-veh number of vehicles which are getting a new name
5426 * B/W offset number of the first vehicle that gets a new name
5427 * Byte : ID of vehicle to change
5428 * Word : ID of string to change/add
5429 * S data new texts, each of them zero-terminated, after
5430 * which the next name begins. */
5432 bool new_scheme = _cur.grffile->grf_version >= 7;
5434 uint8 feature = buf->ReadByte();
5435 uint8 lang = buf->ReadByte();
5436 uint8 num = buf->ReadByte();
5437 bool generic = HasBit(lang, 7);
5438 uint16 id;
5439 if (generic) {
5440 id = buf->ReadWord();
5441 } else if (feature <= GSF_AIRCRAFT) {
5442 id = buf->ReadExtendedByte();
5443 } else {
5444 id = buf->ReadByte();
5447 ClrBit(lang, 7);
5449 uint16 endid = id + num;
5451 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5452 id, endid, feature, lang);
5454 for (; id < endid && buf->HasData(); id++) {
5455 const char *name = buf->ReadString();
5456 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5458 switch (feature) {
5459 case GSF_TRAINS:
5460 case GSF_ROADVEHICLES:
5461 case GSF_SHIPS:
5462 case GSF_AIRCRAFT:
5463 if (!generic) {
5464 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5465 if (e == NULL) break;
5466 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5467 e->info.string_id = string;
5468 } else {
5469 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5471 break;
5473 default:
5474 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5475 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5476 break;
5479 switch (GB(id, 8, 8)) {
5480 case 0xC4: // Station class name
5481 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5482 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5483 } else {
5484 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5485 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5487 break;
5489 case 0xC5: // Station name
5490 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5491 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5492 } else {
5493 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5495 break;
5497 case 0xC7: // Airporttile name
5498 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5499 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5500 } else {
5501 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5503 break;
5505 case 0xC9: // House name
5506 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5507 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5508 } else {
5509 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5511 break;
5513 default:
5514 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5515 break;
5517 break;
5521 return 0;
5525 struct SpritePair {
5526 SpriteID old, spr;
5529 /* Shore sprite replacements for single-corner and inclined slopes. */
5530 static const SpritePair shore_sprites_1 [] = {
5531 { SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1 }, // SLOPE_W
5532 { SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2 }, // SLOPE_S
5533 { SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3 }, // SLOPE_SW
5534 { SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4 }, // SLOPE_E
5535 { SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6 }, // SLOPE_SE
5536 { SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8 }, // SLOPE_N
5537 { SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9 }, // SLOPE_NW
5538 { SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12 }, // SLOPE_NE
5541 /* Shore sprite replacements for three-corner and steep slopes. */
5542 static const SpritePair shore_sprites_2 [] = {
5543 { SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0 }, // SLOPE_STEEP_S
5544 { SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5 }, // SLOPE_STEEP_W
5545 { SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7 }, // SLOPE_WSE
5546 { SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10 }, // SLOPE_STEEP_N
5547 { SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11 }, // SLOPE_NWS
5548 { SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13 }, // SLOPE_ENW
5549 { SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14 }, // SLOPE_SEN
5550 { SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15 }, // SLOPE_STEEP_E
5551 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
5552 * If they would be used somewhen, then these grass tiles will most like not look as needed */
5553 { SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16 }, // SLOPE_EW
5554 { SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17 }, // SLOPE_NS
5558 /** The type of action 5 type. */
5559 enum Action5BlockType {
5560 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5561 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5562 A5BLOCK_INVALID, ///< unknown/not-implemented type
5564 /** Information about a single action 5 type. */
5565 struct Action5Type {
5566 Action5BlockType block_type; ///< How is this Action5 type processed?
5567 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5568 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5569 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5570 const char *name; ///< Name for error messages.
5573 /** The information about action 5 types. */
5574 static const Action5Type _action5_types[] = {
5575 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5576 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5577 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5578 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5579 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5580 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5581 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5582 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5583 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5584 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5585 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5586 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5587 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5588 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5589 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5590 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5591 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5592 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5593 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5594 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5595 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5596 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5597 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5598 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5599 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5600 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5603 /* Action 0x05 */
5604 static int GraphicsNew (ByteReader *buf)
5606 /* <05> <graphics-type> <num-sprites> <other data...>
5608 * B graphics-type What set of graphics the sprites define.
5609 * E num-sprites How many sprites are in this set?
5610 * V other data Graphics type specific data. Currently unused. */
5611 /* TODO */
5613 uint8 type = buf->ReadByte();
5614 uint16 num = buf->ReadExtendedByte();
5615 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5616 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5618 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5619 /* Special not-TTDP-compatible case used in openttd.grf
5620 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5621 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5622 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
5623 LoadNextSprite (shore_sprites_2[i].spr, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
5625 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5626 return 0;
5629 /* Supported type? */
5630 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5631 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5632 return num;
5635 const Action5Type *action5_type = &_action5_types[type];
5637 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5638 * except for the long version of the shore type:
5639 * Ignore offset if not allowed */
5640 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5641 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5642 offset = 0;
5645 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5646 * This does not make sense, if <offset> is allowed */
5647 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5648 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);
5649 return num;
5652 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5653 uint16 skip_num;
5654 if (offset >= action5_type->max_sprites) {
5655 grfmsg (1, "GraphicsNew: %s sprite offset must be less than %i, skipping", action5_type->name, action5_type->max_sprites);
5656 skip_num = num;
5657 num = 0;
5658 } else if (offset + num > action5_type->max_sprites) {
5659 grfmsg (4, "GraphicsNew: %s sprite overflow, truncating...", action5_type->name);
5660 uint rem = action5_type->max_sprites - offset;
5661 skip_num = num - rem;
5662 num = rem;
5663 } else {
5664 skip_num = 0;
5666 SpriteID replace = action5_type->sprite_base + offset;
5668 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5669 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);
5671 for (; num > 0; num--) {
5672 _cur.nfo_line++;
5673 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5676 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5678 return skip_num;
5681 /* Action 0x05 (SKIP) */
5682 static int SkipAct5 (ByteReader *buf)
5684 /* Ignore type byte */
5685 buf->ReadByte();
5687 /* Skip the sprites of this action */
5688 int skip = buf->ReadExtendedByte();
5689 grfmsg (3, "SkipAct5: Skipping %d sprites", skip);
5690 return skip;
5694 * Reads a variable common to VarAction2 and Action7/9/D.
5696 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5697 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5699 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5700 * @param value returns the value of the variable.
5701 * @param grffile NewGRF querying the variable
5702 * @return true iff the variable is known and the value is returned in 'value'.
5704 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5706 switch (param) {
5707 case 0x00: // current date
5708 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5709 return true;
5711 case 0x01: // current year
5712 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5713 return true;
5715 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)
5716 YearMonthDay ymd;
5717 ConvertDateToYMD(_date, &ymd);
5718 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5719 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5720 return true;
5723 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5724 *value = _settings_game.game_creation.landscape;
5725 return true;
5727 case 0x06: // road traffic side, bit 4 clear=left, set=right
5728 *value = _settings_game.vehicle.road_side << 4;
5729 return true;
5731 case 0x09: // date fraction
5732 *value = _date_fract * 885;
5733 return true;
5735 case 0x0A: // animation counter
5736 *value = _tick_counter;
5737 return true;
5739 case 0x0B: { // TTDPatch version
5740 uint major = 2;
5741 uint minor = 6;
5742 uint revision = 1; // special case: 2.0.1 is 2.0.10
5743 uint build = 1382;
5744 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5745 return true;
5748 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5749 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5750 return true;
5752 case 0x0E: // Y-offset for train sprites
5753 *value = _cur.grffile->traininfo_vehicle_pitch;
5754 return true;
5756 case 0x0F: // Rail track type cost factors
5757 *value = 0;
5758 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5759 if (_settings_game.vehicle.disable_elrails) {
5760 /* skip elrail multiplier - disabled */
5761 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5762 } else {
5763 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5764 /* Skip monorail multiplier - no space in result */
5766 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5767 return true;
5769 case 0x11: // current rail tool type
5770 *value = 0; // constant fake value to avoid desync
5771 return true;
5773 case 0x12: // Game mode
5774 *value = _game_mode;
5775 return true;
5777 /* case 0x13: // Tile refresh offset to left not implemented */
5778 /* case 0x14: // Tile refresh offset to right not implemented */
5779 /* case 0x15: // Tile refresh offset upwards not implemented */
5780 /* case 0x16: // Tile refresh offset downwards not implemented */
5781 /* case 0x17: // temperate snow line not implemented */
5783 case 0x1A: // Always -1
5784 *value = UINT_MAX;
5785 return true;
5787 case 0x1B: // Display options
5788 *value = 0x3F; // constant fake value to avoid desync
5789 return true;
5791 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5792 *value = 1;
5793 return true;
5795 case 0x1E: // Miscellaneous GRF features
5796 *value = _misc_grf_features;
5798 /* Add the local flags */
5799 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5800 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5801 return true;
5803 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5805 case 0x20: { // snow line height
5806 byte snowline = GetSnowLine();
5807 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5808 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5809 } else {
5810 /* No snow */
5811 *value = 0xFF;
5813 return true;
5816 case 0x21: // OpenTTD version
5817 *value = _openttd_newgrf_version;
5818 return true;
5820 case 0x22: // difficulty level
5821 *value = SP_CUSTOM;
5822 return true;
5824 case 0x23: // long format date
5825 *value = _date;
5826 return true;
5828 case 0x24: // long format year
5829 *value = _cur_year;
5830 return true;
5832 default: return false;
5836 static uint32 GetParamVal(byte param, uint32 *cond_val)
5838 /* First handle variable common with VarAction2 */
5839 uint32 value;
5840 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5842 /* Non-common variable */
5843 switch (param) {
5844 case 0x84: { // GRF loading stage
5845 uint32 res = 0;
5847 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5848 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5849 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5850 return res;
5853 case 0x85: // TTDPatch flags, only for bit tests
5854 if (cond_val == NULL) {
5855 /* Supported in Action 0x07 and 0x09, not 0x0D */
5856 return 0;
5857 } else {
5858 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5859 *cond_val %= 0x20;
5860 return param_val;
5863 case 0x88: // GRF ID check
5864 return 0;
5866 /* case 0x99: Global ID offset not implemented */
5868 default:
5869 /* GRF Parameter */
5870 if (param < 0x80) return _cur.grffile->GetParam(param);
5872 /* In-game variable. */
5873 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5874 return UINT_MAX;
5878 /* Action 0x06 */
5879 static int CfgApply (ByteReader *buf)
5881 /* <06> <param-num> <param-size> <offset> ... <FF>
5883 * B param-num Number of parameter to substitute (First = "zero")
5884 * Ignored if that parameter was not specified in newgrf.cfg
5885 * B param-size How many bytes to replace. If larger than 4, the
5886 * bytes of the following parameter are used. In that
5887 * case, nothing is applied unless *all* parameters
5888 * were specified.
5889 * B offset Offset into data from beginning of next sprite
5890 * to place where parameter is to be stored. */
5892 /* Preload the next sprite */
5893 size_t pos = FioGetPos();
5894 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5895 uint8 type = FioReadByte();
5897 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5898 if (type != 0xFF) {
5899 /* Reset the file position to the start of the next sprite */
5900 FioSeekTo(pos, SEEK_SET);
5902 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5903 return 0;
5906 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5907 std::pair <GRFLineToSpriteOverride::iterator, bool> ins =
5908 _grf_line_to_action6_sprite_override.insert (std::make_pair (location, ttd_unique_free_ptr<byte>()));
5910 byte *preload_sprite;
5911 if (ins.second) {
5912 preload_sprite = xmalloct<byte> (num);
5913 ins.first->second.reset (preload_sprite);
5914 FioReadBlock (preload_sprite, num);
5915 } else {
5916 preload_sprite = ins.first->second.get();
5919 /* Reset the file position to the start of the next sprite */
5920 FioSeekTo (pos, SEEK_SET);
5922 /* Now perform the Action 0x06 on our data. */
5924 for (;;) {
5925 uint i;
5926 uint param_num;
5927 uint param_size;
5928 uint offset;
5929 bool add_value;
5931 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5932 param_num = buf->ReadByte();
5933 if (param_num == 0xFF) break;
5935 /* Get the size of the parameter to use. If the size covers multiple
5936 * double words, sequential parameter values are used. */
5937 param_size = buf->ReadByte();
5939 /* Bit 7 of param_size indicates we should add to the original value
5940 * instead of replacing it. */
5941 add_value = HasBit(param_size, 7);
5942 param_size = GB(param_size, 0, 7);
5944 /* Where to apply the data to within the pseudo sprite data. */
5945 offset = buf->ReadExtendedByte();
5947 /* If the parameter is a GRF parameter (not an internal variable) check
5948 * if it (and all further sequential parameters) has been defined. */
5949 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5950 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5951 break;
5954 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5956 bool carry = false;
5957 for (i = 0; i < param_size && offset + i < num; i++) {
5958 uint32 value = GetParamVal(param_num + i / 4, NULL);
5959 /* Reset carry flag for each iteration of the variable (only really
5960 * matters if param_size is greater than 4) */
5961 if (i % 4 == 0) carry = false;
5963 if (add_value) {
5964 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5965 preload_sprite[offset + i] = GB(new_value, 0, 8);
5966 /* Check if the addition overflowed */
5967 carry = new_value >= 256;
5968 } else {
5969 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
5974 return 0;
5978 * Disable a static NewGRF when it is influencing another (non-static)
5979 * NewGRF as this could cause desyncs.
5981 * We could just tell the NewGRF querying that the file doesn't exist,
5982 * but that might give unwanted results. Disabling the NewGRF gives the
5983 * best result as no NewGRF author can complain about that.
5984 * @param c The NewGRF to disable.
5986 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
5988 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
5991 /* Action 0x07
5992 * Action 0x09 */
5993 static int SkipIf (ByteReader *buf)
5995 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
5997 * B param-num
5998 * B param-size
5999 * B condition-type
6000 * V value
6001 * B num-sprites */
6002 /* TODO: More params. More condition types. */
6003 uint32 cond_val = 0;
6004 uint32 mask = 0;
6005 bool result;
6007 uint8 param = buf->ReadByte();
6008 uint8 paramsize = buf->ReadByte();
6009 uint8 condtype = buf->ReadByte();
6011 if (condtype < 2) {
6012 /* Always 1 for bit tests, the given value should be ignored. */
6013 paramsize = 1;
6016 switch (paramsize) {
6017 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6018 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6019 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6020 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6021 default: break;
6024 if (param < 0x80 && _cur.grffile->param_end <= param) {
6025 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6026 return 0;
6029 uint32 param_val = GetParamVal(param, &cond_val);
6031 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6034 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6035 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6036 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6037 * So, when the condition type is one of those, the specific variable
6038 * 0x88 code is skipped, so the "general" code for the cargo
6039 * availability conditions kicks in.
6041 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6042 /* GRF ID checks */
6044 GRFConfig *c = GetGRFConfig(cond_val, mask);
6046 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6047 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6048 c = NULL;
6051 if (condtype != 10 && c == NULL) {
6052 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6053 return 0;
6056 switch (condtype) {
6057 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6058 case 0x06: // Is GRFID active?
6059 result = c->status == GCS_ACTIVATED;
6060 break;
6062 case 0x07: // Is GRFID non-active?
6063 result = c->status != GCS_ACTIVATED;
6064 break;
6066 case 0x08: // GRFID is not but will be active?
6067 result = c->status == GCS_INITIALISED;
6068 break;
6070 case 0x09: // GRFID is or will be active?
6071 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6072 break;
6074 case 0x0A: // GRFID is not nor will be active
6075 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6076 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6077 break;
6079 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return 0;
6081 } else {
6082 /* Parameter or variable tests */
6083 switch (condtype) {
6084 case 0x00: result = !!(param_val & (1 << cond_val));
6085 break;
6086 case 0x01: result = !(param_val & (1 << cond_val));
6087 break;
6088 case 0x02: result = (param_val & mask) == cond_val;
6089 break;
6090 case 0x03: result = (param_val & mask) != cond_val;
6091 break;
6092 case 0x04: result = (param_val & mask) < cond_val;
6093 break;
6094 case 0x05: result = (param_val & mask) > cond_val;
6095 break;
6096 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6097 break;
6098 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6099 break;
6100 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6101 break;
6102 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6103 break;
6105 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return 0;
6109 if (!result) {
6110 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6111 return 0;
6114 uint8 numsprites = buf->ReadByte();
6116 /* numsprites can be a GOTO label if it has been defined in the GRF
6117 * file. The jump will always be the first matching label that follows
6118 * the current nfo_line. If no matching label is found, the first matching
6119 * label in the file is used. */
6120 GRFLabel *choice = NULL;
6121 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6122 if (label->label != numsprites) continue;
6124 /* Remember a goto before the current line */
6125 if (choice == NULL) choice = label;
6126 /* If we find a label here, this is definitely good */
6127 if (label->nfo_line > _cur.nfo_line) {
6128 choice = label;
6129 break;
6133 if (choice != NULL) {
6134 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6135 FioSeekTo(choice->pos, SEEK_SET);
6136 _cur.nfo_line = choice->nfo_line;
6137 return 0;
6140 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6142 if (numsprites != 0) return numsprites;
6144 /* If an action 8 hasn't been encountered yet, disable the grf. */
6145 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6146 DisableCur();
6149 /* Zero means there are no sprites to skip, so we use -1 to indicate
6150 * that all further sprites should be skipped. */
6151 return -1;
6155 /* Action 0x08 (GLS_FILESCAN) */
6156 static int ScanInfo (ByteReader *buf)
6158 uint8 grf_version = buf->ReadByte();
6159 uint32 grfid = buf->ReadDWord();
6160 const char *name = buf->ReadString();
6162 _cur.grfconfig->ident.grfid = grfid;
6164 if (grf_version < 2 || grf_version > 8) {
6165 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6166 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);
6169 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6170 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6172 _cur.grfconfig->name->add (0x7F, grfid, false, name);
6174 if (buf->HasData()) {
6175 const char *info = buf->ReadString();
6176 _cur.grfconfig->info->add (0x7F, grfid, true, info);
6179 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6180 return -1;
6183 /* Action 0x08 */
6184 static int GRFInfo (ByteReader *buf)
6186 /* <08> <version> <grf-id> <name> <info>
6188 * B version newgrf version, currently 06
6189 * 4*B grf-id globally unique ID of this .grf file
6190 * S name name of this .grf set
6191 * S info string describing the set, and e.g. author and copyright */
6193 uint8 version = buf->ReadByte();
6194 uint32 grfid = buf->ReadDWord();
6195 const char *name = buf->ReadString();
6197 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6198 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6199 return -1;
6202 if (_cur.grffile->grfid != grfid) {
6203 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));
6204 _cur.grffile->grfid = grfid;
6207 _cur.grffile->grf_version = version;
6208 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6210 /* Do swap the GRFID for displaying purposes since people expect that */
6211 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);
6213 return 0;
6216 /* Action 0x0A */
6217 static int SpriteReplace (ByteReader *buf)
6219 /* <0A> <num-sets> <set1> [<set2> ...]
6220 * <set>: <num-sprites> <first-sprite>
6222 * B num-sets How many sets of sprites to replace.
6223 * Each set:
6224 * B num-sprites How many sprites are in this set
6225 * W first-sprite First sprite number to replace */
6227 uint8 num_sets = buf->ReadByte();
6229 for (uint i = 0; i < num_sets; i++) {
6230 uint8 num_sprites = buf->ReadByte();
6231 uint16 first_sprite = buf->ReadWord();
6233 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6234 i, num_sprites, first_sprite
6237 for (uint j = 0; j < num_sprites; j++) {
6238 int load_index = first_sprite + j;
6239 _cur.nfo_line++;
6240 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6242 /* Shore sprites now located at different addresses.
6243 * So detect when the old ones get replaced. */
6244 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6245 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6250 return 0;
6253 /* Action 0x0A (SKIP) */
6254 static int SkipActA (ByteReader *buf)
6256 uint8 num_sets = buf->ReadByte();
6258 int skip = 0;
6259 for (uint i = 0; i < num_sets; i++) {
6260 /* Skip the sprites this replaces */
6261 skip += buf->ReadByte();
6262 /* But ignore where they go */
6263 buf->ReadWord();
6266 grfmsg (3, "SkipActA: Skipping %d sprites", skip);
6268 return skip;
6271 /* Action 0x0B */
6272 static int GRFLoadError (ByteReader *buf)
6274 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6276 * B severity 00: notice, contine loading grf file
6277 * 01: warning, continue loading grf file
6278 * 02: error, but continue loading grf file, and attempt
6279 * loading grf again when loading or starting next game
6280 * 03: error, abort loading and prevent loading again in
6281 * the future (only when restarting the patch)
6282 * B language-id see action 4, use 1F for built-in error messages
6283 * B message-id message to show, see below
6284 * S message for custom messages (message-id FF), text of the message
6285 * not present for built-in messages.
6286 * V data additional data for built-in (or custom) messages
6287 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6289 static const StringID msgstr[] = {
6290 STR_NEWGRF_ERROR_VERSION_NUMBER,
6291 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6292 STR_NEWGRF_ERROR_UNSET_SWITCH,
6293 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6294 STR_NEWGRF_ERROR_LOAD_BEFORE,
6295 STR_NEWGRF_ERROR_LOAD_AFTER,
6296 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6299 static const StringID sevstr[] = {
6300 STR_NEWGRF_ERROR_MSG_INFO,
6301 STR_NEWGRF_ERROR_MSG_WARNING,
6302 STR_NEWGRF_ERROR_MSG_ERROR,
6303 STR_NEWGRF_ERROR_MSG_FATAL
6306 byte severity = buf->ReadByte();
6307 byte lang = buf->ReadByte();
6308 byte message_id = buf->ReadByte();
6310 /* Skip the error if it isn't valid for the current language. */
6311 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return 0;
6313 /* Skip the error until the activation stage unless bit 7 of the severity
6314 * is set. */
6315 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6316 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6317 return 0;
6319 ClrBit(severity, 7);
6321 if (severity >= lengthof(sevstr)) {
6322 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6323 severity = 2;
6324 } else if (severity == 3) {
6325 /* This is a fatal error, so make sure the GRF is deactivated and no
6326 * more of it gets loaded. */
6327 DisableCur();
6329 /* Make sure we show fatal errors, instead of silly infos from before */
6330 delete _cur.grfconfig->error;
6331 _cur.grfconfig->error = NULL;
6334 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6335 grfmsg(7, "GRFLoadError: Invalid message id.");
6337 } else if (!buf->HasData (2)) {
6338 grfmsg(7, "GRFLoadError: No message data supplied.");
6340 } else if (_cur.grfconfig->error == NULL) {
6341 /* For now we can only show one message per newgrf file. */
6342 GRFError *error = new GRFError (sevstr[severity]);
6344 if (message_id != 0xFF) {
6345 error->message = msgstr[message_id];
6346 } else if (buf->HasData()) {
6347 /* This is a custom error message. */
6348 const char *message = buf->ReadString();
6349 error->custom_message = TranslateTTDPatchCodes (_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
6350 } else {
6351 grfmsg(7, "GRFLoadError: No custom message supplied.");
6352 error->custom_message = xstrdup("");
6355 if (buf->HasData()) {
6356 const char *data = buf->ReadString();
6357 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6358 } else {
6359 grfmsg(7, "GRFLoadError: No message data supplied.");
6360 error->data = xstrdup("");
6363 /* Only two parameter numbers can be used in the string. */
6364 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6365 uint param_number = buf->ReadByte();
6366 error->param_value[i] = _cur.grffile->GetParam(param_number);
6369 _cur.grfconfig->error = error;
6372 return (severity == 3) ? -1 : 0;
6375 /* Action 0x0C */
6376 static int GRFComment (ByteReader *buf)
6378 /* <0C> [<ignored...>]
6380 * V ignored Anything following the 0C is ignored */
6382 if (buf->HasData()) grfmsg (2, "GRFComment: %s", buf->ReadString());
6384 return 0;
6387 /* Action 0x0D (GLS_SAFETYSCAN) */
6388 static int SafeParamSet (ByteReader *buf)
6390 uint8 target = buf->ReadByte();
6392 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6393 if (target < 0x80 || target == 0x9E) return 0;
6395 /* GRM could be unsafe, but as here it can only happen after other GRFs
6396 * are loaded, it should be okay. If the GRF tried to use the slots it
6397 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6398 * sprites is considered safe. */
6400 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6402 /* Skip remainder of GRF */
6403 return -1;
6407 static uint32 GetPatchVariable(uint8 param)
6409 switch (param) {
6410 /* start year - 1920 */
6411 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6413 /* freight trains weight factor */
6414 case 0x0E: return _settings_game.vehicle.freight_trains;
6416 /* empty wagon speed increase */
6417 case 0x0F: return 0;
6419 /* plane speed factor; our patch option is reversed from TTDPatch's,
6420 * the following is good for 1x, 2x and 4x (most common?) and...
6421 * well not really for 3x. */
6422 case 0x10:
6423 switch (_settings_game.vehicle.plane_speed) {
6424 default:
6425 case 4: return 1;
6426 case 3: return 2;
6427 case 2: return 2;
6428 case 1: return 4;
6432 /* 2CC colourmap base sprite */
6433 case 0x11: return SPR_2CCMAP_BASE;
6435 /* map size: format = -MABXYSS
6436 * M : the type of map
6437 * bit 0 : set : squared map. Bit 1 is now not relevant
6438 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6439 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6440 * clear : X is the bigger edge.
6441 * A : minimum edge(log2) of the map
6442 * B : maximum edge(log2) of the map
6443 * XY : edges(log2) of each side of the map.
6444 * SS : combination of both X and Y, thus giving the size(log2) of the map
6446 case 0x13: {
6447 byte map_bits = 0;
6448 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6449 byte log_Y = MapLogY() - 6;
6450 byte max_edge = max(log_X, log_Y);
6452 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6453 SetBit(map_bits, 0);
6454 } else {
6455 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6458 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6459 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6462 /* The maximum height of the map. */
6463 case 0x14:
6464 return _settings_game.construction.max_heightlevel;
6466 /* Extra foundations base sprite */
6467 case 0x15:
6468 return SPR_SLOPES_BASE;
6470 /* Shore base sprite */
6471 case 0x16:
6472 return SPR_SHORE_BASE;
6474 default:
6475 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6476 return 0;
6481 static bool PerformGRM (uint32 *grm, uint16 num_ids, uint16 count,
6482 uint8 op, uint8 target, uint32 *res, const char *type)
6484 uint start = 0;
6485 uint size = 0;
6487 if (op == 6) {
6488 /* Return GRFID of set that reserved ID */
6489 *res = grm[_cur.grffile->GetParam(target)];
6490 return true;
6493 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6494 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6496 for (uint i = start; i < num_ids; i++) {
6497 if (grm[i] == 0) {
6498 size++;
6499 } else {
6500 if (op == 2 || op == 3) break;
6501 start = i + 1;
6502 size = 0;
6505 if (size == count) break;
6508 if (size == count) {
6509 /* Got the slot... */
6510 if (op == 0 || op == 3) {
6511 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6512 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6514 *res = start;
6515 return true;
6518 /* Unable to allocate */
6519 if (op != 4 && op != 5) {
6520 /* Deactivate GRF */
6521 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6522 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6523 return false;
6526 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6527 *res = UINT_MAX;
6528 return true;
6532 /** Action 0x0D: Set parameter */
6533 static int ParamSet (ByteReader *buf)
6535 /* <0D> <target> <operation> <source1> <source2> [<data>]
6537 * B target parameter number where result is stored
6538 * B operation operation to perform, see below
6539 * B source1 first source operand
6540 * B source2 second source operand
6541 * D data data to use in the calculation, not necessary
6542 * if both source1 and source2 refer to actual parameters
6544 * Operations
6545 * 00 Set parameter equal to source1
6546 * 01 Addition, source1 + source2
6547 * 02 Subtraction, source1 - source2
6548 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6549 * 04 Signed multiplication, source1 * source2 (both signed)
6550 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6551 * signed quantity; left shift if positive and right shift if
6552 * negative, source1 is unsigned)
6553 * 06 Signed bit shift, source1 by source2
6554 * (source2 like in 05, and source1 as well)
6557 uint8 target = buf->ReadByte();
6558 uint8 oper = buf->ReadByte();
6559 uint32 src1 = buf->ReadByte();
6560 uint32 src2 = buf->ReadByte();
6562 uint32 data = 0;
6563 if (buf->HasData (4)) data = buf->ReadDWord();
6565 /* You can add 80 to the operation to make it apply only if the target
6566 * is not defined yet. In this respect, a parameter is taken to be
6567 * defined if any of the following applies:
6568 * - it has been set to any value in the newgrf(w).cfg parameter list
6569 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6570 * an earlier action D */
6571 if (HasBit(oper, 7)) {
6572 if (target < 0x80 && target < _cur.grffile->param_end) {
6573 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6574 return 0;
6577 oper = GB(oper, 0, 7);
6580 if (src2 != 0xFE) {
6581 /* The source1 and source2 operands refer to the grf parameter number
6582 * like in action 6 and 7. In addition, they can refer to the special
6583 * variables available in action 7, or they can be FF to use the value
6584 * of <data>. If referring to parameters that are undefined, a value
6585 * of 0 is used instead. */
6586 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6587 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6588 } else if (GB(data, 0, 8) != 0xFF) {
6589 /* Read another GRF File's parameter */
6590 const GRFFile *file = GetFileByGRFID(data);
6591 GRFConfig *c = GetGRFConfig(data);
6592 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6593 /* Disable the read GRF if it is a static NewGRF. */
6594 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6595 src1 = 0;
6596 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6597 src1 = 0;
6598 } else if (src1 == 0xFE) {
6599 src1 = c->version;
6600 } else {
6601 src1 = file->GetParam(src1);
6603 } else if (data == 0x0000FFFF) {
6604 /* Patch variables */
6605 src1 = GetPatchVariable(src1);
6606 } else {
6607 /* GRF Resource Management */
6608 uint8 op = src1;
6609 uint8 feature = GB(data, 8, 8);
6610 uint16 count = GB(data, 16, 16);
6612 if (_cur.stage == GLS_RESERVE) {
6613 if (feature == 0x08) {
6614 /* General sprites */
6615 if (op == 0) {
6616 /* Check if the allocated sprites will fit below the original sprite limit */
6617 if (_cur.spriteid + count >= 16384) {
6618 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6619 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6620 return -1;
6623 /* Reserve space at the current sprite ID */
6624 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6625 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6626 _cur.spriteid += count;
6629 /* Ignore GRM result during reservation */
6630 src1 = 0;
6631 } else if (_cur.stage == GLS_ACTIVATION) {
6632 switch (feature) {
6633 case 0x00: // Trains
6634 case 0x01: // Road Vehicles
6635 case 0x02: // Ships
6636 case 0x03: // Aircraft
6637 if (!_settings_game.vehicle.dynamic_engines) {
6638 if (!PerformGRM (&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, &src1, "vehicles")) {
6639 return -1;
6641 } else {
6642 /* GRM does not apply for dynamic engine allocation. */
6643 switch (op) {
6644 case 2:
6645 case 3:
6646 src1 = _cur.grffile->GetParam(target);
6647 break;
6649 default:
6650 src1 = 0;
6651 break;
6654 break;
6656 case 0x08: // General sprites
6657 switch (op) {
6658 case 0:
6659 /* Return space reserved during reservation stage */
6660 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6661 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6662 break;
6664 case 1:
6665 src1 = _cur.spriteid;
6666 break;
6668 default:
6669 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6670 return 0;
6672 break;
6674 case 0x0B: // Cargo
6675 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6676 if (!PerformGRM (_grm_cargoes, NUM_CARGO * 2, count, op, target, &src1, "cargoes")) {
6677 return -1;
6679 break;
6681 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return 0;
6683 } else {
6684 /* Ignore GRM during initialization */
6685 src1 = 0;
6689 /* TODO: You can access the parameters of another GRF file by using
6690 * source2=FE, source1=the other GRF's parameter number and data=GRF
6691 * ID. This is only valid with operation 00 (set). If the GRF ID
6692 * cannot be found, a value of 0 is used for the parameter value
6693 * instead. */
6695 uint32 res;
6696 switch (oper) {
6697 case 0x00:
6698 res = src1;
6699 break;
6701 case 0x01:
6702 res = src1 + src2;
6703 break;
6705 case 0x02:
6706 res = src1 - src2;
6707 break;
6709 case 0x03:
6710 res = src1 * src2;
6711 break;
6713 case 0x04:
6714 res = (int32)src1 * (int32)src2;
6715 break;
6717 case 0x05:
6718 if ((int32)src2 < 0) {
6719 res = src1 >> -(int32)src2;
6720 } else {
6721 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6723 break;
6725 case 0x06:
6726 if ((int32)src2 < 0) {
6727 res = (int32)src1 >> -(int32)src2;
6728 } else {
6729 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6731 break;
6733 case 0x07: // Bitwise AND
6734 res = src1 & src2;
6735 break;
6737 case 0x08: // Bitwise OR
6738 res = src1 | src2;
6739 break;
6741 case 0x09: // Unsigned division
6742 if (src2 == 0) {
6743 res = src1;
6744 } else {
6745 res = src1 / src2;
6747 break;
6749 case 0x0A: // Signed divison
6750 if (src2 == 0) {
6751 res = src1;
6752 } else {
6753 res = (int32)src1 / (int32)src2;
6755 break;
6757 case 0x0B: // Unsigned modulo
6758 if (src2 == 0) {
6759 res = src1;
6760 } else {
6761 res = src1 % src2;
6763 break;
6765 case 0x0C: // Signed modulo
6766 if (src2 == 0) {
6767 res = src1;
6768 } else {
6769 res = (int32)src1 % (int32)src2;
6771 break;
6773 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return 0;
6776 switch (target) {
6777 case 0x8E: // Y-Offset for train sprites
6778 _cur.grffile->traininfo_vehicle_pitch = res;
6779 break;
6781 case 0x8F: { // Rail track type cost factors
6782 extern RailtypeInfo _railtypes[RAILTYPE_END];
6783 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6784 if (_settings_game.vehicle.disable_elrails) {
6785 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6786 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6787 } else {
6788 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6789 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6791 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6792 break;
6795 /* @todo implement */
6796 case 0x93: // Tile refresh offset to left
6797 case 0x94: // Tile refresh offset to right
6798 case 0x95: // Tile refresh offset upwards
6799 case 0x96: // Tile refresh offset downwards
6800 case 0x97: // Snow line height
6801 case 0x99: // Global ID offset
6802 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6803 break;
6805 case 0x9E: // Miscellaneous GRF features
6806 /* Set train list engine width */
6807 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6808 /* Remove the local flags from the global flags */
6809 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6811 /* Only copy safe bits for static grfs */
6812 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6813 uint32 safe_bits = 0;
6814 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6816 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6817 } else {
6818 _misc_grf_features = res;
6820 break;
6822 case 0x9F: // locale-dependent settings
6823 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6824 break;
6826 default:
6827 if (target < 0x80) {
6828 _cur.grffile->param[target] = res;
6829 /* param is zeroed by default */
6830 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6831 } else {
6832 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6834 break;
6837 return 0;
6840 /* Action 0x0E (GLS_SAFETYSCAN) */
6841 static int SafeGRFInhibit (ByteReader *buf)
6843 /* <0E> <num> <grfids...>
6845 * B num Number of GRFIDs that follow
6846 * D grfids GRFIDs of the files to deactivate */
6848 uint8 num = buf->ReadByte();
6850 for (uint i = 0; i < num; i++) {
6851 uint32 grfid = buf->ReadDWord();
6853 /* GRF is unsafe it if tries to deactivate other GRFs */
6854 if (grfid != _cur.grfconfig->ident.grfid) {
6855 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6857 /* Skip remainder of GRF */
6858 return -1;
6862 return 0;
6865 /* Action 0x0E */
6866 static int GRFInhibit (ByteReader *buf)
6868 /* <0E> <num> <grfids...>
6870 * B num Number of GRFIDs that follow
6871 * D grfids GRFIDs of the files to deactivate */
6873 uint8 num = buf->ReadByte();
6875 for (uint i = 0; i < num; i++) {
6876 uint32 grfid = buf->ReadDWord();
6877 GRFConfig *file = GetGRFConfig(grfid);
6879 /* Unset activation flag */
6880 if (file != NULL && file != _cur.grfconfig) {
6881 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6882 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6886 return 0;
6889 /** Action 0x0F - Define Town names */
6890 static int FeatureTownName (ByteReader *buf)
6892 /* <0F> <id> <style-name> <num-parts> <parts>
6894 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6895 * V style-name Name of the style (only for final definition)
6896 * B num-parts Number of parts in this definition
6897 * V parts The parts */
6899 uint32 grfid = _cur.grffile->grfid;
6901 GRFTownName *townname = AddGRFTownName(grfid);
6903 byte id = buf->ReadByte();
6904 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6906 if (HasBit(id, 7)) {
6907 /* Final definition */
6908 ClrBit(id, 7);
6909 bool new_scheme = _cur.grffile->grf_version >= 7;
6911 byte lang = buf->ReadByte();
6913 byte nb_gen = townname->nb_gen;
6914 do {
6915 ClrBit(lang, 7);
6917 const char *name = buf->ReadString();
6919 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6920 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6921 free(lang_name);
6923 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6925 lang = buf->ReadByte();
6926 } while (lang != 0);
6927 townname->id[nb_gen] = id;
6928 townname->nb_gen++;
6931 byte nb = buf->ReadByte();
6932 grfmsg(6, "FeatureTownName: %u parts", nb);
6934 townname->nbparts[id] = nb;
6935 townname->partlist[id] = xcalloct<NamePartList>(nb);
6937 for (int i = 0; i < nb; i++) {
6938 byte nbtext = buf->ReadByte();
6939 townname->partlist[id][i].bitstart = buf->ReadByte();
6940 townname->partlist[id][i].bitcount = buf->ReadByte();
6941 townname->partlist[id][i].maxprob = 0;
6942 townname->partlist[id][i].partcount = nbtext;
6943 townname->partlist[id][i].parts = xcalloct<NamePart>(nbtext);
6944 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);
6946 for (int j = 0; j < nbtext; j++) {
6947 byte prob = buf->ReadByte();
6949 if (HasBit(prob, 7)) {
6950 byte ref_id = buf->ReadByte();
6952 if (townname->nbparts[ref_id] == 0) {
6953 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6954 DelGRFTownName(grfid);
6955 DisableCur (STR_NEWGRF_ERROR_INVALID_ID);
6956 return -1;
6959 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6960 townname->partlist[id][i].parts[j].data.id = ref_id;
6961 } else {
6962 const char *text = buf->ReadString();
6963 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6964 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6966 townname->partlist[id][i].parts[j].prob = prob;
6967 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6969 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6972 return 0;
6975 /** Action 0x10 - Define goto label */
6976 static int DefineGotoLabel (ByteReader *buf)
6978 /* <10> <label> [<comment>]
6980 * B label The label to define
6981 * V comment Optional comment - ignored */
6983 byte nfo_label = buf->ReadByte();
6985 GRFLabel *label = xmalloct<GRFLabel>();
6986 label->label = nfo_label;
6987 label->nfo_line = _cur.nfo_line;
6988 label->pos = FioGetPos();
6989 label->next = NULL;
6991 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6992 if (_cur.grffile->label == NULL) {
6993 _cur.grffile->label = label;
6994 } else {
6995 /* Attach the label to the end of the list */
6996 GRFLabel *l;
6997 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
6998 l->next = label;
7001 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7003 return 0;
7007 * Process a sound import from another GRF file.
7008 * @param sound Destination for sound.
7010 static void ImportGRFSound(SoundEntry *sound)
7012 const GRFFile *file;
7013 uint32 grfid = FioReadDword();
7014 SoundID sound_id = FioReadWord();
7016 file = GetFileByGRFID(grfid);
7017 if (file == NULL || file->sound_offset == 0) {
7018 grfmsg(1, "ImportGRFSound: Source file not available");
7019 return;
7022 if (sound_id >= file->num_sounds) {
7023 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7024 return;
7027 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7029 *sound = *GetSound(file->sound_offset + sound_id);
7031 /* Reset volume and priority, which TTDPatch doesn't copy */
7032 sound->volume = 128;
7033 sound->priority = 0;
7037 * Load a sound from a file.
7038 * @param offs File offset to read sound from.
7039 * @param sound Destination for sound.
7041 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7043 /* Set default volume and priority */
7044 sound->volume = 0x80;
7045 sound->priority = 0;
7047 if (offs != SIZE_MAX) {
7048 /* Sound is present in the NewGRF. */
7049 sound->file_slot = _cur.file_index;
7050 sound->file_offset = offs;
7051 sound->grf_container_ver = _cur.grf_container_ver;
7055 /* Action 0x11 */
7056 static int GRFSound (ByteReader *buf)
7058 /* <11> <num>
7060 * W num Number of sound files that follow */
7062 uint16 num = buf->ReadWord();
7063 if (num == 0) return 0;
7065 SoundEntry *sound;
7066 if (_cur.grffile->sound_offset == 0) {
7067 _cur.grffile->sound_offset = GetNumSounds();
7068 _cur.grffile->num_sounds = num;
7069 sound = AllocateSound(num);
7070 } else {
7071 sound = GetSound(_cur.grffile->sound_offset);
7074 for (int i = 0; i < num; i++) {
7075 _cur.nfo_line++;
7077 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7078 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7079 bool invalid = i >= _cur.grffile->num_sounds;
7081 size_t offs = FioGetPos();
7083 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7084 byte type = FioReadByte();
7086 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7087 /* Reference to sprite section. */
7088 if (invalid) {
7089 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7090 FioSkipBytes(len);
7091 } else if (len != 4) {
7092 grfmsg(1, "GRFSound: Invalid sprite section import");
7093 FioSkipBytes(len);
7094 } else {
7095 uint32 id = FioReadDword();
7096 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7098 continue;
7101 if (type != 0xFF) {
7102 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7103 FioSkipBytes(7);
7104 SkipSpriteData(type, len - 8);
7105 continue;
7108 if (invalid) {
7109 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7110 FioSkipBytes(len);
7113 byte action = FioReadByte();
7114 switch (action) {
7115 case 0xFF:
7116 /* Allocate sound only in init stage. */
7117 if (_cur.stage == GLS_INIT) {
7118 if (_cur.grf_container_ver >= 2) {
7119 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7120 } else {
7121 LoadGRFSound(offs, sound + i);
7124 FioSkipBytes(len - 1); // already read <action>
7125 break;
7127 case 0xFE:
7128 if (_cur.stage == GLS_ACTIVATION) {
7129 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7130 * importing sounds, so this is probably all wrong... */
7131 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7132 ImportGRFSound(sound + i);
7133 } else {
7134 FioSkipBytes(len - 1); // already read <action>
7136 break;
7138 default:
7139 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7140 FioSkipBytes(len - 1); // already read <action>
7141 break;
7145 return 0;
7148 /* Action 0x11 (SKIP) */
7149 static int SkipAct11 (ByteReader *buf)
7151 /* <11> <num>
7153 * W num Number of sound files that follow */
7155 int skip = buf->ReadWord();
7156 grfmsg (3, "SkipAct11: Skipping %d sprites", skip);
7157 return skip;
7160 /** Action 0x12 */
7161 static int LoadFontGlyph (ByteReader *buf)
7163 /* <12> <num_def> <font_size> <num_char> <base_char>
7165 * B num_def Number of definitions
7166 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7167 * B num_char Number of consecutive glyphs
7168 * W base_char First character index */
7170 uint8 num_def = buf->ReadByte();
7172 for (uint i = 0; i < num_def; i++) {
7173 FontSize size = (FontSize)buf->ReadByte();
7174 uint8 num_char = buf->ReadByte();
7175 uint16 base_char = buf->ReadWord();
7177 FontCache *fc;
7178 if (size >= FS_END) {
7179 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7180 fc = NULL;
7181 } else {
7182 fc = FontCache::Get (size);
7185 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7187 for (uint c = 0; c < num_char; c++) {
7188 if (fc != NULL) fc->SetUnicodeGlyph (base_char + c, _cur.spriteid);
7189 _cur.nfo_line++;
7190 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7194 return 0;
7197 /** Action 0x12 (SKIP) */
7198 static int SkipAct12 (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)
7204 * B num_char Number of consecutive glyphs
7205 * W base_char First character index */
7207 uint8 num_def = buf->ReadByte();
7209 int skip = 0;
7210 for (uint i = 0; i < num_def; i++) {
7211 /* Ignore 'size' byte */
7212 buf->ReadByte();
7214 /* Sum up number of characters */
7215 skip += buf->ReadByte();
7217 /* Ignore 'base_char' word */
7218 buf->ReadWord();
7221 grfmsg (3, "SkipAct12: Skipping %d sprites", skip);
7223 return skip;
7226 /** Action 0x13 */
7227 static int TranslateGRFStrings (ByteReader *buf)
7229 /* <13> <grfid> <num-ent> <offset> <text...>
7231 * 4*B grfid The GRFID of the file whose texts are to be translated
7232 * B num-ent Number of strings
7233 * W offset First text ID
7234 * S text... Zero-terminated strings */
7236 uint32 grfid = buf->ReadDWord();
7237 const GRFConfig *c = GetGRFConfig(grfid);
7238 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7239 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7240 return 0;
7243 if (c->status == GCS_INITIALISED) {
7244 /* If the file is not active but will be activated later, give an error
7245 * and disable this file. */
7246 GRFError *error = DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER);
7248 char tmp[256];
7249 GetString (tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7250 error->data = xstrdup(tmp);
7252 return -1;
7255 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7256 * to be added as a generic string, thus the language id of 0x7F. For this to work
7257 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7258 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7259 * not change anything if a string has been provided specifically for this language. */
7260 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7261 byte num_strings = buf->ReadByte();
7262 uint16 first_id = buf->ReadWord();
7264 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7265 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7266 return 0;
7269 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7270 const char *string = buf->ReadString();
7272 if (StrEmpty(string)) {
7273 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7274 continue;
7277 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7280 return 0;
7283 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7284 static bool ChangeGRFName(byte langid, const char *str)
7286 _cur.grfconfig->name->add (langid, _cur.grfconfig->ident.grfid, false, str);
7287 return true;
7290 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7291 static bool ChangeGRFDescription(byte langid, const char *str)
7293 _cur.grfconfig->info->add (langid, _cur.grfconfig->ident.grfid, true, str);
7294 return true;
7297 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7298 static bool ChangeGRFURL(byte langid, const char *str)
7300 _cur.grfconfig->url->add (langid, _cur.grfconfig->ident.grfid, false, str);
7301 return true;
7304 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7305 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7307 if (len != 1) {
7308 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7309 buf->Skip(len);
7310 } else {
7311 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7313 return true;
7316 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7317 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7319 if (len != 1) {
7320 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7321 buf->Skip(len);
7322 } else {
7323 char data = buf->ReadByte();
7324 GRFPalette pal = GRFP_GRF_UNSET;
7325 switch (data) {
7326 case '*':
7327 case 'A': pal = GRFP_GRF_ANY; break;
7328 case 'W': pal = GRFP_GRF_WINDOWS; break;
7329 case 'D': pal = GRFP_GRF_DOS; break;
7330 default:
7331 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7332 break;
7334 if (pal != GRFP_GRF_UNSET) {
7335 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7336 _cur.grfconfig->palette |= pal;
7339 return true;
7342 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7343 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7345 if (len != 1) {
7346 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7347 buf->Skip(len);
7348 } else {
7349 char data = buf->ReadByte();
7350 GRFPalette pal = GRFP_BLT_UNSET;
7351 switch (data) {
7352 case '8': pal = GRFP_BLT_UNSET; break;
7353 case '3': pal = GRFP_BLT_32BPP; break;
7354 default:
7355 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7356 return true;
7358 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7359 _cur.grfconfig->palette |= pal;
7361 return true;
7364 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7365 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7367 if (len != 4) {
7368 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7369 buf->Skip(len);
7370 } else {
7371 /* Set min_loadable_version as well (default to minimal compatibility) */
7372 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7374 return true;
7377 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7378 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7380 if (len != 4) {
7381 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7382 buf->Skip(len);
7383 } else {
7384 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7385 if (_cur.grfconfig->version == 0) {
7386 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7387 _cur.grfconfig->min_loadable_version = 0;
7389 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7390 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7391 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7394 return true;
7397 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7399 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7400 static bool ChangeGRFParamName(byte langid, const char *str)
7402 _cur_parameter->name.add (langid, _cur.grfconfig->ident.grfid, false, str);
7403 return true;
7406 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7407 static bool ChangeGRFParamDescription(byte langid, const char *str)
7409 _cur_parameter->desc.add (langid, _cur.grfconfig->ident.grfid, true, str);
7410 return true;
7413 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7414 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7416 if (len != 1) {
7417 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7418 buf->Skip(len);
7419 } else {
7420 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7421 if (type < PTYPE_END) {
7422 _cur_parameter->type = type;
7423 } else {
7424 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7427 return true;
7430 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7431 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7433 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7434 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7435 buf->Skip(len);
7436 } else if (len != 8) {
7437 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7438 buf->Skip(len);
7439 } else {
7440 _cur_parameter->min_value = buf->ReadDWord();
7441 _cur_parameter->max_value = buf->ReadDWord();
7443 return true;
7446 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7447 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7449 if (len < 1 || len > 3) {
7450 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7451 buf->Skip(len);
7452 } else {
7453 byte param_nr = buf->ReadByte();
7454 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7455 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7456 buf->Skip(len - 1);
7457 } else {
7458 _cur_parameter->param_nr = param_nr;
7459 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7460 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7464 return true;
7467 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7468 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7470 if (len != 4) {
7471 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7472 buf->Skip(len);
7473 } else {
7474 _cur_parameter->def_value = buf->ReadDWord();
7476 _cur.grfconfig->has_param_defaults = true;
7477 return true;
7481 * Data structure to store the allowed id/type combinations for action 14. The
7482 * data can be represented as a tree with 3 types of nodes:
7483 * 1. Branch nodes (identified by 'C' for choice).
7484 * 2. Binary leaf nodes (identified by 'B').
7485 * 3. Text leaf nodes (identified by 'T').
7487 struct AllowedSubtags {
7488 typedef bool (*DataHandler) (size_t, ByteReader *); ///< Type of callback function for binary nodes
7489 typedef bool (*TextHandler) (byte, const char *str); ///< Type of callback function for text nodes
7490 typedef bool (*BranchHandler) (ByteReader *); ///< Type of callback function for branch nodes
7492 uint32 id; ///< The identifier for this node
7493 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7494 byte nsub; ///< The number of subtags, or 0 if not applicable
7495 union {
7496 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7497 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7498 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7499 const AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7502 /** Create empty subtags object used to identify the end of a list. */
7503 CONSTEXPR AllowedSubtags() :
7504 id(0), type(0), nsub(0), subtags(NULL)
7508 * Create a binary leaf node.
7509 * @param id The id for this node.
7510 * @param handler The callback function to call.
7512 CONSTEXPR AllowedSubtags (uint32 id, DataHandler handler) :
7513 id(id), type('B'), nsub(0), data(handler)
7518 * Create a text leaf node.
7519 * @param id The id for this node.
7520 * @param handler The callback function to call.
7522 CONSTEXPR AllowedSubtags (uint32 id, TextHandler handler) :
7523 id(id), type('T'), nsub(0), text(handler)
7528 * Create a branch node with a callback handler
7529 * @param id The id for this node.
7530 * @param handler The callback function to call.
7532 CONSTEXPR AllowedSubtags (uint32 id, BranchHandler handler) :
7533 id(id), type('C'), nsub(0), branch(handler)
7538 * Create a branch node with a list of sub-nodes.
7539 * @param id The id for this node.
7540 * @param subtags Array with all valid subtags.
7542 template <uint N>
7543 CONSTEXPR AllowedSubtags (uint32 id, const AllowedSubtags (&subtags) [N]) :
7544 id(id), type('C'), nsub(N), subtags(subtags)
7546 assert_tcompile (N > 0);
7547 assert_tcompile (N <= UINT8_MAX);
7551 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7552 static bool HandleNodes(ByteReader *buf, const AllowedSubtags *tags);
7555 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7556 * of some parameter values (type uint/enum) or the names of some bits
7557 * (type bitmask). In both cases the format is the same:
7558 * Each subnode should be a text node with the value/bit number as id.
7560 static bool ChangeGRFParamValueNames(ByteReader *buf)
7562 for (;;) {
7563 byte type = buf->ReadByte();
7564 if (type == 0) break;
7566 uint32 id = buf->ReadDWord();
7567 if (type != 'T' || id > _cur_parameter->max_value) {
7568 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7569 if (!SkipUnknownInfo(buf, type)) return false;
7570 continue;
7573 byte langid = buf->ReadByte();
7574 const char *name_string = buf->ReadString();
7576 _cur_parameter->value_names[id].add (langid,
7577 _cur.grfconfig->ident.grfid, false, name_string);
7579 return true;
7582 /** Action14 parameter tags */
7583 static const AllowedSubtags _tags_parameters[] = {
7584 AllowedSubtags('NAME', ChangeGRFParamName),
7585 AllowedSubtags('DESC', ChangeGRFParamDescription),
7586 AllowedSubtags('TYPE', ChangeGRFParamType),
7587 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7588 AllowedSubtags('MASK', ChangeGRFParamMask),
7589 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7590 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7591 AllowedSubtags()
7595 * Callback function for 'INFO'->'PARA' to set extra information about the
7596 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7597 * the parameter number as id. The first parameter has id 0. The maximum
7598 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7600 static bool HandleParameterInfo(ByteReader *buf)
7602 for (;;) {
7603 byte type = buf->ReadByte();
7604 if (type == 0) break;
7606 uint32 id = buf->ReadDWord();
7607 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7608 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7609 if (!SkipUnknownInfo(buf, type)) return false;
7610 continue;
7613 if (id >= _cur.grfconfig->param_info.Length()) {
7614 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7615 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7616 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7618 if (_cur.grfconfig->param_info[id] == NULL) {
7619 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7621 _cur_parameter = _cur.grfconfig->param_info[id];
7622 /* Read all parameter-data and process each node. */
7623 if (!HandleNodes(buf, _tags_parameters)) return false;
7625 return true;
7628 /** Action14 tags for the INFO node */
7629 static const AllowedSubtags _tags_info[] = {
7630 AllowedSubtags('NAME', ChangeGRFName),
7631 AllowedSubtags('DESC', ChangeGRFDescription),
7632 AllowedSubtags('URL_', ChangeGRFURL),
7633 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7634 AllowedSubtags('PALS', ChangeGRFPalette),
7635 AllowedSubtags('BLTR', ChangeGRFBlitter),
7636 AllowedSubtags('VRSN', ChangeGRFVersion),
7637 AllowedSubtags('MINV', ChangeGRFMinVersion),
7638 AllowedSubtags('PARA', HandleParameterInfo),
7639 AllowedSubtags()
7642 /** Action14 root tags */
7643 static const AllowedSubtags _tags_root[] = {
7644 AllowedSubtags('INFO', _tags_info),
7645 AllowedSubtags()
7650 * Try to skip the current node and all subnodes (if it's a branch node).
7651 * @param buf Buffer.
7652 * @param type The node type to skip.
7653 * @return True if we could skip the node, false if an error occurred.
7655 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7657 /* type and id are already read */
7658 switch (type) {
7659 case 'C':
7660 for (;;) {
7661 byte new_type = buf->ReadByte();
7662 if (new_type == 0) break;
7663 buf->ReadDWord(); // skip the id
7664 if (!SkipUnknownInfo(buf, new_type)) return false;
7666 break;
7668 case 'T':
7669 buf->ReadByte(); // lang
7670 buf->ReadString(); // actual text
7671 break;
7673 case 'B': {
7674 uint16 size = buf->ReadWord();
7675 buf->Skip(size);
7676 break;
7679 default:
7680 return false;
7683 return true;
7687 * Handle the nodes of an Action14
7688 * @param type Type of node.
7689 * @param id ID.
7690 * @param buf Buffer.
7691 * @param subtags Allowed subtags.
7692 * @return Whether all tags could be handled.
7694 static bool HandleNode (byte type, uint32 id, ByteReader *buf, const AllowedSubtags *subtags)
7696 for (const AllowedSubtags *tag = subtags; tag->type != 0; tag++) {
7697 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7698 switch (type) {
7699 default: NOT_REACHED();
7701 case 'T': {
7702 byte langid = buf->ReadByte();
7703 return tag->text (langid, buf->ReadString());
7706 case 'B': {
7707 size_t len = buf->ReadWord();
7708 if (!buf->HasData (len)) return false;
7709 return tag->data (len, buf);
7712 case 'C': {
7713 if (tag->nsub == 0) {
7714 return tag->branch (buf);
7716 return HandleNodes (buf, tag->subtags);
7720 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7721 return SkipUnknownInfo(buf, type);
7725 * Handle the contents of a 'C' choice of an Action14
7726 * @param buf Buffer.
7727 * @param subtags List of subtags.
7728 * @return Whether the nodes could all be handled.
7730 static bool HandleNodes (ByteReader *buf, const AllowedSubtags *subtags)
7732 for (;;) {
7733 byte type = buf->ReadByte();
7734 if (type == 0) break;
7735 uint32 id = buf->ReadDWord();
7736 if (!HandleNode(type, id, buf, subtags)) return false;
7738 return true;
7742 * Handle Action 0x14
7743 * @param buf Buffer.
7745 static int StaticGRFInfo (ByteReader *buf)
7747 /* <14> <type> <id> <text/data...> */
7748 HandleNodes(buf, _tags_root);
7749 return 0;
7753 * Set the current NewGRF as unsafe for static use
7754 * @param buf Unused.
7755 * @note Used during safety scan on unsafe actions.
7757 static int GRFUnsafe (ByteReader *buf)
7759 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7761 /* Skip remainder of GRF */
7762 return -1;
7766 /** Initialize the TTDPatch flags */
7767 static void InitializeGRFSpecial()
7769 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7770 | (1 << 0x0D) // newairports
7771 | (1 << 0x0E) // largestations
7772 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7773 | (0 << 0x10) // loadtime
7774 | (1 << 0x12) // presignals
7775 | (1 << 0x13) // extpresignals
7776 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7777 | (1 << 0x1B) // multihead
7778 | (1 << 0x1D) // lowmemory
7779 | (1 << 0x1E); // generalfixes
7781 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7782 | (1 << 0x08) // mammothtrains
7783 | (1 << 0x09) // trainrefit
7784 | (0 << 0x0B) // subsidiaries
7785 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7786 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7787 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7788 | (1 << 0x14) // bridgespeedlimits
7789 | (1 << 0x16) // eternalgame
7790 | (1 << 0x17) // newtrains
7791 | (1 << 0x18) // newrvs
7792 | (1 << 0x19) // newships
7793 | (1 << 0x1A) // newplanes
7794 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7795 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7797 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7798 | (1 << 0x03) // semaphores
7799 | (1 << 0x0A) // newobjects
7800 | (0 << 0x0B) // enhancedgui
7801 | (0 << 0x0C) // newagerating
7802 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7803 | (1 << 0x0E) // fullloadany
7804 | (1 << 0x0F) // planespeed
7805 | (0 << 0x10) // moreindustriesperclimate - obsolete
7806 | (0 << 0x11) // moretoylandfeatures
7807 | (1 << 0x12) // newstations
7808 | (1 << 0x13) // tracktypecostdiff
7809 | (1 << 0x14) // manualconvert
7810 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7811 | (1 << 0x16) // canals
7812 | (1 << 0x17) // newstartyear
7813 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7814 | (1 << 0x19) // newhouses
7815 | (1 << 0x1A) // newbridges
7816 | (1 << 0x1B) // newtownnames
7817 | (1 << 0x1C) // moreanimation
7818 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7819 | (1 << 0x1E) // newshistory
7820 | (0 << 0x1F); // custombridgeheads
7822 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7823 | (1 << 0x01) // windowsnap
7824 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7825 | (1 << 0x03) // pathbasedsignalling
7826 | (0 << 0x04) // aichoosechance
7827 | (1 << 0x05) // resolutionwidth
7828 | (1 << 0x06) // resolutionheight
7829 | (1 << 0x07) // newindustries
7830 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7831 | (0 << 0x09) // townroadbranchprob
7832 | (0 << 0x0A) // tempsnowline
7833 | (1 << 0x0B) // newcargo
7834 | (1 << 0x0C) // enhancemultiplayer
7835 | (1 << 0x0D) // onewayroads
7836 | (1 << 0x0E) // irregularstations
7837 | (1 << 0x0F) // statistics
7838 | (1 << 0x10) // newsounds
7839 | (1 << 0x11) // autoreplace
7840 | (1 << 0x12) // autoslope
7841 | (0 << 0x13) // followvehicle
7842 | (1 << 0x14) // trams
7843 | (0 << 0x15) // enhancetunnels
7844 | (1 << 0x16) // shortrvs
7845 | (1 << 0x17) // articulatedrvs
7846 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7847 | (1 << 0x1E) // variablerunningcosts
7848 | (1 << 0x1F); // any switch is on
7851 /** Reset and clear all NewGRF stations */
7852 static void ResetCustomStations()
7854 const GRFFile * const *end = _grf_files.End();
7855 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7856 StationSpec **&stations = (*file)->stations;
7857 if (stations == NULL) continue;
7858 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7859 if (stations[i] == NULL) continue;
7860 StationSpec *statspec = stations[i];
7862 delete[] statspec->renderdata;
7864 /* Release platforms and layouts */
7865 if (!statspec->copied_layouts) {
7866 for (uint l = 0; l < statspec->lengths; l++) {
7867 for (uint p = 0; p < statspec->platforms[l]; p++) {
7868 free(statspec->layouts[l][p]);
7870 free(statspec->layouts[l]);
7872 free(statspec->layouts);
7873 free(statspec->platforms);
7876 /* Release this station */
7877 free(statspec);
7880 /* Free and reset the station data */
7881 free(stations);
7882 stations = NULL;
7886 /** Reset and clear all NewGRF houses */
7887 static void ResetCustomHouses()
7889 const GRFFile * const *end = _grf_files.End();
7890 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7891 HouseSpec **&housespec = (*file)->housespec;
7892 if (housespec == NULL) continue;
7893 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7894 free(housespec[i]);
7897 free(housespec);
7898 housespec = NULL;
7902 /** Reset and clear all NewGRF airports */
7903 static void ResetCustomAirports()
7905 const GRFFile * const *end = _grf_files.End();
7906 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7907 AirportSpec **aslist = (*file)->airportspec;
7908 if (aslist != NULL) {
7909 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7910 AirportSpec *as = aslist[i];
7912 if (as != NULL) {
7913 /* We need to remove the tiles layouts */
7914 for (int j = 0; j < as->num_table; j++) {
7915 /* remove the individual layouts */
7916 free(as->table[j]);
7918 free(as->table);
7919 free(as->depot_table);
7921 free(as);
7924 free(aslist);
7925 (*file)->airportspec = NULL;
7928 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7929 if (airporttilespec != NULL) {
7930 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7931 free(airporttilespec[i]);
7933 free(airporttilespec);
7934 airporttilespec = NULL;
7939 /** Reset and clear all NewGRF industries */
7940 static void ResetCustomIndustries()
7942 const GRFFile * const *end = _grf_files.End();
7943 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7944 IndustrySpec **&industryspec = (*file)->industryspec;
7945 IndustryTileSpec **&indtspec = (*file)->indtspec;
7947 /* We are verifiying both tiles and industries specs loaded from the grf file
7948 * First, let's deal with industryspec */
7949 if (industryspec != NULL) {
7950 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7951 IndustrySpec *ind = industryspec[i];
7952 if (ind == NULL) continue;
7954 /* We need to remove the sounds array */
7955 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7956 free(ind->random_sounds);
7959 /* We need to remove the tiles layouts */
7960 CleanIndustryTileTable(ind);
7962 free(ind);
7965 free(industryspec);
7966 industryspec = NULL;
7969 if (indtspec == NULL) continue;
7970 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
7971 free(indtspec[i]);
7974 free(indtspec);
7975 indtspec = NULL;
7979 /** Reset and clear all NewObjects */
7980 static void ResetCustomObjects()
7982 const GRFFile * const *end = _grf_files.End();
7983 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7984 ObjectSpec **&objectspec = (*file)->objectspec;
7985 if (objectspec == NULL) continue;
7986 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
7987 free(objectspec[i]);
7990 free(objectspec);
7991 objectspec = NULL;
7995 /** Reset and clear all NewGRFs */
7996 static void ResetNewGRF()
7998 const GRFFile * const *end = _grf_files.End();
7999 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8000 delete *file;
8003 _grf_files.Clear();
8004 _cur.grffile = NULL;
8007 /** Clear all NewGRF errors */
8008 static void ResetNewGRFErrors()
8010 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8011 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8012 delete c->error;
8013 c->error = NULL;
8019 * Reset all NewGRF loaded data
8020 * TODO
8022 void ResetNewGRFData()
8024 CleanUpStrings();
8025 CleanUpGRFTownNames();
8027 /* Copy/reset original engine info data */
8028 SetupEngines();
8030 /* Copy/reset original bridge info data */
8031 ResetBridges();
8033 /* Reset rail type information */
8034 ResetRailTypes();
8036 /* Allocate temporary refit/cargo class data */
8037 _gted = xcalloct<GRFTempEngineData>(Engine::GetPoolSize());
8039 /* Fill rail type label temporary data for default trains */
8040 Engine *e;
8041 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8042 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8045 /* Reset GRM reservations */
8046 memset(&_grm_engines, 0, sizeof(_grm_engines));
8047 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8049 /* Reset generic feature callback lists */
8050 ResetGenericCallbacks();
8052 /* Reset price base data */
8053 ResetPriceBaseMultipliers();
8055 /* Reset the curencies array */
8056 ResetCurrencies();
8058 /* Reset the house array */
8059 ResetCustomHouses();
8060 ResetHouses();
8062 /* Reset the industries structures*/
8063 ResetCustomIndustries();
8064 ResetIndustries();
8066 /* Reset the objects. */
8067 ObjectClass::Reset();
8068 ResetCustomObjects();
8069 ResetObjects();
8071 /* Reset station classes */
8072 StationClass::Reset();
8073 ResetCustomStations();
8075 /* Reset airport-related structures */
8076 AirportClass::Reset();
8077 ResetCustomAirports();
8078 AirportSpec::ResetAirports();
8079 AirportTileSpec::ResetAirportTiles();
8081 /* Reset canal sprite groups and flags */
8082 memset(_water_feature, 0, sizeof(_water_feature));
8084 /* Reset the snowline table. */
8085 ClearSnowLine();
8087 /* Reset NewGRF files */
8088 ResetNewGRF();
8090 /* Reset NewGRF errors. */
8091 ResetNewGRFErrors();
8093 /* Set up the default cargo types */
8094 SetupCargoForClimate(_settings_game.game_creation.landscape);
8096 /* Reset misc GRF features and train list display variables */
8097 _misc_grf_features = 0;
8099 _loaded_newgrf_features.has_2CC = false;
8100 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8101 _loaded_newgrf_features.has_newhouses = false;
8102 _loaded_newgrf_features.has_newindustries = false;
8103 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8105 /* Clear all GRF overrides */
8106 _grf_id_overrides.clear();
8108 InitializeSoundPool();
8109 SpriteGroup::clear();
8113 * Reset NewGRF data which is stored persistently in savegames.
8115 void ResetPersistentNewGRFData()
8117 /* Reset override managers */
8118 _engine_mngr.ResetToDefaultMapping();
8119 _house_mngr.ResetMapping();
8120 _industry_mngr.ResetMapping();
8121 _industile_mngr.ResetMapping();
8122 _airport_mngr.ResetMapping();
8123 _airporttile_mngr.ResetMapping();
8127 * Construct the Cargo Mapping
8128 * @note This is the reverse of a cargo translation table
8130 static void BuildCargoTranslationMap()
8132 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8134 for (CargoID c = 0; c < NUM_CARGO; c++) {
8135 const CargoSpec *cs = CargoSpec::Get(c);
8136 if (!cs->IsValid()) continue;
8138 if (_cur.grffile->cargo_list.Length() == 0) {
8139 /* Default translation table, so just a straight mapping to bitnum */
8140 _cur.grffile->cargo_map[c] = cs->bitnum;
8141 } else {
8142 /* Check the translation table for this cargo's label */
8143 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8144 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8150 * Constructor for GRFFile
8151 * @param config GRFConfig to copy name, grfid and parameters from.
8153 GRFFile::GRFFile(const GRFConfig *config)
8155 this->filename = xstrdup(config->filename);
8156 this->grfid = config->ident.grfid;
8158 /* Initialise local settings to defaults */
8159 this->traininfo_vehicle_pitch = 0;
8160 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8162 /* Mark price_base_multipliers as 'not set' */
8163 for (Price i = PR_BEGIN; i < PR_END; i++) {
8164 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8167 /* Initialise rail type map with default rail types */
8168 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8169 this->railtype_map[0] = RAILTYPE_RAIL;
8170 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8171 this->railtype_map[2] = RAILTYPE_MONO;
8172 this->railtype_map[3] = RAILTYPE_MAGLEV;
8174 /* Copy the initial parameter list
8175 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8176 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8178 assert(config->num_params <= lengthof(config->param));
8179 this->param_end = config->num_params;
8180 if (this->param_end > 0) {
8181 MemCpyT(this->param, config->param, this->param_end);
8185 GRFFile::~GRFFile()
8187 free(this->filename);
8188 delete[] this->language_map;
8193 * List of what cargo labels are refittable for the given the vehicle-type.
8194 * Only currently active labels are applied.
8196 static const CargoLabel _default_refitmasks_rail[] = {
8197 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8198 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8199 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8200 'PLST', 'FZDR',
8201 0 };
8203 static const CargoLabel _default_refitmasks_road[] = {
8204 0 };
8206 static const CargoLabel _default_refitmasks_ships[] = {
8207 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8208 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8209 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8210 'PLST', 'FZDR',
8211 0 };
8213 static const CargoLabel _default_refitmasks_aircraft[] = {
8214 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8215 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8216 0 };
8218 static const CargoLabel * const _default_refitmasks[] = {
8219 _default_refitmasks_rail,
8220 _default_refitmasks_road,
8221 _default_refitmasks_ships,
8222 _default_refitmasks_aircraft,
8227 * Precalculate refit masks from cargo classes for all vehicles.
8229 static void CalculateRefitMasks()
8231 Engine *e;
8233 FOR_ALL_ENGINES(e) {
8234 EngineID engine = e->index;
8235 EngineInfo *ei = &e->info;
8236 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8238 /* Did the newgrf specify any refitting? If not, use defaults. */
8239 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8240 uint32 mask = 0;
8241 uint32 not_mask = 0;
8242 uint32 xor_mask = ei->refit_mask;
8244 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8245 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8246 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8248 if (_gted[engine].cargo_allowed != 0) {
8249 /* Build up the list of cargo types from the set cargo classes. */
8250 const CargoSpec *cs;
8251 FOR_ALL_CARGOSPECS(cs) {
8252 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8253 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8257 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8259 /* Apply explicit refit includes/excludes. */
8260 ei->refit_mask |= _gted[engine].ctt_include_mask;
8261 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8262 } else {
8263 uint32 xor_mask = 0;
8265 /* Don't apply default refit mask to wagons nor engines with no capacity */
8266 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8267 const CargoLabel *cl = _default_refitmasks[e->type];
8268 for (uint i = 0;; i++) {
8269 if (cl[i] == 0) break;
8271 CargoID cargo = GetCargoIDByLabel(cl[i]);
8272 if (cargo == CT_INVALID) continue;
8274 SetBit(xor_mask, cargo);
8278 ei->refit_mask = xor_mask & _cargo_mask;
8280 /* If the mask is zero, the vehicle shall only carry the default cargo */
8281 only_defaultcargo = (ei->refit_mask == 0);
8284 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8285 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8287 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8288 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8289 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8290 ei->cargo_type = CT_INVALID;
8293 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8294 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8295 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8296 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8297 const uint8 *cargo_map_for_first_refittable = NULL;
8299 const GRFFile *file = _gted[engine].defaultcargo_grf;
8300 if (file == NULL) file = e->GetGRF();
8301 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8302 cargo_map_for_first_refittable = file->cargo_map;
8306 if (cargo_map_for_first_refittable != NULL) {
8307 /* Use first refittable cargo from cargo translation table */
8308 byte best_local_slot = 0xFF;
8309 CargoID cargo_type;
8310 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8311 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8312 if (local_slot < best_local_slot) {
8313 best_local_slot = local_slot;
8314 ei->cargo_type = cargo_type;
8319 if (ei->cargo_type == CT_INVALID) {
8320 /* Use first refittable cargo slot */
8321 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8324 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8326 /* Clear refit_mask for not refittable ships */
8327 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8328 ei->refit_mask = 0;
8333 /** Set to use the correct action0 properties for each canal feature */
8334 static void FinaliseCanals()
8336 for (uint i = 0; i < CF_END; i++) {
8337 if (_water_feature[i].grffile != NULL) {
8338 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8339 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8344 /** Check for invalid engines */
8345 static void FinaliseEngineArray()
8347 Engine *e;
8349 FOR_ALL_ENGINES(e) {
8350 if (e->GetGRF() == NULL) {
8351 const EngineIDMapping &eid = _engine_mngr[e->index];
8352 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8353 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8357 /* When the train does not set property 27 (misc flags), but it
8358 * is overridden by a NewGRF graphically we want to disable the
8359 * flipping possibility. */
8360 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8361 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8364 /* Skip wagons, there livery is defined via the engine */
8365 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8366 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8367 SetBit(_loaded_newgrf_features.used_liveries, ls);
8368 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8370 if (e->type == VEH_TRAIN) {
8371 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8372 switch (ls) {
8373 case LS_STEAM:
8374 case LS_DIESEL:
8375 case LS_ELECTRIC:
8376 case LS_MONORAIL:
8377 case LS_MAGLEV:
8378 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8379 break;
8381 case LS_DMU:
8382 case LS_EMU:
8383 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8384 break;
8386 default: NOT_REACHED();
8393 /** Check for invalid cargoes */
8394 static void FinaliseCargoArray()
8396 for (CargoID c = 0; c < NUM_CARGO; c++) {
8397 CargoSpec *cs = CargoSpec::Get(c);
8398 if (!cs->IsValid()) {
8399 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8400 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8401 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8407 * Check if a given housespec is valid and disable it if it's not.
8408 * The housespecs that follow it are used to check the validity of
8409 * multitile houses.
8410 * @param hs The housespec to check.
8411 * @param next1 The housespec that follows \c hs.
8412 * @param next2 The housespec that follows \c next1.
8413 * @param next3 The housespec that follows \c next2.
8414 * @param filename The filename of the newgrf this house was defined in.
8415 * @return Whether the given housespec is valid.
8417 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8419 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8420 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8421 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8422 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8423 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8424 hs->enabled = false;
8425 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);
8426 return false;
8429 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8430 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8431 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8432 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8433 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8434 hs->enabled = false;
8435 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);
8436 return false;
8439 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8440 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8441 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8442 hs->enabled = false;
8443 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);
8444 return false;
8447 /* Make sure that additional parts of multitile houses are not available. */
8448 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8449 hs->enabled = false;
8450 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);
8451 return false;
8454 return true;
8458 * Make sure there is at least one house available in the year 0 for the given
8459 * climate.
8460 * @param bitmask The climate to check for. Exactly one climate bit should be
8461 * set.
8463 static void EnsureEarlyHouses (HouseZones climate_mask)
8465 for (uint z = 0; z < HZB_END; z++) {
8466 HouseZones bitmask = (HouseZones)(1U << z) | climate_mask;
8467 Year min_year = MAX_YEAR;
8469 for (int i = 0; i < NUM_HOUSES; i++) {
8470 const HouseSpec *hs = HouseSpec::Get(i);
8471 if (hs == NULL || !hs->enabled) continue;
8472 if ((hs->building_availability & bitmask) != bitmask) continue;
8473 if (hs->min_year < min_year) min_year = hs->min_year;
8476 if (min_year == 0) continue;
8478 for (int i = 0; i < NUM_HOUSES; i++) {
8479 HouseSpec *hs = HouseSpec::Get(i);
8480 if (hs == NULL || !hs->enabled) continue;
8481 if ((hs->building_availability & bitmask) != bitmask) continue;
8482 if (hs->min_year == min_year) hs->min_year = 0;
8488 * Add all new houses to the house array. House properties can be set at any
8489 * time in the GRF file, so we can only add a house spec to the house array
8490 * after the file has finished loading. We also need to check the dates, due to
8491 * the TTDPatch behaviour described below that we need to emulate.
8493 static void FinaliseHouseArray()
8495 /* If there are no houses with start dates before 1930, then all houses
8496 * with start dates of 1930 have them reset to 0. This is in order to be
8497 * compatible with TTDPatch, where if no houses have start dates before
8498 * 1930 and the date is before 1930, the game pretends that this is 1930.
8499 * If there have been any houses defined with start dates before 1930 then
8500 * the dates are left alone.
8501 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8502 * minimum introduction date to 0.
8504 const GRFFile * const *end = _grf_files.End();
8505 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8506 HouseSpec **&housespec = (*file)->housespec;
8507 if (housespec == NULL) continue;
8509 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8510 HouseSpec *hs = housespec[i];
8512 if (hs == NULL) continue;
8514 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8515 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8516 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8518 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8520 _house_mngr.SetEntitySpec(hs);
8524 for (int i = 0; i < NUM_HOUSES; i++) {
8525 HouseSpec *hs = HouseSpec::Get(i);
8526 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8527 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8528 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8530 /* We need to check all houses again to we are sure that multitile houses
8531 * did get consecutive IDs and none of the parts are missing. */
8532 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8533 /* GetHouseNorthPart checks 3 houses that are directly before
8534 * it in the house pool. If any of those houses have multi-tile
8535 * flags set it assumes it's part of a multitile house. Since
8536 * we can have invalid houses in the pool marked as disabled, we
8537 * don't want to have them influencing valid tiles. As such set
8538 * building_flags to zero here to make sure any house following
8539 * this one in the pool is properly handled as 1x1 house. */
8540 hs->building_flags = TILE_NO_FLAG;
8544 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8545 EnsureEarlyHouses (climate_mask);
8547 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8548 EnsureEarlyHouses (HZ_SUBARTC_ABOVE);
8553 * Add all new industries to the industry array. Industry properties can be set at any
8554 * time in the GRF file, so we can only add a industry spec to the industry array
8555 * after the file has finished loading.
8557 static void FinaliseIndustriesArray()
8559 const GRFFile * const *end = _grf_files.End();
8560 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8561 IndustrySpec **&industryspec = (*file)->industryspec;
8562 IndustryTileSpec **&indtspec = (*file)->indtspec;
8563 if (industryspec != NULL) {
8564 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8565 IndustrySpec *indsp = industryspec[i];
8567 if (indsp != NULL && indsp->enabled) {
8568 StringID strid;
8569 /* process the conversion of text at the end, so to be sure everything will be fine
8570 * and available. Check if it does not return undefind marker, which is a very good sign of a
8571 * substitute industry who has not changed the string been examined, thus using it as such */
8572 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8573 if (strid != STR_UNDEFINED) indsp->name = strid;
8575 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8576 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8578 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8579 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8581 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8582 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8584 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8585 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8587 if (indsp->station_name != STR_NULL) {
8588 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8589 * station's name. Don't want to lose the value, therefore, do not process. */
8590 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8591 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8594 _industry_mngr.SetEntitySpec(indsp);
8595 _loaded_newgrf_features.has_newindustries = true;
8600 if (indtspec != NULL) {
8601 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8602 IndustryTileSpec *indtsp = indtspec[i];
8603 if (indtsp != NULL) {
8604 _industile_mngr.SetEntitySpec(indtsp);
8610 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8611 IndustrySpec *indsp = &_industry_specs[j];
8612 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8613 for (uint i = 0; i < 3; i++) {
8614 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8617 if (!indsp->enabled) {
8618 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8624 * Add all new objects to the object array. Object properties can be set at any
8625 * time in the GRF file, so we can only add an object spec to the object array
8626 * after the file has finished loading.
8628 static void FinaliseObjectsArray()
8630 const GRFFile * const *end = _grf_files.End();
8631 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8632 ObjectSpec **&objectspec = (*file)->objectspec;
8633 if (objectspec != NULL) {
8634 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8635 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8636 _object_mngr.SetEntitySpec(objectspec[i]);
8644 * Add all new airports to the airport array. Airport properties can be set at any
8645 * time in the GRF file, so we can only add a airport spec to the airport array
8646 * after the file has finished loading.
8648 static void FinaliseAirportsArray()
8650 const GRFFile * const *end = _grf_files.End();
8651 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8652 AirportSpec **&airportspec = (*file)->airportspec;
8653 if (airportspec != NULL) {
8654 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8655 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8656 _airport_mngr.SetEntitySpec(airportspec[i]);
8661 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8662 if (airporttilespec != NULL) {
8663 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8664 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8665 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8672 /* Here we perform initial decoding of some special sprites (as are they
8673 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8674 * partial implementation yet).
8675 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8676 * a crafted invalid GRF file. We should tell that to the user somehow, or
8677 * better make this more robust in the future. */
8678 static int DecodeSpecialSprite (byte *buf, uint num, GrfLoadingStage stage)
8680 /* XXX: There is a difference between staged loading in TTDPatch and
8681 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8682 * during stage 1, whilst action 3 is carried out during stage 2 (to
8683 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8684 * IDs are valid only within a given set (action 1) block, and may be
8685 * overwritten after action 3 associates them. But overwriting happens
8686 * in an earlier stage than associating, so... We just process actions
8687 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8688 * --pasky
8689 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8690 * is not in memory and scanning the file every time would be too expensive.
8691 * In other stages we skip action 0x10 since it's already dealt with. */
8692 static const SpecialSpriteHandler handlers[][GLS_END] = {
8693 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8694 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8695 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8696 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8697 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8698 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8699 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8700 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8701 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8702 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8703 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8704 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8705 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8706 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8707 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8708 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8709 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8710 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8711 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8712 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8713 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8716 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8718 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8719 if (it == _grf_line_to_action6_sprite_override.end()) {
8720 /* No preloaded sprite to work with; read the
8721 * pseudo sprite content. */
8722 FioReadBlock(buf, num);
8723 } else {
8724 /* Use the preloaded sprite data. */
8725 buf = it->second.get();
8726 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8728 /* Skip the real (original) content of this action. */
8729 FioSeekTo(num, SEEK_CUR);
8732 ByteReader br(buf, buf + num);
8733 ByteReader *bufp = &br;
8735 try {
8736 byte action = bufp->ReadByte();
8738 if (action == 0xFF) {
8739 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8740 } else if (action == 0xFE) {
8741 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8742 } else if (action >= lengthof(handlers)) {
8743 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8744 } else if (handlers[action][stage] == NULL) {
8745 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8746 } else {
8747 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8748 return handlers[action][stage](bufp);
8750 } catch (...) {
8751 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8752 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS);
8753 return -1;
8756 return 0;
8760 /** Signature of a container version 2 GRF. */
8761 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8764 * Get the container version of the currently opened GRF file.
8765 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8767 byte GetGRFContainerVersion()
8769 size_t pos = FioGetPos();
8771 if (FioReadWord() == 0) {
8772 /* Check for GRF container version 2, which is identified by the bytes
8773 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8774 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8775 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8778 return 2;
8781 /* Container version 1 has no header, rewind to start. */
8782 FioSeekTo(pos, SEEK_SET);
8783 return 1;
8787 * Load a particular NewGRF.
8788 * @param config The configuration of the to be loaded NewGRF.
8789 * @param file_index The Fio index of the first NewGRF to load.
8790 * @param stage The loading stage of the NewGRF.
8791 * @param subdir The sub directory to find the NewGRF in.
8793 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8795 assert (file_index < MAX_FILE_SLOTS);
8797 const char *filename = config->filename;
8799 FioOpenFile(file_index, filename, subdir);
8800 _cur.file_index = file_index; // XXX
8801 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8803 _cur.grfconfig = config;
8805 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8807 _cur.grf_container_ver = GetGRFContainerVersion();
8808 if (_cur.grf_container_ver == 0) {
8809 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8810 return;
8813 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8814 /* We need the sprite offsets in the init stage for NewGRF sounds
8815 * and in the activation stage for real sprites. */
8816 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8817 } else {
8818 /* Skip sprite section offset if present. */
8819 if (_cur.grf_container_ver >= 2) FioReadDword();
8822 if (_cur.grf_container_ver >= 2) {
8823 /* Read compression value. */
8824 byte compression = FioReadByte();
8825 if (compression != 0) {
8826 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8827 return;
8831 /* Skip the first sprite; we don't care about how many sprites this
8832 * does contain; newest TTDPatches and George's longvehicles don't
8833 * neither, apparently. */
8834 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8835 if (num == 4 && FioReadByte() == 0xFF) {
8836 FioReadDword();
8837 } else {
8838 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8839 return;
8842 _cur.ClearDataForNextFile();
8844 ReusableBuffer<byte> buf;
8845 int skip_sprites = 0;
8847 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8848 byte type = FioReadByte();
8849 _cur.nfo_line++;
8851 if (type == 0xFF) {
8852 if (skip_sprites == 0) {
8853 skip_sprites = DecodeSpecialSprite (buf.Allocate(num), num, stage);
8855 /* Stop all processing if we are to skip the remaining sprites */
8856 if (skip_sprites == -1) break;
8858 continue;
8859 } else {
8860 FioSkipBytes(num);
8862 } else {
8863 if (skip_sprites == 0) {
8864 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8865 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8866 break;
8869 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8870 /* Reference to data section. Container version >= 2 only. */
8871 FioSkipBytes(num);
8872 } else {
8873 FioSkipBytes(7);
8874 SkipSpriteData(type, num - 8);
8878 if (skip_sprites > 0) skip_sprites--;
8883 * Relocates the old shore sprites at new positions.
8885 * 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)
8886 * 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)
8887 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8889 static void ActivateOldShore()
8891 /* Use default graphics, if no shore sprites were loaded.
8892 * Should not happen, as the base set's extra grf should include some. */
8893 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8895 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8896 for (uint i = 0; i < lengthof(shore_sprites_1); i++) {
8897 DupSprite (shore_sprites_1[i].old, shore_sprites_1[i].spr);
8901 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8902 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
8903 DupSprite (shore_sprites_2[i].old, shore_sprites_2[i].spr);
8909 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8911 static void FinalisePriceBaseMultipliers()
8913 extern const PriceBaseSpec _price_base_specs[];
8914 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8915 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8917 /* Evaluate grf overrides */
8918 int num_grfs = _grf_files.Length();
8919 int *grf_overrides = AllocaM(int, num_grfs);
8920 for (int i = 0; i < num_grfs; i++) {
8921 grf_overrides[i] = -1;
8923 GRFFile *source = _grf_files[i];
8924 uint32 override = _grf_id_overrides[source->grfid];
8925 if (override == 0) continue;
8927 GRFFile *dest = GetFileByGRFID(override);
8928 if (dest == NULL) continue;
8930 grf_overrides[i] = _grf_files.FindIndex(dest);
8931 assert(grf_overrides[i] >= 0);
8934 /* Override features and price base multipliers of earlier loaded grfs */
8935 for (int i = 0; i < num_grfs; i++) {
8936 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
8937 GRFFile *source = _grf_files[i];
8938 GRFFile *dest = _grf_files[grf_overrides[i]];
8940 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8941 source->grf_features |= features;
8942 dest->grf_features |= features;
8944 for (Price p = PR_BEGIN; p < PR_END; p++) {
8945 /* No price defined -> nothing to do */
8946 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
8947 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
8948 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8952 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
8953 for (int i = num_grfs - 1; i >= 0; i--) {
8954 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
8955 GRFFile *source = _grf_files[i];
8956 GRFFile *dest = _grf_files[grf_overrides[i]];
8958 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8959 source->grf_features |= features;
8960 dest->grf_features |= features;
8962 for (Price p = PR_BEGIN; p < PR_END; p++) {
8963 /* Already a price defined -> nothing to do */
8964 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
8965 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
8966 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8970 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
8971 for (int i = 0; i < num_grfs; i++) {
8972 if (grf_overrides[i] < 0) continue;
8973 GRFFile *source = _grf_files[i];
8974 GRFFile *dest = _grf_files[grf_overrides[i]];
8976 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8977 source->grf_features |= features;
8978 dest->grf_features |= features;
8980 for (Price p = PR_BEGIN; p < PR_END; p++) {
8981 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
8982 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
8983 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
8985 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
8989 /* Apply fallback prices for grf version < 8 */
8990 const GRFFile * const *end = _grf_files.End();
8991 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8992 if ((*file)->grf_version >= 8) continue;
8993 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
8994 for (Price p = PR_BEGIN; p < PR_END; p++) {
8995 Price fallback_price = _price_base_specs[p].fallback_price;
8996 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
8997 /* No price multiplier has been set.
8998 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
8999 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9004 /* Decide local/global scope of price base multipliers */
9005 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9006 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9007 for (Price p = PR_BEGIN; p < PR_END; p++) {
9008 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9009 /* No multiplier was set; set it to a neutral value */
9010 price_base_multipliers[p] = 0;
9011 } else {
9012 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9013 /* The grf does not define any objects of the feature,
9014 * so it must be a difficulty setting. Apply it globally */
9015 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9016 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9017 price_base_multipliers[p] = 0;
9018 } else {
9019 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9026 extern void InitGRFTownGeneratorNames();
9028 /** Finish loading NewGRFs and execute needed post-processing */
9029 static void AfterLoadGRFs()
9031 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9032 *it->target = MapGRFStringID(it->grfid, it->source);
9034 _string_to_grf_mapping.Clear();
9036 /* Free the action 6 override sprites. */
9037 _grf_line_to_action6_sprite_override.clear();
9039 /* Polish cargoes */
9040 FinaliseCargoArray();
9042 /* Pre-calculate all refit masks after loading GRF files. */
9043 CalculateRefitMasks();
9045 /* Polish engines */
9046 FinaliseEngineArray();
9048 /* Set the actually used Canal properties */
9049 FinaliseCanals();
9051 /* Add all new houses to the house array. */
9052 FinaliseHouseArray();
9054 /* Add all new industries to the industry array. */
9055 FinaliseIndustriesArray();
9057 /* Add all new objects to the object array. */
9058 FinaliseObjectsArray();
9060 InitializeSortedCargoSpecs();
9062 /* Sort the list of industry types. */
9063 SortIndustryTypes();
9065 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9066 BuildIndustriesLegend();
9068 /* Build the routemap legend, based on the available cargos */
9069 BuildLinkStatsLegend();
9071 /* Add all new airports to the airports array. */
9072 FinaliseAirportsArray();
9073 BindAirportSpecs();
9075 /* Update the townname generators list */
9076 InitGRFTownGeneratorNames();
9078 /* Run all queued vehicle list order changes */
9079 CommitVehicleListOrderChanges();
9081 /* Load old shore sprites in new position, if they were replaced by ActionA */
9082 ActivateOldShore();
9084 /* Set up custom rail types */
9085 InitRailTypes();
9087 Engine *e;
9088 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9089 if (_gted[e->index].rv_max_speed != 0) {
9090 /* Set RV maximum speed from the mph/0.8 unit value */
9091 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9095 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9096 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9097 if (railtype == INVALID_RAILTYPE) {
9098 /* Rail type is not available, so disable this engine */
9099 e->info.climates = 0;
9100 } else {
9101 e->u.rail.railtype = railtype;
9105 SetYearEngineAgingStops();
9107 FinalisePriceBaseMultipliers();
9109 /* Deallocate temporary loading data */
9110 free(_gted);
9111 _grm_sprites.clear();
9115 * Load all the NewGRFs.
9116 * @param load_index The offset for the first sprite to add.
9117 * @param file_index The Fio index of the first NewGRF to load.
9118 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9120 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9122 /* In case of networking we need to "sync" the start values
9123 * so all NewGRFs are loaded equally. For this we use the
9124 * start date of the game and we set the counters, etc. to
9125 * 0 so they're the same too. */
9126 Date date = _date;
9127 Year year = _cur_year;
9128 DateFract date_fract = _date_fract;
9129 uint16 tick_counter = _tick_counter;
9130 byte display_opt = _display_opt;
9132 if (_networking) {
9133 _cur_year = _settings_game.game_creation.starting_year;
9134 _date = ConvertYMDToDate(_cur_year, 0, 1);
9135 _date_fract = 0;
9136 _tick_counter = 0;
9137 _display_opt = 0;
9140 InitializeGRFSpecial();
9142 ResetNewGRFData();
9145 * Reset the status of all files, so we can 'retry' to load them.
9146 * This is needed when one for example rearranges the NewGRFs in-game
9147 * and a previously disabled NewGRF becomes useable. If it would not
9148 * be reset, the NewGRF would remain disabled even though it should
9149 * have been enabled.
9151 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9152 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9155 _cur.spriteid = load_index;
9157 /* Load newgrf sprites
9158 * in each loading stage, (try to) open each file specified in the config
9159 * and load information from it. */
9160 uint num_non_static = 0;
9161 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9162 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9163 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9164 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9165 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9168 if (stage == GLS_RESERVE) {
9169 static const uint32 overrides[][2] = {
9170 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9171 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9172 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9174 for (size_t i = 0; i < lengthof(overrides); i++) {
9175 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9179 uint slot = file_index;
9181 _cur.stage = stage;
9182 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9183 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9184 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9186 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9187 if (!FioCheckFileExists(c->filename, subdir)) {
9188 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9189 c->status = GCS_NOT_FOUND;
9190 continue;
9193 /* A .grf file is activated only if it was active
9194 * when the game was started. If a game is loaded,
9195 * only its active .grfs will be reactivated, unless
9196 * "loadallgraphics on" is used. A .grf file is
9197 * considered active if its action 8 has been
9198 * processed, i.e. its action 8 hasn't been skipped
9199 * using an action 7.
9201 * During activation, only actions 0, 1, 2, 3, 4, 5,
9202 * 7, 8, 9, 0A and 0B are carried out. All others
9203 * are ignored, because they only need to be
9204 * processed once at initialization. */
9206 _cur.grffile = GetFileByFilename (c->filename);
9207 if (stage == GLS_LABELSCAN) {
9208 if (_cur.grffile == NULL) {
9209 _cur.grffile = new GRFFile (c);
9210 *_grf_files.Append() = _cur.grffile;
9213 bool disable = false;
9214 if (slot == MAX_FILE_SLOTS) {
9215 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", c->filename);
9216 disable = true;
9217 } else if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9218 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9219 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9220 disable = true;
9221 } else {
9222 num_non_static++;
9225 if (disable) {
9226 c->status = GCS_DISABLED;
9227 c->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9228 continue;
9230 } else {
9231 if (_cur.grffile == NULL) usererror ("File '%s' lost in cache.\n", c->filename);
9232 if (stage == GLS_RESERVE && c->status != GCS_INITIALISED) return;
9233 if (stage == GLS_ACTIVATION && !HasBit(c->flags, GCF_RESERVED)) return;
9236 assert (slot < MAX_FILE_SLOTS);
9238 LoadNewGRFFile(c, slot++, stage, subdir);
9239 if (stage == GLS_RESERVE) {
9240 SetBit(c->flags, GCF_RESERVED);
9241 } else if (stage == GLS_ACTIVATION) {
9242 ClrBit(c->flags, GCF_RESERVED);
9243 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9244 ClearTemporaryNewGRFData(_cur.grffile);
9245 BuildCargoTranslationMap();
9246 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9247 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9248 /* We're not going to activate this, so free whatever data we allocated */
9249 ClearTemporaryNewGRFData(_cur.grffile);
9254 /* Pseudo sprite processing is finished; free temporary stuff */
9255 _cur.ClearDataForNextFile();
9257 /* Call any functions that should be run after GRFs have been loaded. */
9258 AfterLoadGRFs();
9260 /* Now revert back to the original situation */
9261 _cur_year = year;
9262 _date = date;
9263 _date_fract = date_fract;
9264 _tick_counter = tick_counter;
9265 _display_opt = display_opt;