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/>.
10 /** @file newgrf.cpp Base of all NewGRF support. */
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
46 #include "smallmap_gui.h"
49 #include "vehicle_func.h"
51 #include "vehicle_base.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 #include "safeguards.h"
58 /* TTDPatch extended GRF format codec
59 * (c) Petr Baudis 2004 (GPL'd)
60 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
62 * Contains portions of documentation by TTDPatch team.
63 * Thanks especially to Josef Drexler for the documentation as well as a lot
64 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
65 * served as subject to the initial testing of this codec. */
67 /** List of all loaded GRF files */
68 static SmallVector
<GRFFile
*, 16> _grf_files
;
70 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
71 byte _misc_grf_features
= 0;
73 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
74 static uint32 _ttdpatch_flags
[8];
76 /** Indicates which are the newgrf features currently loaded ingame */
77 GRFLoadedFeatures _loaded_newgrf_features
;
79 static const uint MAX_SPRITEGROUP
= UINT8_MAX
; ///< Maximum GRF-local ID for a spritegroup.
81 /** Temporary data during loading of GRFs */
82 struct GrfProcessingState
{
84 /** Definition of a single Action1 spriteset */
86 SpriteID sprite
; ///< SpriteID of the first sprite of the set.
87 uint num_sprites
; ///< Number of sprites in the set.
90 /** Currently referenceable spritesets */
91 std::map
<uint
, SpriteSet
> spritesets
[GSF_END
];
95 GrfLoadingStage stage
; ///< Current loading stage
96 SpriteID spriteid
; ///< First available SpriteID for loading realsprites.
98 /* Local state in the file */
99 uint file_index
; ///< File index of currently processed GRF file.
100 GRFFile
*grffile
; ///< Currently processed GRF file.
101 GRFConfig
*grfconfig
; ///< Config of the currently processed GRF file.
102 uint32 nfo_line
; ///< Currently processed pseudo sprite number in the GRF.
103 byte grf_container_ver
; ///< Container format of the current GRF file.
105 /* Kind of return values when processing certain actions */
106 int skip_sprites
; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
108 /* Currently referenceable spritegroups */
109 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
111 /** Clear temporary data before processing the next file in the current loading stage */
112 void ClearDataForNextFile()
115 this->skip_sprites
= 0;
117 for (uint i
= 0; i
< GSF_END
; i
++) {
118 this->spritesets
[i
].clear();
121 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
125 * Records new spritesets.
126 * @param feature GrfSpecFeature the set is defined for.
127 * @param first_sprite SpriteID of the first sprite in the set.
128 * @param first_set First spriteset to define.
129 * @param numsets Number of sets to define.
130 * @param numents Number of sprites per set to define.
132 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
134 assert(feature
< GSF_END
);
135 for (uint i
= 0; i
< numsets
; i
++) {
136 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
137 set
.sprite
= first_sprite
+ i
* numents
;
138 set
.num_sprites
= numents
;
143 * Check whether there are any valid spritesets for a feature.
144 * @param feature GrfSpecFeature to check.
145 * @return true if there are any valid sets.
146 * @note Spritesets with zero sprites are valid to allow callback-failures.
148 bool HasValidSpriteSets(byte feature
) const
150 assert(feature
< GSF_END
);
151 return !this->spritesets
[feature
].empty();
155 * Check whether a specific set is defined.
156 * @param feature GrfSpecFeature to check.
157 * @param set Set to check.
158 * @return true if the set is valid.
159 * @note Spritesets with zero sprites are valid to allow callback-failures.
161 bool IsValidSpriteSet(byte feature
, uint set
) const
163 assert(feature
< GSF_END
);
164 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
168 * Returns the first sprite of a spriteset.
169 * @param feature GrfSpecFeature to query.
170 * @param set Set to query.
171 * @return First sprite of the set.
173 SpriteID
GetSprite(byte feature
, uint set
) const
175 assert(IsValidSpriteSet(feature
, set
));
176 return this->spritesets
[feature
].find(set
)->second
.sprite
;
180 * Returns the number of sprites in a spriteset
181 * @param feature GrfSpecFeature to query.
182 * @param set Set to query.
183 * @return Number of sprites in the set.
185 uint
GetNumEnts(byte feature
, uint set
) const
187 assert(IsValidSpriteSet(feature
, set
));
188 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
192 static GrfProcessingState _cur
;
196 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
197 * @param <T> The type of vehicle.
198 * @param image_index The image index to check.
199 * @return True iff the image index is valid, or 0xFD (use new graphics).
201 template <VehicleType T
>
202 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
204 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
207 class OTTDByteReaderSignal
{ };
209 /** Class to read from a NewGRF file */
216 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
218 inline byte
ReadByte()
220 if (data
< end
) return *(data
)++;
221 throw OTTDByteReaderSignal();
226 uint16 val
= ReadByte();
227 return val
| (ReadByte() << 8);
230 uint16
ReadExtendedByte()
232 uint16 val
= ReadByte();
233 return val
== 0xFF ? ReadWord() : val
;
238 uint32 val
= ReadWord();
239 return val
| (ReadWord() << 16);
242 uint32
ReadVarSize(byte size
)
245 case 1: return ReadByte();
246 case 2: return ReadWord();
247 case 4: return ReadDWord();
254 const char *ReadString()
256 char *string
= reinterpret_cast<char *>(data
);
257 size_t string_length
= ttd_strnlen(string
, Remaining());
259 if (string_length
== Remaining()) {
260 /* String was not NUL terminated, so make sure it is now. */
261 string
[string_length
- 1] = '\0';
262 grfmsg(7, "String was not terminated with a zero byte.");
264 /* Increase the string length to include the NUL byte. */
272 inline size_t Remaining() const
277 inline bool HasData(size_t count
= 1) const
279 return data
+ count
<= end
;
287 inline void Skip(size_t len
)
290 /* It is valid to move the buffer to exactly the end of the data,
291 * as there may not be any more data read. */
292 if (data
> end
) throw OTTDByteReaderSignal();
296 typedef void (*SpecialSpriteHandler
)(ByteReader
*buf
);
298 static const uint NUM_STATIONS_PER_GRF
= 255; ///< Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on.
300 /** Temporary engine data used when loading only */
301 struct GRFTempEngineData
{
302 /** Summary state of refittability properties */
304 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
305 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
306 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
309 uint16 cargo_allowed
;
310 uint16 cargo_disallowed
;
311 RailTypeLabel railtypelabel
;
312 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
313 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
314 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
315 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
316 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
317 uint32 ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
320 * Update the summary refittability on setting a refittability property.
321 * @param non_empty true if the GRF sets the vehicle to be refittable.
323 void UpdateRefittability(bool non_empty
)
326 this->refittability
= NONEMPTY
;
327 } else if (this->refittability
== UNSET
) {
328 this->refittability
= EMPTY
;
333 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
336 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
337 * GRM for vehicles is only used if dynamic engine allocation is disabled,
338 * so 256 is the number of original engines. */
339 static uint32 _grm_engines
[256];
341 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
342 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
348 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
350 bool operator<(const GRFLocation
&other
) const
352 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
355 bool operator == (const GRFLocation
&other
) const
357 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
361 static std::map
<GRFLocation
, SpriteID
> _grm_sprites
;
362 typedef std::map
<GRFLocation
, byte
*> GRFLineToSpriteOverride
;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
366 * DEBUG() function dedicated to newGRF debugging messages
367 * Function is essentially the same as DEBUG(grf, severity, ...) with the
368 * addition of file:line information when parsing grf files.
369 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
370 * loading/parsing grf files, not for runtime debug messages as there
371 * is no file information available during that time.
372 * @param severity debugging severity level, see debug.h
373 * @param str message in printf() format
375 void CDECL
grfmsg(int severity
, const char *str
, ...)
381 vseprintf(buf
, lastof(buf
), str
, va
);
384 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
388 * Obtain a NewGRF file by its grfID
389 * @param grfid The grfID to obtain the file for
392 static GRFFile
*GetFileByGRFID(uint32 grfid
)
394 const GRFFile
* const *end
= _grf_files
.End();
395 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
396 if ((*file
)->grfid
== grfid
) return *file
;
402 * Obtain a NewGRF file by its filename
403 * @param filename The filename to obtain the file for.
406 static GRFFile
*GetFileByFilename(const char *filename
)
408 const GRFFile
* const *end
= _grf_files
.End();
409 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
410 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
415 /** Reset all NewGRFData that was used only while processing data */
416 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
418 /* Clear the GOTO labels used for GRF processing */
419 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
420 GRFLabel
*l2
= l
->next
;
429 * @param message Error message or STR_NULL.
430 * @param config GRFConfig to disable, NULL for current.
431 * @return Error message of the GRF for further customisation.
433 static GRFError
*DisableGrf(StringID message
= STR_NULL
, GRFConfig
*config
= NULL
)
436 if (config
!= NULL
) {
437 file
= GetFileByGRFID(config
->ident
.grfid
);
439 config
= _cur
.grfconfig
;
443 config
->status
= GCS_DISABLED
;
444 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
445 if (config
== _cur
.grfconfig
) _cur
.skip_sprites
= -1;
447 if (message
!= STR_NULL
) {
448 delete config
->error
;
449 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
450 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
453 return config
->error
;
457 * Information for mapping static StringIDs.
459 struct StringIDMapping
{
460 uint32 grfid
; ///< Source NewGRF.
461 StringID source
; ///< Source StringID (GRF local).
462 StringID
*target
; ///< Destination for mapping result.
464 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
465 static StringIDMappingVector _string_to_grf_mapping
;
468 * Record a static StringID for getting translated later.
469 * @param source Source StringID (GRF local).
470 * @param target Destination for the mapping result.
472 static void AddStringForMapping(StringID source
, StringID
*target
)
474 *target
= STR_UNDEFINED
;
475 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
476 item
->grfid
= _cur
.grffile
->grfid
;
477 item
->source
= source
;
478 item
->target
= target
;
482 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
483 * string IDs, but only for the ones we are aware off; the rest
484 * like likely unused and will show a warning.
485 * @param str the string ID to convert
486 * @return the converted string ID
488 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
490 /* StringID table for TextIDs 0x4E->0x6D */
491 static const StringID units_volume
[] = {
492 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
493 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
494 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
495 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
496 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
497 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
498 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
499 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
502 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506 assert_compile(stringend - stringid == end - begin); \
507 if (str >= begin && str <= end) return str + (stringid - begin)
509 /* We have some changes in our cargo strings, resulting in some missing. */
510 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
511 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
512 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
513 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
514 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
515 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
517 /* Map building names according to our lang file changes. There are several
518 * ranges of house ids, all of which need to be remapped to allow newgrfs
519 * to use original house names. */
520 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
521 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
522 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
524 /* Same thing for industries */
525 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
526 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
527 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
528 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
529 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
532 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
533 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
534 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
536 #undef TEXTID_TO_STRINGID
538 if (str
== STR_NULL
) return STR_EMPTY
;
540 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
546 * Used when setting an object's property to map to the GRF's strings
547 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
548 * @param grfid Id of the grf file.
549 * @param str StringID that we want to have the equivalent in OoenTTD.
550 * @return The properly adjusted StringID.
552 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
554 if (IsInsideMM(str
, 0xD800, 0xE000)) {
555 /* General text provided by NewGRF.
556 * In the specs this is called the 0xDCxx range (misc presistent texts),
557 * but we meanwhile extended the range to 0xD800-0xDFFF.
558 * Note: We are not involved in the "persistent" business, since we do not store
559 * any NewGRF strings in savegames. */
560 return GetGRFStringID(grfid
, str
);
561 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
562 /* Callback text provided by NewGRF.
563 * In the specs this is called the 0xD0xx range (misc graphics texts).
564 * These texts can be returned by various callbacks.
566 * Due to how TTDP implements the GRF-local- to global-textid translation
567 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568 * We do not care about that difference and just mask out the 0x400 bit.
571 return GetGRFStringID(grfid
, str
);
573 /* The NewGRF wants to include/reference an original TTD string.
574 * Try our best to find an equivalent one. */
575 return TTDPStringIDToOTTDStringIDMapping(str
);
579 static std::map
<uint32
, uint32
> _grf_id_overrides
;
582 * Set the override for a NewGRF
583 * @param source_grfid The grfID which wants to override another NewGRF.
584 * @param target_grfid The grfID which is being overridden.
586 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
588 _grf_id_overrides
[source_grfid
] = target_grfid
;
589 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
593 * Returns the engine associated to a certain internal_id, resp. allocates it.
594 * @param file NewGRF that wants to change the engine.
595 * @param type Vehicle type.
596 * @param internal_id Engine ID inside the NewGRF.
597 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
598 * @return The requested engine.
600 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
602 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603 * them use the same engine slots. */
604 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
605 if (_settings_game
.vehicle
.dynamic_engines
) {
606 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607 scope_grfid
= file
->grfid
;
608 uint32 override
= _grf_id_overrides
[file
->grfid
];
610 scope_grfid
= override
;
611 const GRFFile
*grf_match
= GetFileByGRFID(override
);
612 if (grf_match
== NULL
) {
613 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
615 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
619 /* Check if the engine is registered in the override manager */
620 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
621 if (engine
!= INVALID_ENGINE
) {
622 Engine
*e
= Engine::Get(engine
);
623 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
628 /* Check if there is an unreserved slot */
629 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
630 if (engine
!= INVALID_ENGINE
) {
631 Engine
*e
= Engine::Get(engine
);
633 if (e
->grf_prop
.grffile
== NULL
) {
634 e
->grf_prop
.grffile
= file
;
635 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
638 /* Reserve the engine slot */
639 if (!static_access
) {
640 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
641 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
647 if (static_access
) return NULL
;
649 if (!Engine::CanAllocateItem()) {
650 grfmsg(0, "Can't allocate any more engines");
654 size_t engine_pool_size
= Engine::GetPoolSize();
656 /* ... it's not, so create a new one based off an existing engine */
657 Engine
*e
= new Engine(type
, internal_id
);
658 e
->grf_prop
.grffile
= file
;
660 /* Reserve the engine slot */
661 assert(_engine_mngr
.Length() == e
->index
);
662 EngineIDMapping
*eid
= _engine_mngr
.Append();
664 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
665 eid
->internal_id
= internal_id
;
666 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
668 if (engine_pool_size
!= Engine::GetPoolSize()) {
669 /* Resize temporary engine data ... */
670 _gted
= ReallocT(_gted
, Engine::GetPoolSize());
672 /* and blank the new block. */
673 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
674 memset(_gted
+ engine_pool_size
, 0, len
);
676 if (type
== VEH_TRAIN
) {
677 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
680 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
686 * Return the ID of a new engine
687 * @param file The NewGRF file providing the engine.
688 * @param type The Vehicle type.
689 * @param internal_id NewGRF-internal ID of the engine.
690 * @return The new EngineID.
691 * @note depending on the dynamic_engine setting and a possible override
692 * property the grfID may be unique or overwriting or partially re-defining
693 * properties of an existing engine.
695 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
697 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
698 if (_settings_game
.vehicle
.dynamic_engines
) {
699 scope_grfid
= file
->grfid
;
700 uint32 override
= _grf_id_overrides
[file
->grfid
];
701 if (override
!= 0) scope_grfid
= override
;
704 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
708 * Map the colour modifiers of TTDPatch to those that Open is using.
709 * @param grf_sprite Pointer to the structure been modified.
711 static void MapSpriteMappingRecolour(PalSpriteID
*grf_sprite
)
713 if (HasBit(grf_sprite
->pal
, 14)) {
714 ClrBit(grf_sprite
->pal
, 14);
715 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_OPAQUE
);
718 if (HasBit(grf_sprite
->sprite
, 14)) {
719 ClrBit(grf_sprite
->sprite
, 14);
720 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_TRANSPARENT
);
723 if (HasBit(grf_sprite
->sprite
, 15)) {
724 ClrBit(grf_sprite
->sprite
, 15);
725 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_COLOUR
);
730 * Read a sprite and a palette from the GRF and convert them into a format
731 * suitable to OpenTTD.
732 * @param buf Input stream.
733 * @param read_flags Whether to read TileLayoutFlags.
734 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
735 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
736 * @param feature GrfSpecFeature to use spritesets from.
737 * @param [out] grf_sprite Read sprite and palette.
738 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
739 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
740 * @return Read TileLayoutFlags.
742 static TileLayoutFlags
ReadSpriteLayoutSprite(ByteReader
*buf
, bool read_flags
, bool invert_action1_flag
, bool use_cur_spritesets
, int feature
, PalSpriteID
*grf_sprite
, uint16
*max_sprite_offset
= NULL
, uint16
*max_palette_offset
= NULL
)
744 grf_sprite
->sprite
= buf
->ReadWord();
745 grf_sprite
->pal
= buf
->ReadWord();
746 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
748 MapSpriteMappingRecolour(grf_sprite
);
750 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
751 ClrBit(grf_sprite
->pal
, 15);
753 /* Use sprite from Action 1 */
754 uint index
= GB(grf_sprite
->sprite
, 0, 14);
755 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
756 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
757 grf_sprite
->sprite
= SPR_IMG_QUERY
;
758 grf_sprite
->pal
= PAL_NONE
;
760 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
761 if (max_sprite_offset
!= NULL
) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
762 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
763 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
765 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
766 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
771 if (flags
& TLF_CUSTOM_PALETTE
) {
772 /* Use palette from Action 1 */
773 uint index
= GB(grf_sprite
->pal
, 0, 14);
774 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
775 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
776 grf_sprite
->pal
= PAL_NONE
;
778 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
779 if (max_palette_offset
!= NULL
) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
780 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
781 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
783 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
784 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
793 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
794 * @param buf Input stream.
795 * @param flags TileLayoutFlags to process.
796 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
797 * @param dts Sprite layout to insert data into.
798 * @param index Sprite index to process; 0 for ground sprite.
800 static void ReadSpriteLayoutRegisters(ByteReader
*buf
, TileLayoutFlags flags
, bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
802 if (!(flags
& TLF_DRAWING_FLAGS
)) return;
804 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
805 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
806 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
808 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
809 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
810 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
813 if (flags
& TLF_BB_XY_OFFSET
) {
814 regs
.delta
.parent
[0] = buf
->ReadByte();
815 regs
.delta
.parent
[1] = buf
->ReadByte();
817 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
819 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
820 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
823 if (flags
& TLF_SPRITE_VAR10
) {
824 regs
.sprite_var10
= buf
->ReadByte();
825 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
826 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
832 if (flags
& TLF_PALETTE_VAR10
) {
833 regs
.palette_var10
= buf
->ReadByte();
834 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
835 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
843 * Read a spritelayout from the GRF.
845 * @param num_building_sprites Number of building sprites to read
846 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
847 * @param feature GrfSpecFeature to use spritesets from.
848 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
849 * @param no_z_position Whether bounding boxes have no Z offset
850 * @param dts Layout container to output into
851 * @return True on error (GRF was disabled).
853 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
855 bool has_flags
= HasBit(num_building_sprites
, 6);
856 ClrBit(num_building_sprites
, 6);
857 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
858 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
859 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
861 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
862 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
863 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
864 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
867 TileLayoutFlags flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &dts
->ground
, max_sprite_offset
, max_palette_offset
);
868 if (_cur
.skip_sprites
< 0) return true;
870 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
871 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
876 ReadSpriteLayoutRegisters(buf
, flags
, false, dts
, 0);
877 if (_cur
.skip_sprites
< 0) return true;
879 for (uint i
= 0; i
< num_building_sprites
; i
++) {
880 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
882 flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &seq
->image
, max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1);
883 if (_cur
.skip_sprites
< 0) return true;
885 if (flags
& ~valid_flags
) {
886 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
891 seq
->delta_x
= buf
->ReadByte();
892 seq
->delta_y
= buf
->ReadByte();
894 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
896 if (seq
->IsParentSprite()) {
897 seq
->size_x
= buf
->ReadByte();
898 seq
->size_y
= buf
->ReadByte();
899 seq
->size_z
= buf
->ReadByte();
902 ReadSpriteLayoutRegisters(buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1);
903 if (_cur
.skip_sprites
< 0) return true;
906 /* Check if the number of sprites per spriteset is consistent */
907 bool is_consistent
= true;
908 dts
->consistent_max_offset
= 0;
909 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
910 if (max_sprite_offset
[i
] > 0) {
911 if (dts
->consistent_max_offset
== 0) {
912 dts
->consistent_max_offset
= max_sprite_offset
[i
];
913 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
914 is_consistent
= false;
918 if (max_palette_offset
[i
] > 0) {
919 if (dts
->consistent_max_offset
== 0) {
920 dts
->consistent_max_offset
= max_palette_offset
[i
];
921 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
922 is_consistent
= false;
928 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
931 if (!is_consistent
|| dts
->registers
!= NULL
) {
932 dts
->consistent_max_offset
= 0;
933 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
935 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
936 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
937 regs
.max_sprite_offset
= max_sprite_offset
[i
];
938 regs
.max_palette_offset
= max_palette_offset
[i
];
946 * Translate the refit mask.
948 static uint32
TranslateRefitMask(uint32 refit_mask
)
952 FOR_EACH_SET_BIT(bit
, refit_mask
) {
953 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
954 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
960 * Converts TTD(P) Base Price pointers into the enum used by OTTD
961 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
962 * @param base_pointer TTD(P) Base Price Pointer
963 * @param error_location Function name for grf error messages
964 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
966 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
968 /* Special value for 'none' */
969 if (base_pointer
== 0) {
970 *index
= INVALID_PRICE
;
974 static const uint32 start
= 0x4B34; ///< Position of first base price
975 static const uint32 size
= 6; ///< Size of each base price record
977 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
978 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
982 *index
= (Price
)((base_pointer
- start
) / size
);
985 /** Possible return values for the FeatureChangeInfo functions */
986 enum ChangeInfoResult
{
987 CIR_SUCCESS
, ///< Variable was parsed and read
988 CIR_DISABLED
, ///< GRF was disabled due to error
989 CIR_UNHANDLED
, ///< Variable was parsed but unread
990 CIR_UNKNOWN
, ///< Variable is unknown
991 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
994 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
997 * Define properties common to all vehicles
998 * @param ei Engine info.
999 * @param prop The property to change.
1000 * @param buf The property value.
1001 * @return ChangeInfoResult.
1003 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1006 case 0x00: // Introduction date
1007 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1010 case 0x02: // Decay speed
1011 ei
->decay_speed
= buf
->ReadByte();
1014 case 0x03: // Vehicle life
1015 ei
->lifelength
= buf
->ReadByte();
1018 case 0x04: // Model life
1019 ei
->base_life
= buf
->ReadByte();
1022 case 0x06: // Climates available
1023 ei
->climates
= buf
->ReadByte();
1026 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1027 /* Amount of cargo loaded during a vehicle's "loading tick" */
1028 ei
->load_amount
= buf
->ReadByte();
1039 * Define properties for rail vehicles
1040 * @param engine :ocal ID of the first vehicle.
1041 * @param numinfo Number of subsequent IDs to change the property for.
1042 * @param prop The property to change.
1043 * @param buf The property value.
1044 * @return ChangeInfoResult.
1046 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1048 ChangeInfoResult ret
= CIR_SUCCESS
;
1050 for (int i
= 0; i
< numinfo
; i
++) {
1051 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1052 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1054 EngineInfo
*ei
= &e
->info
;
1055 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1058 case 0x05: { // Track type
1059 uint8 tracktype
= buf
->ReadByte();
1061 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1062 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1066 switch (tracktype
) {
1067 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1068 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1069 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1071 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1077 case 0x08: // AI passenger service
1078 /* Tells the AI that this engine is designed for
1079 * passenger services and shouldn't be used for freight. */
1080 rvi
->ai_passenger_only
= buf
->ReadByte();
1083 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084 uint16 speed
= buf
->ReadWord();
1085 if (speed
== 0xFFFF) speed
= 0;
1087 rvi
->max_speed
= speed
;
1091 case PROP_TRAIN_POWER
: // 0x0B Power
1092 rvi
->power
= buf
->ReadWord();
1094 /* Set engine / wagon state based on power */
1095 if (rvi
->power
!= 0) {
1096 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1097 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1100 rvi
->railveh_type
= RAILVEH_WAGON
;
1104 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1105 rvi
->running_cost
= buf
->ReadByte();
1108 case 0x0E: // Running cost base
1109 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1112 case 0x12: { // Sprite ID
1113 uint8 spriteid
= buf
->ReadByte();
1114 uint8 orig_spriteid
= spriteid
;
1116 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117 * as an array index, so we need it to be half the original value. */
1118 if (spriteid
< 0xFD) spriteid
>>= 1;
1120 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1121 rvi
->image_index
= spriteid
;
1123 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1124 rvi
->image_index
= 0;
1129 case 0x13: { // Dual-headed
1130 uint8 dual
= buf
->ReadByte();
1133 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1135 rvi
->railveh_type
= rvi
->power
== 0 ?
1136 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1141 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1142 rvi
->capacity
= buf
->ReadByte();
1145 case 0x15: { // Cargo type
1146 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1147 uint8 ctype
= buf
->ReadByte();
1149 if (ctype
== 0xFF) {
1150 /* 0xFF is specified as 'use first refittable' */
1151 ei
->cargo_type
= CT_INVALID
;
1152 } else if (_cur
.grffile
->grf_version
>= 8) {
1153 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1155 } else if (ctype
< NUM_CARGO
) {
1156 /* Use untranslated cargo. */
1157 ei
->cargo_type
= ctype
;
1159 ei
->cargo_type
= CT_INVALID
;
1160 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1165 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1166 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1169 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1170 rvi
->cost_factor
= buf
->ReadByte();
1173 case 0x18: // AI rank
1174 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1178 case 0x19: { // Engine traction type
1179 /* What do the individual numbers mean?
1180 * 0x00 .. 0x07: Steam
1181 * 0x08 .. 0x27: Diesel
1182 * 0x28 .. 0x31: Electric
1183 * 0x32 .. 0x37: Monorail
1184 * 0x38 .. 0x41: Maglev
1186 uint8 traction
= buf
->ReadByte();
1187 EngineClass engclass
;
1189 if (traction
<= 0x07) {
1190 engclass
= EC_STEAM
;
1191 } else if (traction
<= 0x27) {
1192 engclass
= EC_DIESEL
;
1193 } else if (traction
<= 0x31) {
1194 engclass
= EC_ELECTRIC
;
1195 } else if (traction
<= 0x37) {
1196 engclass
= EC_MONORAIL
;
1197 } else if (traction
<= 0x41) {
1198 engclass
= EC_MAGLEV
;
1203 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1204 /* Use traction type to select between normal and electrified
1205 * rail only when no translation list is in place. */
1206 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1207 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1210 rvi
->engclass
= engclass
;
1214 case 0x1A: // Alter purchase list sort order
1215 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1218 case 0x1B: // Powered wagons power bonus
1219 rvi
->pow_wag_power
= buf
->ReadWord();
1222 case 0x1C: // Refit cost
1223 ei
->refit_cost
= buf
->ReadByte();
1226 case 0x1D: { // Refit cargo
1227 uint32 mask
= buf
->ReadDWord();
1228 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1229 ei
->refit_mask
= TranslateRefitMask(mask
);
1230 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1234 case 0x1E: // Callback
1235 ei
->callback_mask
= buf
->ReadByte();
1238 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1239 rvi
->tractive_effort
= buf
->ReadByte();
1242 case 0x20: // Air drag
1243 rvi
->air_drag
= buf
->ReadByte();
1246 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1247 rvi
->shorten_factor
= buf
->ReadByte();
1250 case 0x22: // Visual effect
1251 rvi
->visual_effect
= buf
->ReadByte();
1252 /* Avoid accidentally setting visual_effect to the default value
1253 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254 if (rvi
->visual_effect
== VE_DEFAULT
) {
1255 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1256 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1260 case 0x23: // Powered wagons weight bonus
1261 rvi
->pow_wag_weight
= buf
->ReadByte();
1264 case 0x24: { // High byte of vehicle weight
1265 byte weight
= buf
->ReadByte();
1268 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1270 SB(rvi
->weight
, 8, 8, weight
);
1275 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276 rvi
->user_def_data
= buf
->ReadByte();
1279 case 0x26: // Retire vehicle early
1280 ei
->retire_early
= buf
->ReadByte();
1283 case 0x27: // Miscellaneous flags
1284 ei
->misc_flags
= buf
->ReadByte();
1285 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1286 _gted
[e
->index
].prop27_set
= true;
1289 case 0x28: // Cargo classes allowed
1290 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1291 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1292 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1295 case 0x29: // Cargo classes disallowed
1296 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1297 _gted
[e
->index
].UpdateRefittability(false);
1300 case 0x2A: // Long format introduction date (days since year 0)
1301 ei
->base_intro
= buf
->ReadDWord();
1304 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1305 ei
->cargo_age_period
= buf
->ReadWord();
1308 case 0x2C: // CTT refit include list
1309 case 0x2D: { // CTT refit exclude list
1310 uint8 count
= buf
->ReadByte();
1311 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1312 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1313 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1316 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1317 if (ctype
== CT_INVALID
) continue;
1324 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1333 * Define properties for road vehicles
1334 * @param engine Local ID of the first vehicle.
1335 * @param numinfo Number of subsequent IDs to change the property for.
1336 * @param prop The property to change.
1337 * @param buf The property value.
1338 * @return ChangeInfoResult.
1340 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1342 ChangeInfoResult ret
= CIR_SUCCESS
;
1344 for (int i
= 0; i
< numinfo
; i
++) {
1345 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1346 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1348 EngineInfo
*ei
= &e
->info
;
1349 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1352 case 0x08: // Speed (1 unit is 0.5 kmh)
1353 rvi
->max_speed
= buf
->ReadByte();
1356 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1357 rvi
->running_cost
= buf
->ReadByte();
1360 case 0x0A: // Running cost base
1361 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1364 case 0x0E: { // Sprite ID
1365 uint8 spriteid
= buf
->ReadByte();
1366 uint8 orig_spriteid
= spriteid
;
1368 /* cars have different custom id in the GRF file */
1369 if (spriteid
== 0xFF) spriteid
= 0xFD;
1371 if (spriteid
< 0xFD) spriteid
>>= 1;
1373 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1374 rvi
->image_index
= spriteid
;
1376 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1377 rvi
->image_index
= 0;
1382 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1383 rvi
->capacity
= buf
->ReadByte();
1386 case 0x10: { // Cargo type
1387 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1388 uint8 ctype
= buf
->ReadByte();
1390 if (ctype
== 0xFF) {
1391 /* 0xFF is specified as 'use first refittable' */
1392 ei
->cargo_type
= CT_INVALID
;
1393 } else if (_cur
.grffile
->grf_version
>= 8) {
1394 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1395 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1396 } else if (ctype
< NUM_CARGO
) {
1397 /* Use untranslated cargo. */
1398 ei
->cargo_type
= ctype
;
1400 ei
->cargo_type
= CT_INVALID
;
1401 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1406 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1407 rvi
->cost_factor
= buf
->ReadByte();
1411 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1414 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1415 rvi
->power
= buf
->ReadByte();
1418 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1419 rvi
->weight
= buf
->ReadByte();
1422 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1423 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1426 case 0x16: { // Cargoes available for refitting
1427 uint32 mask
= buf
->ReadDWord();
1428 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1429 ei
->refit_mask
= TranslateRefitMask(mask
);
1430 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1434 case 0x17: // Callback mask
1435 ei
->callback_mask
= buf
->ReadByte();
1438 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1439 rvi
->tractive_effort
= buf
->ReadByte();
1442 case 0x19: // Air drag
1443 rvi
->air_drag
= buf
->ReadByte();
1446 case 0x1A: // Refit cost
1447 ei
->refit_cost
= buf
->ReadByte();
1450 case 0x1B: // Retire vehicle early
1451 ei
->retire_early
= buf
->ReadByte();
1454 case 0x1C: // Miscellaneous flags
1455 ei
->misc_flags
= buf
->ReadByte();
1456 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1459 case 0x1D: // Cargo classes allowed
1460 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1461 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1462 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1465 case 0x1E: // Cargo classes disallowed
1466 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1467 _gted
[e
->index
].UpdateRefittability(false);
1470 case 0x1F: // Long format introduction date (days since year 0)
1471 ei
->base_intro
= buf
->ReadDWord();
1474 case 0x20: // Alter purchase list sort order
1475 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1478 case 0x21: // Visual effect
1479 rvi
->visual_effect
= buf
->ReadByte();
1480 /* Avoid accidentally setting visual_effect to the default value
1481 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1482 if (rvi
->visual_effect
== VE_DEFAULT
) {
1483 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1484 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1488 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1489 ei
->cargo_age_period
= buf
->ReadWord();
1492 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1493 rvi
->shorten_factor
= buf
->ReadByte();
1496 case 0x24: // CTT refit include list
1497 case 0x25: { // CTT refit exclude list
1498 uint8 count
= buf
->ReadByte();
1499 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1500 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1501 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1504 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1505 if (ctype
== CT_INVALID
) continue;
1512 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1521 * Define properties for ships
1522 * @param engine Local ID of the first vehicle.
1523 * @param numinfo Number of subsequent IDs to change the property for.
1524 * @param prop The property to change.
1525 * @param buf The property value.
1526 * @return ChangeInfoResult.
1528 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1530 ChangeInfoResult ret
= CIR_SUCCESS
;
1532 for (int i
= 0; i
< numinfo
; i
++) {
1533 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1534 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1536 EngineInfo
*ei
= &e
->info
;
1537 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1540 case 0x08: { // Sprite ID
1541 uint8 spriteid
= buf
->ReadByte();
1542 uint8 orig_spriteid
= spriteid
;
1544 /* ships have different custom id in the GRF file */
1545 if (spriteid
== 0xFF) spriteid
= 0xFD;
1547 if (spriteid
< 0xFD) spriteid
>>= 1;
1549 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1550 svi
->image_index
= spriteid
;
1552 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1553 svi
->image_index
= 0;
1558 case 0x09: // Refittable
1559 svi
->old_refittable
= (buf
->ReadByte() != 0);
1562 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1563 svi
->cost_factor
= buf
->ReadByte();
1566 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1567 svi
->max_speed
= buf
->ReadByte();
1570 case 0x0C: { // Cargo type
1571 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1572 uint8 ctype
= buf
->ReadByte();
1574 if (ctype
== 0xFF) {
1575 /* 0xFF is specified as 'use first refittable' */
1576 ei
->cargo_type
= CT_INVALID
;
1577 } else if (_cur
.grffile
->grf_version
>= 8) {
1578 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1579 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1580 } else if (ctype
< NUM_CARGO
) {
1581 /* Use untranslated cargo. */
1582 ei
->cargo_type
= ctype
;
1584 ei
->cargo_type
= CT_INVALID
;
1585 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1590 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1591 svi
->capacity
= buf
->ReadWord();
1594 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1595 svi
->running_cost
= buf
->ReadByte();
1599 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1602 case 0x11: { // Cargoes available for refitting
1603 uint32 mask
= buf
->ReadDWord();
1604 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1605 ei
->refit_mask
= TranslateRefitMask(mask
);
1606 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1610 case 0x12: // Callback mask
1611 ei
->callback_mask
= buf
->ReadByte();
1614 case 0x13: // Refit cost
1615 ei
->refit_cost
= buf
->ReadByte();
1618 case 0x14: // Ocean speed fraction
1619 svi
->ocean_speed_frac
= buf
->ReadByte();
1622 case 0x15: // Canal speed fraction
1623 svi
->canal_speed_frac
= buf
->ReadByte();
1626 case 0x16: // Retire vehicle early
1627 ei
->retire_early
= buf
->ReadByte();
1630 case 0x17: // Miscellaneous flags
1631 ei
->misc_flags
= buf
->ReadByte();
1632 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1635 case 0x18: // Cargo classes allowed
1636 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1637 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1638 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1641 case 0x19: // Cargo classes disallowed
1642 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1643 _gted
[e
->index
].UpdateRefittability(false);
1646 case 0x1A: // Long format introduction date (days since year 0)
1647 ei
->base_intro
= buf
->ReadDWord();
1650 case 0x1B: // Alter purchase list sort order
1651 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1654 case 0x1C: // Visual effect
1655 svi
->visual_effect
= buf
->ReadByte();
1656 /* Avoid accidentally setting visual_effect to the default value
1657 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1658 if (svi
->visual_effect
== VE_DEFAULT
) {
1659 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1660 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1664 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1665 ei
->cargo_age_period
= buf
->ReadWord();
1668 case 0x1E: // CTT refit include list
1669 case 0x1F: { // CTT refit exclude list
1670 uint8 count
= buf
->ReadByte();
1671 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1672 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1673 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1676 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1677 if (ctype
== CT_INVALID
) continue;
1684 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1693 * Define properties for aircraft
1694 * @param engine Local ID of the aircraft.
1695 * @param numinfo Number of subsequent IDs to change the property for.
1696 * @param prop The property to change.
1697 * @param buf The property value.
1698 * @return ChangeInfoResult.
1700 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1702 ChangeInfoResult ret
= CIR_SUCCESS
;
1704 for (int i
= 0; i
< numinfo
; i
++) {
1705 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1706 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1708 EngineInfo
*ei
= &e
->info
;
1709 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1712 case 0x08: { // Sprite ID
1713 uint8 spriteid
= buf
->ReadByte();
1714 uint8 orig_spriteid
= spriteid
;
1716 /* aircraft have different custom id in the GRF file */
1717 if (spriteid
== 0xFF) spriteid
= 0xFD;
1719 if (spriteid
< 0xFD) spriteid
>>= 1;
1721 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1722 avi
->image_index
= spriteid
;
1724 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1725 avi
->image_index
= 0;
1730 case 0x09: // Helicopter
1731 if (buf
->ReadByte() == 0) {
1732 avi
->subtype
= AIR_HELI
;
1734 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1739 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1742 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1743 avi
->cost_factor
= buf
->ReadByte();
1746 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1747 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1750 case 0x0D: // Acceleration
1751 avi
->acceleration
= buf
->ReadByte();
1754 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1755 avi
->running_cost
= buf
->ReadByte();
1758 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1759 avi
->passenger_capacity
= buf
->ReadWord();
1762 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1763 avi
->mail_capacity
= buf
->ReadByte();
1767 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1770 case 0x13: { // Cargoes available for refitting
1771 uint32 mask
= buf
->ReadDWord();
1772 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1773 ei
->refit_mask
= TranslateRefitMask(mask
);
1774 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1778 case 0x14: // Callback mask
1779 ei
->callback_mask
= buf
->ReadByte();
1782 case 0x15: // Refit cost
1783 ei
->refit_cost
= buf
->ReadByte();
1786 case 0x16: // Retire vehicle early
1787 ei
->retire_early
= buf
->ReadByte();
1790 case 0x17: // Miscellaneous flags
1791 ei
->misc_flags
= buf
->ReadByte();
1792 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1795 case 0x18: // Cargo classes allowed
1796 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1797 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1798 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1801 case 0x19: // Cargo classes disallowed
1802 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1803 _gted
[e
->index
].UpdateRefittability(false);
1806 case 0x1A: // Long format introduction date (days since year 0)
1807 ei
->base_intro
= buf
->ReadDWord();
1810 case 0x1B: // Alter purchase list sort order
1811 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1814 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1815 ei
->cargo_age_period
= buf
->ReadWord();
1818 case 0x1D: // CTT refit include list
1819 case 0x1E: { // CTT refit exclude list
1820 uint8 count
= buf
->ReadByte();
1821 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1822 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1823 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1826 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1827 if (ctype
== CT_INVALID
) continue;
1833 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1834 avi
->max_range
= buf
->ReadWord();
1838 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1847 * Define properties for stations
1848 * @param stdid StationID of the first station tile.
1849 * @param numinfo Number of subsequent station tiles to change the property for.
1850 * @param prop The property to change.
1851 * @param buf The property value.
1852 * @return ChangeInfoResult.
1854 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1856 ChangeInfoResult ret
= CIR_SUCCESS
;
1858 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1859 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1860 return CIR_INVALID_ID
;
1863 /* Allocate station specs if necessary */
1864 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= CallocT
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1866 for (int i
= 0; i
< numinfo
; i
++) {
1867 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1869 /* Check that the station we are modifying is defined. */
1870 if (statspec
== NULL
&& prop
!= 0x08) {
1871 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1872 return CIR_INVALID_ID
;
1876 case 0x08: { // Class ID
1877 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1879 /* Property 0x08 is special; it is where the station is allocated */
1880 if (*spec
== NULL
) *spec
= CallocT
<StationSpec
>(1);
1882 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1883 uint32 classid
= buf
->ReadDWord();
1884 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1888 case 0x09: // Define sprite layout
1889 statspec
->tiles
= buf
->ReadExtendedByte();
1890 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1891 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1893 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1894 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1895 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1897 if (buf
->HasData(4) && *(uint32
*)buf
->Data() == 0) {
1899 extern const DrawTileSprites _station_display_datas_rail
[8];
1900 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1904 ReadSpriteLayoutSprite(buf
, false, false, false, GSF_STATIONS
, &dts
->ground
);
1905 /* On error, bail out immediately. Temporary GRF data was already freed */
1906 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1908 static SmallVector
<DrawTileSeqStruct
, 8> tmp_layout
;
1911 /* no relative bounding box support */
1912 DrawTileSeqStruct
*dtss
= tmp_layout
.Append();
1915 dtss
->delta_x
= buf
->ReadByte();
1916 if (dtss
->IsTerminator()) break;
1917 dtss
->delta_y
= buf
->ReadByte();
1918 dtss
->delta_z
= buf
->ReadByte();
1919 dtss
->size_x
= buf
->ReadByte();
1920 dtss
->size_y
= buf
->ReadByte();
1921 dtss
->size_z
= buf
->ReadByte();
1923 ReadSpriteLayoutSprite(buf
, false, true, false, GSF_STATIONS
, &dtss
->image
);
1924 /* On error, bail out immediately. Temporary GRF data was already freed */
1925 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1927 dts
->Clone(tmp_layout
.Begin());
1931 case 0x0A: { // Copy sprite layout
1932 byte srcid
= buf
->ReadByte();
1933 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1935 if (srcstatspec
== NULL
) {
1936 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1940 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1942 statspec
->tiles
= srcstatspec
->tiles
;
1943 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1944 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1945 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1950 case 0x0B: // Callback mask
1951 statspec
->callback_mask
= buf
->ReadByte();
1954 case 0x0C: // Disallowed number of platforms
1955 statspec
->disallowed_platforms
= buf
->ReadByte();
1958 case 0x0D: // Disallowed platform lengths
1959 statspec
->disallowed_lengths
= buf
->ReadByte();
1962 case 0x0E: // Define custom layout
1963 statspec
->copied_layouts
= false;
1965 while (buf
->HasData()) {
1966 byte length
= buf
->ReadByte();
1967 byte number
= buf
->ReadByte();
1968 StationLayout layout
;
1971 if (length
== 0 || number
== 0) break;
1973 if (length
> statspec
->lengths
) {
1974 statspec
->platforms
= ReallocT(statspec
->platforms
, length
);
1975 memset(statspec
->platforms
+ statspec
->lengths
, 0, length
- statspec
->lengths
);
1977 statspec
->layouts
= ReallocT(statspec
->layouts
, length
);
1978 memset(statspec
->layouts
+ statspec
->lengths
, 0,
1979 (length
- statspec
->lengths
) * sizeof(*statspec
->layouts
));
1981 statspec
->lengths
= length
;
1983 l
= length
- 1; // index is zero-based
1985 if (number
> statspec
->platforms
[l
]) {
1986 statspec
->layouts
[l
] = ReallocT(statspec
->layouts
[l
], number
);
1987 /* We expect NULL being 0 here, but C99 guarantees that. */
1988 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
1989 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
1991 statspec
->platforms
[l
] = number
;
1995 layout
= MallocT
<byte
>(length
* number
);
1997 for (l
= 0; l
< length
; l
++) {
1998 for (p
= 0; p
< number
; p
++) {
1999 layout
[l
* number
+ p
] = buf
->ReadByte();
2009 free(statspec
->layouts
[l
][p
]);
2010 statspec
->layouts
[l
][p
] = layout
;
2014 case 0x0F: { // Copy custom layout
2015 byte srcid
= buf
->ReadByte();
2016 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2018 if (srcstatspec
== NULL
) {
2019 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2023 statspec
->lengths
= srcstatspec
->lengths
;
2024 statspec
->platforms
= srcstatspec
->platforms
;
2025 statspec
->layouts
= srcstatspec
->layouts
;
2026 statspec
->copied_layouts
= true;
2030 case 0x10: // Little/lots cargo threshold
2031 statspec
->cargo_threshold
= buf
->ReadWord();
2034 case 0x11: // Pylon placement
2035 statspec
->pylons
= buf
->ReadByte();
2038 case 0x12: // Cargo types for random triggers
2039 statspec
->cargo_triggers
= buf
->ReadDWord();
2040 if (_cur
.grffile
->grf_version
>= 7) {
2041 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2045 case 0x13: // General flags
2046 statspec
->flags
= buf
->ReadByte();
2049 case 0x14: // Overhead wire placement
2050 statspec
->wires
= buf
->ReadByte();
2053 case 0x15: // Blocked tiles
2054 statspec
->blocked
= buf
->ReadByte();
2057 case 0x16: // Animation info
2058 statspec
->animation
.frames
= buf
->ReadByte();
2059 statspec
->animation
.status
= buf
->ReadByte();
2062 case 0x17: // Animation speed
2063 statspec
->animation
.speed
= buf
->ReadByte();
2066 case 0x18: // Animation triggers
2067 statspec
->animation
.triggers
= buf
->ReadWord();
2070 case 0x1A: // Advanced sprite layout
2071 statspec
->tiles
= buf
->ReadExtendedByte();
2072 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2073 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2075 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2076 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2077 uint num_building_sprites
= buf
->ReadByte();
2078 /* On error, bail out immediately. Temporary GRF data was already freed */
2079 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) return CIR_DISABLED
;
2093 * Define properties for water features
2094 * @param id Type of the first water feature.
2095 * @param numinfo Number of subsequent water feature ids to change the property for.
2096 * @param prop The property to change.
2097 * @param buf The property value.
2098 * @return ChangeInfoResult.
2100 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2102 ChangeInfoResult ret
= CIR_SUCCESS
;
2104 if (id
+ numinfo
> CF_END
) {
2105 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2106 return CIR_INVALID_ID
;
2109 for (int i
= 0; i
< numinfo
; i
++) {
2110 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2114 cp
->callback_mask
= buf
->ReadByte();
2118 cp
->flags
= buf
->ReadByte();
2131 * Define properties for bridges
2132 * @param brid BridgeID of the bridge.
2133 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2134 * @param prop The property to change.
2135 * @param buf The property value.
2136 * @return ChangeInfoResult.
2138 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2140 ChangeInfoResult ret
= CIR_SUCCESS
;
2142 if (brid
+ numinfo
> MAX_BRIDGES
) {
2143 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2144 return CIR_INVALID_ID
;
2147 for (int i
= 0; i
< numinfo
; i
++) {
2148 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2151 case 0x08: { // Year of availability
2152 /* We treat '0' as always available */
2153 byte year
= buf
->ReadByte();
2154 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2158 case 0x09: // Minimum length
2159 bridge
->min_length
= buf
->ReadByte();
2162 case 0x0A: // Maximum length
2163 bridge
->max_length
= buf
->ReadByte();
2164 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2167 case 0x0B: // Cost factor
2168 bridge
->price
= buf
->ReadByte();
2171 case 0x0C: // Maximum speed
2172 bridge
->speed
= buf
->ReadWord();
2175 case 0x0D: { // Bridge sprite tables
2176 byte tableid
= buf
->ReadByte();
2177 byte numtables
= buf
->ReadByte();
2179 if (bridge
->sprite_table
== NULL
) {
2180 /* Allocate memory for sprite table pointers and zero out */
2181 bridge
->sprite_table
= CallocT
<PalSpriteID
*>(7);
2184 for (; numtables
-- != 0; tableid
++) {
2185 if (tableid
>= 7) { // skip invalid data
2186 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2187 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2191 if (bridge
->sprite_table
[tableid
] == NULL
) {
2192 bridge
->sprite_table
[tableid
] = MallocT
<PalSpriteID
>(32);
2195 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2196 SpriteID image
= buf
->ReadWord();
2197 PaletteID pal
= buf
->ReadWord();
2199 bridge
->sprite_table
[tableid
][sprite
].sprite
= image
;
2200 bridge
->sprite_table
[tableid
][sprite
].pal
= pal
;
2202 MapSpriteMappingRecolour(&bridge
->sprite_table
[tableid
][sprite
]);
2208 case 0x0E: // Flags; bit 0 - disable far pillars
2209 bridge
->flags
= buf
->ReadByte();
2212 case 0x0F: // Long format year of availability (year since year 0)
2213 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2216 case 0x10: { // purchase string
2217 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2218 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2222 case 0x11: // description of bridge with rails or roads
2224 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2225 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2229 case 0x13: // 16 bits cost multiplier
2230 bridge
->price
= buf
->ReadWord();
2243 * Ignore a house property
2244 * @param prop Property to read.
2245 * @param buf Property value.
2246 * @return ChangeInfoResult.
2248 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2250 ChangeInfoResult ret
= CIR_SUCCESS
;
2287 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2291 byte count
= buf
->ReadByte();
2292 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2304 * Define properties for houses
2305 * @param hid HouseID of the house.
2306 * @param numinfo Number of subsequent houseIDs to change the property for.
2307 * @param prop The property to change.
2308 * @param buf The property value.
2309 * @return ChangeInfoResult.
2311 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2313 ChangeInfoResult ret
= CIR_SUCCESS
;
2315 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2316 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2317 return CIR_INVALID_ID
;
2320 /* Allocate house specs if they haven't been allocated already. */
2321 if (_cur
.grffile
->housespec
== NULL
) {
2322 _cur
.grffile
->housespec
= CallocT
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2325 for (int i
= 0; i
< numinfo
; i
++) {
2326 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2328 if (prop
!= 0x08 && housespec
== NULL
) {
2329 /* If the house property 08 is not yet set, ignore this property */
2330 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2331 if (cir
> ret
) ret
= cir
;
2336 case 0x08: { // Substitute building type, and definition of a new house
2337 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2338 byte subs_id
= buf
->ReadByte();
2340 if (subs_id
== 0xFF) {
2341 /* Instead of defining a new house, a substitute house id
2342 * of 0xFF disables the old house with the current id. */
2343 HouseSpec::Get(hid
+ i
)->enabled
= false;
2345 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2346 /* The substitute id must be one of the original houses. */
2347 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2351 /* Allocate space for this house. */
2352 if (*house
== NULL
) *house
= CallocT
<HouseSpec
>(1);
2356 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2358 housespec
->enabled
= true;
2359 housespec
->grf_prop
.local_id
= hid
+ i
;
2360 housespec
->grf_prop
.subst_id
= subs_id
;
2361 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2362 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2363 housespec
->random_colour
[1] = 0x08; // for all new houses
2364 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2365 housespec
->random_colour
[3] = 0x06;
2367 /* Make sure that the third cargo type is valid in this
2368 * climate. This can cause problems when copying the properties
2369 * of a house that accepts food, where the new house is valid
2370 * in the temperate climate. */
2371 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2372 housespec
->cargo_acceptance
[2] = 0;
2375 _loaded_newgrf_features
.has_newhouses
= true;
2379 case 0x09: // Building flags
2380 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2383 case 0x0A: { // Availability years
2384 uint16 years
= buf
->ReadWord();
2385 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2386 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2390 case 0x0B: // Population
2391 housespec
->population
= buf
->ReadByte();
2394 case 0x0C: // Mail generation multiplier
2395 housespec
->mail_generation
= buf
->ReadByte();
2398 case 0x0D: // Passenger acceptance
2399 case 0x0E: // Mail acceptance
2400 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2403 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2404 int8 goods
= buf
->ReadByte();
2406 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2407 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2408 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2409 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2411 /* Make sure the cargo type is valid in this climate. */
2412 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2414 housespec
->accepts_cargo
[2] = cid
;
2415 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2419 case 0x10: // Local authority rating decrease on removal
2420 housespec
->remove_rating_decrease
= buf
->ReadWord();
2423 case 0x11: // Removal cost multiplier
2424 housespec
->removal_cost
= buf
->ReadByte();
2427 case 0x12: // Building name ID
2428 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2431 case 0x13: // Building availability mask
2432 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2435 case 0x14: // House callback mask
2436 housespec
->callback_mask
|= buf
->ReadByte();
2439 case 0x15: { // House override byte
2440 byte override
= buf
->ReadByte();
2442 /* The house being overridden must be an original house. */
2443 if (override
>= NEW_HOUSE_OFFSET
) {
2444 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2448 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2452 case 0x16: // Periodic refresh multiplier
2453 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2456 case 0x17: // Four random colours to use
2457 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2460 case 0x18: // Relative probability of appearing
2461 housespec
->probability
= buf
->ReadByte();
2464 case 0x19: // Extra flags
2465 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2468 case 0x1A: // Animation frames
2469 housespec
->animation
.frames
= buf
->ReadByte();
2470 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2471 SB(housespec
->animation
.frames
, 7, 1, 0);
2474 case 0x1B: // Animation speed
2475 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2478 case 0x1C: // Class of the building type
2479 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2482 case 0x1D: // Callback mask part 2
2483 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2486 case 0x1E: { // Accepted cargo types
2487 uint32 cargotypes
= buf
->ReadDWord();
2489 /* Check if the cargo types should not be changed */
2490 if (cargotypes
== 0xFFFFFFFF) break;
2492 for (uint j
= 0; j
< 3; j
++) {
2493 /* Get the cargo number from the 'list' */
2494 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2495 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2497 if (cargo
== CT_INVALID
) {
2498 /* Disable acceptance of invalid cargo type */
2499 housespec
->cargo_acceptance
[j
] = 0;
2501 housespec
->accepts_cargo
[j
] = cargo
;
2507 case 0x1F: // Minimum life span
2508 housespec
->minimum_life
= buf
->ReadByte();
2511 case 0x20: { // Cargo acceptance watch list
2512 byte count
= buf
->ReadByte();
2513 for (byte j
= 0; j
< count
; j
++) {
2514 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2515 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2520 case 0x21: // long introduction year
2521 housespec
->min_year
= buf
->ReadWord();
2524 case 0x22: // long maximum year
2525 housespec
->max_year
= buf
->ReadWord();
2538 * Get the language map associated with a given NewGRF and language.
2539 * @param grfid The NewGRF to get the map for.
2540 * @param language_id The (NewGRF) language ID to get the map for.
2541 * @return The LanguageMap, or NULL if it couldn't be found.
2543 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2545 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2546 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2547 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2551 * Load a cargo- or railtype-translation table.
2552 * @param gvid ID of the global variable. This is basically only checked for zerones.
2553 * @param numinfo Number of subsequent IDs to change the property for.
2554 * @param buf The property value.
2555 * @param [in,out] translation_table Storage location for the translation table.
2556 * @param name Name of the table for debug output.
2557 * @return ChangeInfoResult.
2559 template <typename T
>
2560 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2563 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2564 return CIR_INVALID_ID
;
2567 translation_table
.Clear();
2568 for (int i
= 0; i
< numinfo
; i
++) {
2569 uint32 item
= buf
->ReadDWord();
2570 *translation_table
.Append() = BSWAP32(item
);
2577 * Define properties for global variables
2578 * @param gvid ID of the global variable.
2579 * @param numinfo Number of subsequent IDs to change the property for.
2580 * @param prop The property to change.
2581 * @param buf The property value.
2582 * @return ChangeInfoResult.
2584 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2586 /* Properties which are handled as a whole */
2588 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2589 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2591 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2592 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2598 /* Properties which are handled per item */
2599 ChangeInfoResult ret
= CIR_SUCCESS
;
2600 for (int i
= 0; i
< numinfo
; i
++) {
2602 case 0x08: { // Cost base factor
2603 int factor
= buf
->ReadByte();
2604 uint price
= gvid
+ i
;
2606 if (price
< PR_END
) {
2607 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2609 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2614 case 0x0A: { // Currency display names
2615 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2616 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2618 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2619 _currency_specs
[curidx
].name
= newone
;
2624 case 0x0B: { // Currency multipliers
2625 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2626 uint32 rate
= buf
->ReadDWord();
2628 if (curidx
< CURRENCY_END
) {
2629 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2630 * which OTTD does not. For this reason, divide grf value by 1000,
2631 * to be compatible */
2632 _currency_specs
[curidx
].rate
= rate
/ 1000;
2634 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2639 case 0x0C: { // Currency options
2640 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2641 uint16 options
= buf
->ReadWord();
2643 if (curidx
< CURRENCY_END
) {
2644 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2645 _currency_specs
[curidx
].separator
[1] = '\0';
2646 /* By specifying only one bit, we prevent errors,
2647 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2648 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2650 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2655 case 0x0D: { // Currency prefix symbol
2656 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2657 uint32 tempfix
= buf
->ReadDWord();
2659 if (curidx
< CURRENCY_END
) {
2660 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2661 _currency_specs
[curidx
].prefix
[4] = 0;
2663 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2668 case 0x0E: { // Currency suffix symbol
2669 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2670 uint32 tempfix
= buf
->ReadDWord();
2672 if (curidx
< CURRENCY_END
) {
2673 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2674 _currency_specs
[curidx
].suffix
[4] = 0;
2676 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2681 case 0x0F: { // Euro introduction dates
2682 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2683 Year year_euro
= buf
->ReadWord();
2685 if (curidx
< CURRENCY_END
) {
2686 _currency_specs
[curidx
].to_euro
= year_euro
;
2688 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2693 case 0x10: // Snow line height table
2694 if (numinfo
> 1 || IsSnowLineSet()) {
2695 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2696 } else if (buf
->Remaining() < SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
) {
2697 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2699 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2701 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2702 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2703 table
[i
][j
] = buf
->ReadByte();
2704 if (_cur
.grffile
->grf_version
>= 8) {
2705 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2707 if (table
[i
][j
] >= 128) {
2711 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2720 case 0x11: // GRF match for engine allocation
2721 /* This is loaded during the reservation stage, so just skip it here. */
2722 /* Each entry is 8 bytes. */
2726 case 0x13: // Gender translation table
2727 case 0x14: // Case translation table
2728 case 0x15: { // Plural form translation
2729 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2730 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : NULL
;
2732 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2733 /* Skip over the data. */
2737 while (buf
->ReadByte() != 0) {
2744 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2747 uint plural_form
= buf
->ReadByte();
2748 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2749 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2751 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2756 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2757 while (newgrf_id
!= 0) {
2758 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2760 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2761 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2762 * is just a subset of UTF8, or they need the bigger UTF8 characters
2763 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2765 size_t len
= Utf8Decode(&c
, name
);
2766 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2768 LanguageMap::Mapping map
;
2769 map
.newgrf_id
= newgrf_id
;
2771 map
.openttd_id
= lang
->GetGenderIndex(name
);
2772 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2773 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2775 *_cur
.grffile
->language_map
[curidx
].gender_map
.Append() = map
;
2778 map
.openttd_id
= lang
->GetCaseIndex(name
);
2779 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2780 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2782 *_cur
.grffile
->language_map
[curidx
].case_map
.Append() = map
;
2785 newgrf_id
= buf
->ReadByte();
2799 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2801 /* Properties which are handled as a whole */
2803 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2804 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2806 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2807 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2813 /* Properties which are handled per item */
2814 ChangeInfoResult ret
= CIR_SUCCESS
;
2815 for (int i
= 0; i
< numinfo
; i
++) {
2817 case 0x08: // Cost base factor
2818 case 0x15: // Plural form translation
2822 case 0x0A: // Currency display names
2823 case 0x0C: // Currency options
2824 case 0x0F: // Euro introduction dates
2828 case 0x0B: // Currency multipliers
2829 case 0x0D: // Currency prefix symbol
2830 case 0x0E: // Currency suffix symbol
2834 case 0x10: // Snow line height table
2835 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2838 case 0x11: { // GRF match for engine allocation
2839 uint32 s
= buf
->ReadDWord();
2840 uint32 t
= buf
->ReadDWord();
2841 SetNewGRFOverride(s
, t
);
2845 case 0x13: // Gender translation table
2846 case 0x14: // Case translation table
2847 while (buf
->ReadByte() != 0) {
2863 * Define properties for cargoes
2864 * @param cid Local ID of the cargo.
2865 * @param numinfo Number of subsequent IDs to change the property for.
2866 * @param prop The property to change.
2867 * @param buf The property value.
2868 * @return ChangeInfoResult.
2870 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2872 ChangeInfoResult ret
= CIR_SUCCESS
;
2874 if (cid
+ numinfo
> NUM_CARGO
) {
2875 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2876 return CIR_INVALID_ID
;
2879 for (int i
= 0; i
< numinfo
; i
++) {
2880 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2883 case 0x08: // Bit number of cargo
2884 cs
->bitnum
= buf
->ReadByte();
2885 if (cs
->IsValid()) {
2886 cs
->grffile
= _cur
.grffile
;
2887 SetBit(_cargo_mask
, cid
+ i
);
2889 ClrBit(_cargo_mask
, cid
+ i
);
2893 case 0x09: // String ID for cargo type name
2894 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2897 case 0x0A: // String for 1 unit of cargo
2898 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2901 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2902 case 0x1B: // String for cargo units
2903 /* String for units of cargo. This is different in OpenTTD
2904 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2905 * Property 1B is used to set OpenTTD's behaviour. */
2906 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2909 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2910 case 0x1C: // String for any amount of cargo
2911 /* Strings for an amount of cargo. This is different in OpenTTD
2912 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2913 * Property 1C is used to set OpenTTD's behaviour. */
2914 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2917 case 0x0D: // String for two letter cargo abbreviation
2918 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2921 case 0x0E: // Sprite ID for cargo icon
2922 cs
->sprite
= buf
->ReadWord();
2925 case 0x0F: // Weight of one unit of cargo
2926 cs
->weight
= buf
->ReadByte();
2929 case 0x10: // Used for payment calculation
2930 cs
->transit_days
[0] = buf
->ReadByte();
2933 case 0x11: // Used for payment calculation
2934 cs
->transit_days
[1] = buf
->ReadByte();
2937 case 0x12: // Base cargo price
2938 cs
->initial_payment
= buf
->ReadDWord();
2941 case 0x13: // Colour for station rating bars
2942 cs
->rating_colour
= buf
->ReadByte();
2945 case 0x14: // Colour for cargo graph
2946 cs
->legend_colour
= buf
->ReadByte();
2949 case 0x15: // Freight status
2950 cs
->is_freight
= (buf
->ReadByte() != 0);
2953 case 0x16: // Cargo classes
2954 cs
->classes
= buf
->ReadWord();
2957 case 0x17: // Cargo label
2958 cs
->label
= buf
->ReadDWord();
2959 cs
->label
= BSWAP32(cs
->label
);
2962 case 0x18: { // Town growth substitute type
2963 uint8 substitute_type
= buf
->ReadByte();
2965 switch (substitute_type
) {
2966 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
2967 case 0x02: cs
->town_effect
= TE_MAIL
; break;
2968 case 0x05: cs
->town_effect
= TE_GOODS
; break;
2969 case 0x09: cs
->town_effect
= TE_WATER
; break;
2970 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
2972 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
2974 case 0xFF: cs
->town_effect
= TE_NONE
; break;
2979 case 0x19: // Town growth coefficient
2980 cs
->multipliertowngrowth
= buf
->ReadWord();
2983 case 0x1A: // Bitmask of callbacks to use
2984 cs
->callback_mask
= buf
->ReadByte();
2987 case 0x1D: // Vehicle capacity muliplier
2988 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3002 * Define properties for sound effects
3003 * @param sid Local ID of the sound.
3004 * @param numinfo Number of subsequent IDs to change the property for.
3005 * @param prop The property to change.
3006 * @param buf The property value.
3007 * @return ChangeInfoResult.
3009 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3011 ChangeInfoResult ret
= CIR_SUCCESS
;
3013 if (_cur
.grffile
->sound_offset
== 0) {
3014 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3015 return CIR_INVALID_ID
;
3018 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3019 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3020 return CIR_INVALID_ID
;
3023 for (int i
= 0; i
< numinfo
; i
++) {
3024 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3027 case 0x08: // Relative volume
3028 sound
->volume
= buf
->ReadByte();
3031 case 0x09: // Priority
3032 sound
->priority
= buf
->ReadByte();
3035 case 0x0A: { // Override old sound
3036 SoundID orig_sound
= buf
->ReadByte();
3038 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3039 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3041 SoundEntry
*old_sound
= GetSound(orig_sound
);
3043 /* Literally copy the data of the new sound over the original */
3044 *old_sound
= *sound
;
3059 * Ignore an industry tile property
3060 * @param prop The property to ignore.
3061 * @param buf The property value.
3062 * @return ChangeInfoResult.
3064 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3066 ChangeInfoResult ret
= CIR_SUCCESS
;
3093 * Define properties for industry tiles
3094 * @param indtid Local ID of the industry tile.
3095 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3096 * @param prop The property to change.
3097 * @param buf The property value.
3098 * @return ChangeInfoResult.
3100 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3102 ChangeInfoResult ret
= CIR_SUCCESS
;
3104 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3105 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3106 return CIR_INVALID_ID
;
3109 /* Allocate industry tile specs if they haven't been allocated already. */
3110 if (_cur
.grffile
->indtspec
== NULL
) {
3111 _cur
.grffile
->indtspec
= CallocT
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3114 for (int i
= 0; i
< numinfo
; i
++) {
3115 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3117 if (prop
!= 0x08 && tsp
== NULL
) {
3118 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3119 if (cir
> ret
) ret
= cir
;
3124 case 0x08: { // Substitute industry tile type
3125 IndustryTileSpec
**tilespec
= &_cur
.grffile
->indtspec
[indtid
+ i
];
3126 byte subs_id
= buf
->ReadByte();
3128 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3129 /* The substitute id must be one of the original industry tile. */
3130 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3134 /* Allocate space for this industry. */
3135 if (*tilespec
== NULL
) {
3136 *tilespec
= CallocT
<IndustryTileSpec
>(1);
3139 memcpy(tsp
, &_industry_tile_specs
[subs_id
], sizeof(_industry_tile_specs
[subs_id
]));
3140 tsp
->enabled
= true;
3142 /* A copied tile should not have the animation infos copied too.
3143 * The anim_state should be left untouched, though
3144 * It is up to the author to animate them himself */
3145 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3146 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3148 tsp
->grf_prop
.local_id
= indtid
+ i
;
3149 tsp
->grf_prop
.subst_id
= subs_id
;
3150 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3151 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3156 case 0x09: { // Industry tile override
3157 byte ovrid
= buf
->ReadByte();
3159 /* The industry being overridden must be an original industry. */
3160 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3165 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3169 case 0x0A: // Tile acceptance
3172 uint16 acctp
= buf
->ReadWord();
3173 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3174 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3178 case 0x0D: // Land shape flags
3179 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3182 case 0x0E: // Callback mask
3183 tsp
->callback_mask
= buf
->ReadByte();
3186 case 0x0F: // Animation information
3187 tsp
->animation
.frames
= buf
->ReadByte();
3188 tsp
->animation
.status
= buf
->ReadByte();
3191 case 0x10: // Animation speed
3192 tsp
->animation
.speed
= buf
->ReadByte();
3195 case 0x11: // Triggers for callback 25
3196 tsp
->animation
.triggers
= buf
->ReadByte();
3199 case 0x12: // Special flags
3200 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3213 * Ignore an industry property
3214 * @param prop The property to ignore.
3215 * @param buf The property value.
3216 * @return ChangeInfoResult.
3218 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3220 ChangeInfoResult ret
= CIR_SUCCESS
;
3258 byte num_table
= buf
->ReadByte();
3259 for (byte j
= 0; j
< num_table
; j
++) {
3260 for (uint k
= 0;; k
++) {
3261 byte x
= buf
->ReadByte();
3262 if (x
== 0xFE && k
== 0) {
3268 byte y
= buf
->ReadByte();
3269 if (x
== 0 && y
== 0x80) break;
3271 byte gfx
= buf
->ReadByte();
3272 if (gfx
== 0xFE) buf
->ReadWord();
3279 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3283 byte number_of_sounds
= buf
->ReadByte();
3284 for (uint8 j
= 0; j
< number_of_sounds
; j
++) {
3298 * Validate the industry layout; e.g. to prevent duplicate tiles.
3299 * @param layout The layout to check.
3300 * @param size The size of the layout.
3301 * @return True if the layout is deemed valid.
3303 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3305 for (int i
= 0; i
< size
- 1; i
++) {
3306 for (int j
= i
+ 1; j
< size
; j
++) {
3307 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3308 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3316 /** Clean the tile table of the IndustrySpec if it's needed. */
3317 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3319 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3320 for (int j
= 0; j
< ind
->num_table
; j
++) {
3321 /* remove the individual layouts */
3322 free(ind
->table
[j
]);
3324 /* remove the layouts pointers */
3331 * Define properties for industries
3332 * @param indid Local ID of the industry.
3333 * @param numinfo Number of subsequent industry IDs to change the property for.
3334 * @param prop The property to change.
3335 * @param buf The property value.
3336 * @return ChangeInfoResult.
3338 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3340 ChangeInfoResult ret
= CIR_SUCCESS
;
3342 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3343 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3344 return CIR_INVALID_ID
;
3347 /* Allocate industry specs if they haven't been allocated already. */
3348 if (_cur
.grffile
->industryspec
== NULL
) {
3349 _cur
.grffile
->industryspec
= CallocT
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3352 for (int i
= 0; i
< numinfo
; i
++) {
3353 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3355 if (prop
!= 0x08 && indsp
== NULL
) {
3356 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3357 if (cir
> ret
) ret
= cir
;
3362 case 0x08: { // Substitute industry type
3363 IndustrySpec
**indspec
= &_cur
.grffile
->industryspec
[indid
+ i
];
3364 byte subs_id
= buf
->ReadByte();
3366 if (subs_id
== 0xFF) {
3367 /* Instead of defining a new industry, a substitute industry id
3368 * of 0xFF disables the old industry with the current id. */
3369 _industry_specs
[indid
+ i
].enabled
= false;
3371 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3372 /* The substitute id must be one of the original industry. */
3373 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3377 /* Allocate space for this industry.
3378 * Only need to do it once. If ever it is called again, it should not
3380 if (*indspec
== NULL
) {
3381 *indspec
= CallocT
<IndustrySpec
>(1);
3384 memcpy(indsp
, &_origin_industry_specs
[subs_id
], sizeof(_industry_specs
[subs_id
]));
3385 indsp
->enabled
= true;
3386 indsp
->grf_prop
.local_id
= indid
+ i
;
3387 indsp
->grf_prop
.subst_id
= subs_id
;
3388 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3389 /* If the grf industry needs to check its surounding upon creation, it should
3390 * rely on callbacks, not on the original placement functions */
3391 indsp
->check_proc
= CHECK_NOTHING
;
3396 case 0x09: { // Industry type override
3397 byte ovrid
= buf
->ReadByte();
3399 /* The industry being overridden must be an original industry. */
3400 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3401 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3404 indsp
->grf_prop
.override
= ovrid
;
3405 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3409 case 0x0A: { // Set industry layout(s)
3410 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3411 /* We read the total size in bytes, but we can't rely on the
3412 * newgrf to provide a sane value. First assume the value is
3413 * sane but later on we make sure we enlarge the array if the
3414 * newgrf contains more data. Each tile uses either 3 or 5
3415 * bytes, so to play it safe we assume 3. */
3416 uint32 def_num_tiles
= buf
->ReadDWord() / 3 + 1;
3417 IndustryTileTable
**tile_table
= CallocT
<IndustryTileTable
*>(new_num_layouts
); // Table with tiles to compose an industry
3418 IndustryTileTable
*itt
= CallocT
<IndustryTileTable
>(def_num_tiles
); // Temporary array to read the tile layouts from the GRF
3420 const IndustryTileTable
*copy_from
;
3423 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3424 for (uint k
= 0;; k
++) {
3425 if (k
>= def_num_tiles
) {
3426 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3427 /* Size reported by newgrf was not big enough so enlarge the array. */
3429 itt
= ReallocT
<IndustryTileTable
>(itt
, def_num_tiles
);
3432 itt
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3434 if (itt
[k
].ti
.x
== 0xFE && k
== 0) {
3435 /* This means we have to borrow the layout from an old industry */
3436 IndustryType type
= buf
->ReadByte(); // industry holding required layout
3437 byte laynbr
= buf
->ReadByte(); // layout number to borrow
3439 copy_from
= _origin_industry_specs
[type
].table
[laynbr
];
3440 for (size
= 1;; size
++) {
3441 if (copy_from
[size
- 1].ti
.x
== -0x80 && copy_from
[size
- 1].ti
.y
== 0) break;
3446 itt
[k
].ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3448 if (itt
[k
].ti
.x
== 0 && itt
[k
].ti
.y
== 0x80) {
3449 /* Not the same terminator. The one we are using is rather
3450 x = -80, y = x . So, adjust it. */
3451 itt
[k
].ti
.x
= -0x80;
3460 itt
[k
].gfx
= buf
->ReadByte();
3462 if (itt
[k
].gfx
== 0xFE) {
3463 /* Use a new tile from this GRF */
3464 int local_tile_id
= buf
->ReadWord();
3466 /* Read the ID from the _industile_mngr. */
3467 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3469 if (tempid
== INVALID_INDUSTRYTILE
) {
3470 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3472 /* Declared as been valid, can be used */
3473 itt
[k
].gfx
= tempid
;
3477 } else if (itt
[k
].gfx
== 0xFF) {
3478 itt
[k
].ti
.x
= (int8
)GB(itt
[k
].ti
.x
, 0, 8);
3479 itt
[k
].ti
.y
= (int8
)GB(itt
[k
].ti
.y
, 0, 8);
3481 /* When there were only 256x256 maps, TileIndex was a uint16 and
3482 * itt[k].ti was just a TileIndexDiff that was added to it.
3483 * As such negative "x" values were shifted into the "y" position.
3484 * x = -1, y = 1 -> x = 255, y = 0
3485 * Since GRF version 8 the position is interpreted as pair of independent int8.
3486 * For GRF version < 8 we need to emulate the old shifting behaviour.
3488 if (_cur
.grffile
->grf_version
< 8 && itt
[k
].ti
.x
< 0) itt
[k
].ti
.y
+= 1;
3492 if (!ValidateIndustryLayout(copy_from
, size
)) {
3493 /* The industry layout was not valid, so skip this one. */
3494 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3498 tile_table
[j
] = CallocT
<IndustryTileTable
>(size
);
3499 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3503 for (int i
= 0; i
< new_num_layouts
; i
++) {
3504 free(tile_table
[i
]);
3511 /* Clean the tile table if it was already set by a previous prop A. */
3512 CleanIndustryTileTable(indsp
);
3513 /* Install final layout construction in the industry spec */
3514 indsp
->num_table
= new_num_layouts
;
3515 indsp
->table
= tile_table
;
3516 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3521 case 0x0B: // Industry production flags
3522 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3525 case 0x0C: // Industry closure message
3526 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3529 case 0x0D: // Production increase message
3530 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3533 case 0x0E: // Production decrease message
3534 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3537 case 0x0F: // Fund cost multiplier
3538 indsp
->cost_multiplier
= buf
->ReadByte();
3541 case 0x10: // Production cargo types
3542 for (byte j
= 0; j
< 2; j
++) {
3543 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3547 case 0x11: // Acceptance cargo types
3548 for (byte j
= 0; j
< 3; j
++) {
3549 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3551 buf
->ReadByte(); // Unnused, eat it up
3554 case 0x12: // Production multipliers
3556 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3559 case 0x14: // Minimal amount of cargo distributed
3560 indsp
->minimal_cargo
= buf
->ReadByte();
3563 case 0x15: { // Random sound effects
3564 indsp
->number_of_sounds
= buf
->ReadByte();
3565 uint8
*sounds
= MallocT
<uint8
>(indsp
->number_of_sounds
);
3568 for (uint8 j
= 0; j
< indsp
->number_of_sounds
; j
++) {
3569 sounds
[j
] = buf
->ReadByte();
3576 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3577 free(indsp
->random_sounds
);
3579 indsp
->random_sounds
= sounds
;
3580 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3584 case 0x16: // Conflicting industry types
3585 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3588 case 0x17: // Probability in random game
3589 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3592 case 0x18: // Probability during gameplay
3593 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3596 case 0x19: // Map colour
3597 indsp
->map_colour
= buf
->ReadByte();
3600 case 0x1A: // Special industry flags to define special behavior
3601 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3604 case 0x1B: // New industry text ID
3605 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3608 case 0x1C: // Input cargo multipliers for the three input cargo types
3611 uint32 multiples
= buf
->ReadDWord();
3612 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3613 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3617 case 0x1F: // Industry name
3618 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3621 case 0x20: // Prospecting success chance
3622 indsp
->prospecting_chance
= buf
->ReadDWord();
3625 case 0x21: // Callback mask
3626 case 0x22: { // Callback additional mask
3627 byte aflag
= buf
->ReadByte();
3628 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3632 case 0x23: // removal cost multiplier
3633 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3636 case 0x24: { // name for nearby station
3637 uint16 str
= buf
->ReadWord();
3639 indsp
->station_name
= STR_NULL
;
3641 AddStringForMapping(str
, &indsp
->station_name
);
3656 * Create a copy of the tile table so it can be freed later
3658 * @param as The AirportSpec to copy the arrays of.
3660 static void DuplicateTileTable(AirportSpec
*as
)
3662 AirportTileTable
**table_list
= MallocT
<AirportTileTable
*>(as
->num_table
);
3663 for (int i
= 0; i
< as
->num_table
; i
++) {
3665 const AirportTileTable
*it
= as
->table
[0];
3668 } while ((++it
)->ti
.x
!= -0x80);
3669 table_list
[i
] = MallocT
<AirportTileTable
>(num_tiles
);
3670 MemCpyT(table_list
[i
], as
->table
[i
], num_tiles
);
3672 as
->table
= table_list
;
3673 HangarTileTable
*depot_table
= MallocT
<HangarTileTable
>(as
->nof_depots
);
3674 MemCpyT(depot_table
, as
->depot_table
, as
->nof_depots
);
3675 as
->depot_table
= depot_table
;
3676 Direction
*rotation
= MallocT
<Direction
>(as
->num_table
);
3677 MemCpyT(rotation
, as
->rotation
, as
->num_table
);
3678 as
->rotation
= rotation
;
3682 * Define properties for airports
3683 * @param airport Local ID of the airport.
3684 * @param numinfo Number of subsequent airport IDs to change the property for.
3685 * @param prop The property to change.
3686 * @param buf The property value.
3687 * @return ChangeInfoResult.
3689 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3691 ChangeInfoResult ret
= CIR_SUCCESS
;
3693 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3694 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3695 return CIR_INVALID_ID
;
3698 /* Allocate industry specs if they haven't been allocated already. */
3699 if (_cur
.grffile
->airportspec
== NULL
) {
3700 _cur
.grffile
->airportspec
= CallocT
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3703 for (int i
= 0; i
< numinfo
; i
++) {
3704 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3706 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3707 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3708 return CIR_INVALID_ID
;
3712 case 0x08: { // Modify original airport
3713 byte subs_id
= buf
->ReadByte();
3715 if (subs_id
== 0xFF) {
3716 /* Instead of defining a new airport, an airport id
3717 * of 0xFF disables the old airport with the current id. */
3718 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3720 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3721 /* The substitute id must be one of the original airports. */
3722 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3726 AirportSpec
**spec
= &_cur
.grffile
->airportspec
[airport
+ i
];
3727 /* Allocate space for this airport.
3728 * Only need to do it once. If ever it is called again, it should not
3730 if (*spec
== NULL
) {
3731 *spec
= MallocT
<AirportSpec
>(1);
3734 memcpy(as
, AirportSpec::GetWithoutOverride(subs_id
), sizeof(*as
));
3736 as
->grf_prop
.local_id
= airport
+ i
;
3737 as
->grf_prop
.subst_id
= subs_id
;
3738 as
->grf_prop
.grffile
= _cur
.grffile
;
3739 /* override the default airport */
3740 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3741 /* Create a copy of the original tiletable so it can be freed later. */
3742 DuplicateTileTable(as
);
3747 case 0x0A: { // Set airport layout
3749 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3750 as
->rotation
= MallocT
<Direction
>(as
->num_table
);
3751 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3752 AirportTileTable
**tile_table
= CallocT
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3753 AirportTileTable
*att
= CallocT
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3755 const AirportTileTable
*copy_from
;
3757 for (byte j
= 0; j
< as
->num_table
; j
++) {
3758 const_cast<Direction
&>(as
->rotation
[j
]) = (Direction
)buf
->ReadByte();
3759 for (int k
= 0;; k
++) {
3760 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3761 att
[k
].ti
.y
= buf
->ReadByte();
3763 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3764 /* Not the same terminator. The one we are using is rather
3765 * x = -80, y = 0 . So, adjust it. */
3766 att
[k
].ti
.x
= -0x80;
3775 att
[k
].gfx
= buf
->ReadByte();
3777 if (att
[k
].gfx
== 0xFE) {
3778 /* Use a new tile from this GRF */
3779 int local_tile_id
= buf
->ReadWord();
3781 /* Read the ID from the _airporttile_mngr. */
3782 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3784 if (tempid
== INVALID_AIRPORTTILE
) {
3785 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3787 /* Declared as been valid, can be used */
3788 att
[k
].gfx
= tempid
;
3792 } else if (att
[k
].gfx
== 0xFF) {
3793 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3794 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3797 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3798 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3799 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3801 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3802 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3805 tile_table
[j
] = CallocT
<AirportTileTable
>(size
);
3806 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3808 /* Install final layout construction in the airport spec */
3809 as
->table
= tile_table
;
3812 for (int i
= 0; i
< as
->num_table
; i
++) {
3813 free(tile_table
[i
]);
3823 as
->min_year
= buf
->ReadWord();
3824 as
->max_year
= buf
->ReadWord();
3825 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3829 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3833 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3837 as
->noise_level
= buf
->ReadByte();
3841 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3844 case 0x11: // Maintenance cost factor
3845 as
->maintenance_cost
= buf
->ReadWord();
3858 * Ignore properties for objects
3859 * @param prop The property to ignore.
3860 * @param buf The property value.
3861 * @return ChangeInfoResult.
3863 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3865 ChangeInfoResult ret
= CIR_SUCCESS
;
3902 * Define properties for objects
3903 * @param id Local ID of the object.
3904 * @param numinfo Number of subsequent objectIDs to change the property for.
3905 * @param prop The property to change.
3906 * @param buf The property value.
3907 * @return ChangeInfoResult.
3909 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
3911 ChangeInfoResult ret
= CIR_SUCCESS
;
3913 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
3914 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
3915 return CIR_INVALID_ID
;
3918 /* Allocate object specs if they haven't been allocated already. */
3919 if (_cur
.grffile
->objectspec
== NULL
) {
3920 _cur
.grffile
->objectspec
= CallocT
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
3923 for (int i
= 0; i
< numinfo
; i
++) {
3924 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
3926 if (prop
!= 0x08 && spec
== NULL
) {
3927 /* If the object property 08 is not yet set, ignore this property */
3928 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
3929 if (cir
> ret
) ret
= cir
;
3934 case 0x08: { // Class ID
3935 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
3937 /* Allocate space for this object. */
3938 if (*ospec
== NULL
) {
3939 *ospec
= CallocT
<ObjectSpec
>(1);
3940 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
3943 /* Swap classid because we read it in BE. */
3944 uint32 classid
= buf
->ReadDWord();
3945 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
3946 (*ospec
)->enabled
= true;
3950 case 0x09: { // Class name
3951 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
3952 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
3956 case 0x0A: // Object name
3957 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
3960 case 0x0B: // Climate mask
3961 spec
->climate
= buf
->ReadByte();
3965 spec
->size
= buf
->ReadByte();
3968 case 0x0D: // Build cost multipler
3969 spec
->build_cost_multiplier
= buf
->ReadByte();
3970 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
3973 case 0x0E: // Introduction date
3974 spec
->introduction_date
= buf
->ReadDWord();
3977 case 0x0F: // End of life
3978 spec
->end_of_life_date
= buf
->ReadDWord();
3982 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
3983 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
3986 case 0x11: // Animation info
3987 spec
->animation
.frames
= buf
->ReadByte();
3988 spec
->animation
.status
= buf
->ReadByte();
3991 case 0x12: // Animation speed
3992 spec
->animation
.speed
= buf
->ReadByte();
3995 case 0x13: // Animation triggers
3996 spec
->animation
.triggers
= buf
->ReadWord();
3999 case 0x14: // Removal cost multiplier
4000 spec
->clear_cost_multiplier
= buf
->ReadByte();
4003 case 0x15: // Callback mask
4004 spec
->callback_mask
= buf
->ReadWord();
4007 case 0x16: // Building height
4008 spec
->height
= buf
->ReadByte();
4012 spec
->views
= buf
->ReadByte();
4013 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4014 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4019 case 0x18: // Amount placed on 256^2 map on map creation
4020 spec
->generate_amount
= buf
->ReadByte();
4033 * Define properties for railtypes
4034 * @param id ID of the railtype.
4035 * @param numinfo Number of subsequent IDs to change the property for.
4036 * @param prop The property to change.
4037 * @param buf The property value.
4038 * @return ChangeInfoResult.
4040 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4042 ChangeInfoResult ret
= CIR_SUCCESS
;
4044 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4046 if (id
+ numinfo
> RAILTYPE_END
) {
4047 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4048 return CIR_INVALID_ID
;
4051 for (int i
= 0; i
< numinfo
; i
++) {
4052 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4053 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4055 RailtypeInfo
*rti
= &_railtypes
[rt
];
4058 case 0x08: // Label of rail type
4059 /* Skipped here as this is loaded during reservation stage. */
4063 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4064 uint16 str
= buf
->ReadWord();
4065 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4066 if (_cur
.grffile
->grf_version
< 8) {
4067 AddStringForMapping(str
, &rti
->strings
.name
);
4072 case 0x0A: // Menu text of railtype
4073 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4076 case 0x0B: // Build window caption
4077 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4080 case 0x0C: // Autoreplace text
4081 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4084 case 0x0D: // New locomotive text
4085 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4088 case 0x0E: // Compatible railtype list
4089 case 0x0F: // Powered railtype list
4090 case 0x18: // Railtype list required for date introduction
4091 case 0x19: // Introduced railtype list
4093 /* Rail type compatibility bits are added to the existing bits
4094 * to allow multiple GRFs to modify compatibility with the
4095 * default rail types. */
4096 int n
= buf
->ReadByte();
4097 for (int j
= 0; j
!= n
; j
++) {
4098 RailTypeLabel label
= buf
->ReadDWord();
4099 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4100 if (rt
!= INVALID_RAILTYPE
) {
4102 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4103 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4104 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4105 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4112 case 0x10: // Rail Type flags
4113 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4116 case 0x11: // Curve speed advantage
4117 rti
->curve_speed
= buf
->ReadByte();
4120 case 0x12: // Station graphic
4121 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4124 case 0x13: // Construction cost factor
4125 rti
->cost_multiplier
= buf
->ReadWord();
4128 case 0x14: // Speed limit
4129 rti
->max_speed
= buf
->ReadWord();
4132 case 0x15: // Acceleration model
4133 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4136 case 0x16: // Map colour
4137 rti
->map_colour
= buf
->ReadByte();
4140 case 0x17: // Introduction date
4141 rti
->introduction_date
= buf
->ReadDWord();
4144 case 0x1A: // Sort order
4145 rti
->sorting_order
= buf
->ReadByte();
4148 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4149 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4152 case 0x1C: // Maintenance cost factor
4153 rti
->maintenance_multiplier
= buf
->ReadWord();
4156 case 0x1D: // Alternate rail type label list
4157 /* Skipped here as this is loaded during reservation stage. */
4158 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4170 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4172 ChangeInfoResult ret
= CIR_SUCCESS
;
4174 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4176 if (id
+ numinfo
> RAILTYPE_END
) {
4177 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4178 return CIR_INVALID_ID
;
4181 for (int i
= 0; i
< numinfo
; i
++) {
4183 case 0x08: // Label of rail type
4185 RailTypeLabel rtl
= buf
->ReadDWord();
4188 RailType rt
= GetRailTypeByLabel(rtl
, false);
4189 if (rt
== INVALID_RAILTYPE
) {
4190 /* Set up new rail type */
4191 rt
= AllocateRailType(rtl
);
4194 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4198 case 0x09: // Toolbar caption of railtype
4199 case 0x0A: // Menu text
4200 case 0x0B: // Build window caption
4201 case 0x0C: // Autoreplace text
4202 case 0x0D: // New loco
4203 case 0x13: // Construction cost
4204 case 0x14: // Speed limit
4205 case 0x1B: // Name of railtype
4206 case 0x1C: // Maintenance cost factor
4210 case 0x1D: // Alternate rail type label list
4211 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4212 int n
= buf
->ReadByte();
4213 for (int j
= 0; j
!= n
; j
++) {
4214 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = BSWAP32(buf
->ReadDWord());
4218 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4221 case 0x0E: // Compatible railtype list
4222 case 0x0F: // Powered railtype list
4223 case 0x18: // Railtype list required for date introduction
4224 case 0x19: // Introduced railtype list
4225 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4228 case 0x10: // Rail Type flags
4229 case 0x11: // Curve speed advantage
4230 case 0x12: // Station graphic
4231 case 0x15: // Acceleration model
4232 case 0x16: // Map colour
4233 case 0x1A: // Sort order
4237 case 0x17: // Introduction date
4250 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4252 ChangeInfoResult ret
= CIR_SUCCESS
;
4254 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4255 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4256 return CIR_INVALID_ID
;
4259 /* Allocate airport tile specs if they haven't been allocated already. */
4260 if (_cur
.grffile
->airtspec
== NULL
) {
4261 _cur
.grffile
->airtspec
= CallocT
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4264 for (int i
= 0; i
< numinfo
; i
++) {
4265 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4267 if (prop
!= 0x08 && tsp
== NULL
) {
4268 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4269 return CIR_INVALID_ID
;
4273 case 0x08: { // Substitute airport tile type
4274 AirportTileSpec
**tilespec
= &_cur
.grffile
->airtspec
[airtid
+ i
];
4275 byte subs_id
= buf
->ReadByte();
4277 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4278 /* The substitute id must be one of the original airport tiles. */
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4283 /* Allocate space for this airport tile. */
4284 if (*tilespec
== NULL
) {
4285 *tilespec
= CallocT
<AirportTileSpec
>(1);
4288 memcpy(tsp
, AirportTileSpec::Get(subs_id
), sizeof(AirportTileSpec
));
4289 tsp
->enabled
= true;
4291 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4293 tsp
->grf_prop
.local_id
= airtid
+ i
;
4294 tsp
->grf_prop
.subst_id
= subs_id
;
4295 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4296 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4301 case 0x09: { // Airport tile override
4302 byte override
= buf
->ReadByte();
4304 /* The airport tile being overridden must be an original airport tile. */
4305 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4306 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4310 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4314 case 0x0E: // Callback mask
4315 tsp
->callback_mask
= buf
->ReadByte();
4318 case 0x0F: // Animation information
4319 tsp
->animation
.frames
= buf
->ReadByte();
4320 tsp
->animation
.status
= buf
->ReadByte();
4323 case 0x10: // Animation speed
4324 tsp
->animation
.speed
= buf
->ReadByte();
4327 case 0x11: // Animation triggers
4328 tsp
->animation
.triggers
= buf
->ReadByte();
4340 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4343 default: NOT_REACHED();
4346 /* Error has already been printed; just stop parsing */
4353 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4357 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4360 case CIR_INVALID_ID
: {
4361 /* No debug message for an invalid ID, as it has already been output */
4362 GRFError
*error
= DisableGrf(cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4363 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4370 static void FeatureChangeInfo(ByteReader
*buf
)
4372 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4375 * B num-props how many properties to change per vehicle/station
4376 * B num-info how many vehicles/stations to change
4377 * E id ID of first vehicle/station to change, if num-info is
4378 * greater than one, this one and the following
4379 * vehicles/stations will be changed
4380 * B property what property to change, depends on the feature
4381 * V new-info new bytes of info (variable size; depends on properties) */
4383 static const VCI_Handler handler
[] = {
4384 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4385 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4386 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4387 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4388 /* GSF_STATIONS */ StationChangeInfo
,
4389 /* GSF_CANALS */ CanalChangeInfo
,
4390 /* GSF_BRIDGES */ BridgeChangeInfo
,
4391 /* GSF_HOUSES */ TownHouseChangeInfo
,
4392 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4393 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4394 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4395 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4396 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4397 /* GSF_AIRPORTS */ AirportChangeInfo
,
4398 /* GSF_SIGNALS */ NULL
,
4399 /* GSF_OBJECTS */ ObjectChangeInfo
,
4400 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4401 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4404 uint8 feature
= buf
->ReadByte();
4405 uint8 numprops
= buf
->ReadByte();
4406 uint numinfo
= buf
->ReadByte();
4407 uint engine
= buf
->ReadExtendedByte();
4409 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410 feature
, numprops
, engine
, numinfo
);
4412 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4413 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4417 /* Mark the feature as used by the grf */
4418 SetBit(_cur
.grffile
->grf_features
, feature
);
4420 while (numprops
-- && buf
->HasData()) {
4421 uint8 prop
= buf
->ReadByte();
4423 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4424 if (HandleChangeInfoResult("FeatureChangeInfo", cir
, feature
, prop
)) return;
4428 /* Action 0x00 (GLS_SAFETYSCAN) */
4429 static void SafeChangeInfo(ByteReader
*buf
)
4431 uint8 feature
= buf
->ReadByte();
4432 uint8 numprops
= buf
->ReadByte();
4433 uint numinfo
= buf
->ReadByte();
4434 buf
->ReadExtendedByte(); // id
4436 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4437 uint8 prop
= buf
->ReadByte();
4438 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4439 * is considered safe. */
4440 if (prop
== 0x0D) return;
4441 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4442 uint8 prop
= buf
->ReadByte();
4443 /* Engine ID Mappings are safe, if the source is static */
4445 bool is_safe
= true;
4446 for (uint i
= 0; i
< numinfo
; i
++) {
4447 uint32 s
= buf
->ReadDWord();
4448 buf
->ReadDWord(); // dest
4449 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4450 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4455 if (is_safe
) return;
4459 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4461 /* Skip remainder of GRF */
4462 _cur
.skip_sprites
= -1;
4465 /* Action 0x00 (GLS_RESERVE) */
4466 static void ReserveChangeInfo(ByteReader
*buf
)
4468 uint8 feature
= buf
->ReadByte();
4470 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return;
4472 uint8 numprops
= buf
->ReadByte();
4473 uint8 numinfo
= buf
->ReadByte();
4474 uint8 index
= buf
->ReadExtendedByte();
4476 while (numprops
-- && buf
->HasData()) {
4477 uint8 prop
= buf
->ReadByte();
4478 ChangeInfoResult cir
= CIR_SUCCESS
;
4481 default: NOT_REACHED();
4483 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4487 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4491 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4495 if (HandleChangeInfoResult("ReserveChangeInfo", cir
, feature
, prop
)) return;
4500 static void NewSpriteSet(ByteReader
*buf
)
4502 /* Basic format: <01> <feature> <num-sets> <num-ent>
4503 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4505 * B feature feature to define sprites for
4506 * 0, 1, 2, 3: veh-type, 4: train stations
4507 * E first-set first sprite set to define
4508 * B num-sets number of sprite sets (extended byte in extended format)
4509 * E num-ent how many entries per sprite set
4510 * For vehicles, this is the number of different
4511 * vehicle directions in each sprite set
4512 * Set num-dirs=8, unless your sprites are symmetric.
4513 * In that case, use num-dirs=4.
4516 uint8 feature
= buf
->ReadByte();
4517 uint16 num_sets
= buf
->ReadByte();
4518 uint16 first_set
= 0;
4520 if (num_sets
== 0 && buf
->HasData(3)) {
4521 /* Extended Action1 format.
4522 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4523 first_set
= buf
->ReadExtendedByte();
4524 num_sets
= buf
->ReadExtendedByte();
4526 uint16 num_ents
= buf
->ReadExtendedByte();
4528 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4530 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4534 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4536 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4540 /* Action 0x01 (SKIP) */
4541 static void SkipAct1(ByteReader
*buf
)
4544 uint16 num_sets
= buf
->ReadByte();
4546 if (num_sets
== 0 && buf
->HasData(3)) {
4547 /* Extended Action1 format.
4548 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4549 buf
->ReadExtendedByte(); // first_set
4550 num_sets
= buf
->ReadExtendedByte();
4552 uint16 num_ents
= buf
->ReadExtendedByte();
4554 _cur
.skip_sprites
= num_sets
* num_ents
;
4556 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur
.skip_sprites
);
4559 /* Helper function to either create a callback or link to a previously
4560 * defined spritegroup. */
4561 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4563 if (HasBit(groupid
, 15)) {
4564 assert(CallbackResultSpriteGroup::CanAllocateItem());
4565 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4568 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4569 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4573 return _cur
.spritegroups
[groupid
];
4577 * Helper function to either create a callback or a result sprite group.
4578 * @param feature GrfSpecFeature to define spritegroup for.
4579 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4580 * @param type Type of the currently being parsed Action2. (only for debug output)
4581 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4582 * @return Created spritegroup.
4584 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4586 if (HasBit(spriteid
, 15)) {
4587 assert(CallbackResultSpriteGroup::CanAllocateItem());
4588 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4591 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4592 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4596 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4597 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4599 /* Ensure that the sprites are loeded */
4600 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4602 assert(ResultSpriteGroup::CanAllocateItem());
4603 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4607 static void NewSpriteGroup(ByteReader
*buf
)
4609 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4611 * B feature see action 1
4612 * B set-id ID of this particular definition
4613 * B type/num-entries
4614 * if 80 or greater, this is a randomized or variational
4615 * list definition, see below
4616 * otherwise it specifies a number of entries, the exact
4617 * meaning depends on the feature
4618 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4619 SpriteGroup
*act_group
= NULL
;
4621 uint8 feature
= buf
->ReadByte();
4622 uint8 setid
= buf
->ReadByte();
4623 uint8 type
= buf
->ReadByte();
4625 /* Sprite Groups are created here but they are allocated from a pool, so
4626 * we do not need to delete anything if there is an exception from the
4630 /* Deterministic Sprite Group */
4631 case 0x81: // Self scope, byte
4632 case 0x82: // Parent scope, byte
4633 case 0x85: // Self scope, word
4634 case 0x86: // Parent scope, word
4635 case 0x89: // Self scope, dword
4636 case 0x8A: // Parent scope, dword
4641 assert(DeterministicSpriteGroup::CanAllocateItem());
4642 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
4644 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4646 switch (GB(type
, 2, 2)) {
4647 default: NOT_REACHED();
4648 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
4649 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
4650 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
4653 static SmallVector
<DeterministicSpriteGroupAdjust
, 16> adjusts
;
4656 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4657 * from the outset, so we shall have to keep reallocing. */
4659 DeterministicSpriteGroupAdjust
*adjust
= adjusts
.Append();
4661 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4662 adjust
->operation
= adjusts
.Length() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
4663 adjust
->variable
= buf
->ReadByte();
4664 if (adjust
->variable
== 0x7E) {
4665 /* Link subroutine group */
4666 adjust
->subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
4668 adjust
->parameter
= IsInsideMM(adjust
->variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
4671 varadjust
= buf
->ReadByte();
4672 adjust
->shift_num
= GB(varadjust
, 0, 5);
4673 adjust
->type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
4674 adjust
->and_mask
= buf
->ReadVarSize(varsize
);
4676 if (adjust
->type
!= DSGA_TYPE_NONE
) {
4677 adjust
->add_val
= buf
->ReadVarSize(varsize
);
4678 adjust
->divmod_val
= buf
->ReadVarSize(varsize
);
4680 adjust
->add_val
= 0;
4681 adjust
->divmod_val
= 0;
4684 /* Continue reading var adjusts while bit 5 is set. */
4685 } while (HasBit(varadjust
, 5));
4687 group
->num_adjusts
= adjusts
.Length();
4688 group
->adjusts
= MallocT
<DeterministicSpriteGroupAdjust
>(group
->num_adjusts
);
4689 MemCpyT(group
->adjusts
, adjusts
.Begin(), group
->num_adjusts
);
4691 std::vector
<DeterministicSpriteGroupRange
> ranges
;
4692 ranges
.resize(buf
->ReadByte());
4693 for (uint i
= 0; i
< ranges
.size(); i
++) {
4694 ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4695 ranges
[i
].low
= buf
->ReadVarSize(varsize
);
4696 ranges
[i
].high
= buf
->ReadVarSize(varsize
);
4699 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4700 group
->error_group
= ranges
.size() > 0 ? ranges
[0].group
: group
->default_group
;
4702 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4703 std::vector
<uint32
> bounds
;
4704 for (uint i
= 0; i
< ranges
.size(); i
++) {
4705 bounds
.push_back(ranges
[i
].low
);
4706 if (ranges
[i
].high
!= UINT32_MAX
) bounds
.push_back(ranges
[i
].high
+ 1);
4708 std::sort(bounds
.begin(), bounds
.end());
4709 bounds
.erase(std::unique(bounds
.begin(), bounds
.end()), bounds
.end());
4711 std::vector
<const SpriteGroup
*> target
;
4712 for (uint j
= 0; j
< bounds
.size(); ++j
) {
4713 uint32 v
= bounds
[j
];
4714 const SpriteGroup
*t
= NULL
;
4715 for (uint i
= 0; i
< ranges
.size(); i
++) {
4716 if (ranges
[i
].low
<= v
&& v
<= ranges
[i
].high
) {
4717 t
= ranges
[i
].group
;
4720 target
.push_back(t
);
4722 assert(target
.size() == bounds
.size());
4724 std::vector
<DeterministicSpriteGroupRange
> optimised
;
4725 for (uint j
= 0; j
< bounds
.size(); ) {
4727 DeterministicSpriteGroupRange r
;
4728 r
.group
= target
[j
];
4730 while (j
< bounds
.size() && target
[j
] == r
.group
) {
4733 r
.high
= j
< bounds
.size() ? bounds
[j
] - 1 : UINT32_MAX
;
4734 optimised
.push_back(r
);
4740 group
->num_ranges
= optimised
.size();
4741 if (group
->num_ranges
> 0) {
4742 group
->ranges
= MallocT
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
4743 MemCpyT(group
->ranges
, &optimised
.front(), group
->num_ranges
);
4748 /* Randomized Sprite Group */
4749 case 0x80: // Self scope
4750 case 0x83: // Parent scope
4751 case 0x84: // Relative scope
4753 assert(RandomizedSpriteGroup::CanAllocateItem());
4754 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
4756 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4758 if (HasBit(type
, 2)) {
4759 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
4760 group
->count
= buf
->ReadByte();
4763 uint8 triggers
= buf
->ReadByte();
4764 group
->triggers
= GB(triggers
, 0, 7);
4765 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
4766 group
->lowest_randbit
= buf
->ReadByte();
4767 group
->num_groups
= buf
->ReadByte();
4768 group
->groups
= CallocT
<const SpriteGroup
*>(group
->num_groups
);
4770 for (uint i
= 0; i
< group
->num_groups
; i
++) {
4771 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4777 /* Neither a variable or randomized sprite group... must be a real group */
4782 case GSF_ROADVEHICLES
:
4791 byte num_loaded
= type
;
4792 byte num_loading
= buf
->ReadByte();
4794 if (!_cur
.HasValidSpriteSets(feature
)) {
4795 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4799 assert(RealSpriteGroup::CanAllocateItem());
4800 RealSpriteGroup
*group
= new RealSpriteGroup();
4803 group
->num_loaded
= num_loaded
;
4804 group
->num_loading
= num_loading
;
4805 if (num_loaded
> 0) group
->loaded
= CallocT
<const SpriteGroup
*>(num_loaded
);
4806 if (num_loading
> 0) group
->loading
= CallocT
<const SpriteGroup
*>(num_loading
);
4808 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4809 setid
, num_loaded
, num_loading
);
4811 for (uint i
= 0; i
< num_loaded
; i
++) {
4812 uint16 spriteid
= buf
->ReadWord();
4813 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4814 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
4817 for (uint i
= 0; i
< num_loading
; i
++) {
4818 uint16 spriteid
= buf
->ReadWord();
4819 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4820 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
4827 case GSF_AIRPORTTILES
:
4829 case GSF_INDUSTRYTILES
: {
4830 byte num_building_sprites
= max((uint8
)1, type
);
4832 assert(TileLayoutSpriteGroup::CanAllocateItem());
4833 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
4836 /* On error, bail out immediately. Temporary GRF data was already freed */
4837 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) return;
4841 case GSF_INDUSTRIES
: {
4843 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4847 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4848 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
4850 group
->version
= type
;
4852 for (uint i
= 0; i
< 3; i
++) {
4853 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4855 for (uint i
= 0; i
< 2; i
++) {
4856 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4858 group
->again
= buf
->ReadByte();
4860 for (uint i
= 0; i
< 3; i
++) {
4861 group
->subtract_input
[i
] = buf
->ReadByte();
4863 for (uint i
= 0; i
< 2; i
++) {
4864 group
->add_output
[i
] = buf
->ReadByte();
4866 group
->again
= buf
->ReadByte();
4871 /* Loading of Tile Layout and Production Callback groups would happen here */
4872 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4877 _cur
.spritegroups
[setid
] = act_group
;
4880 static CargoID
TranslateCargo(uint8 feature
, uint8 ctype
)
4882 if (feature
== GSF_OBJECTS
) {
4885 case 0xFF: return CT_PURCHASE_OBJECT
;
4887 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype
);
4891 /* Special cargo types for purchase list and stations */
4892 if (feature
== GSF_STATIONS
&& ctype
== 0xFE) return CT_DEFAULT_NA
;
4893 if (ctype
== 0xFF) return CT_PURCHASE
;
4895 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4896 /* No cargo table, so use bitnum values */
4898 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4902 const CargoSpec
*cs
;
4903 FOR_ALL_CARGOSPECS(cs
) {
4904 if (cs
->bitnum
== ctype
) {
4905 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4910 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4914 /* Check if the cargo type is out of bounds of the cargo translation table */
4915 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4916 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4920 /* Look up the cargo label from the translation table */
4921 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4923 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
4927 ctype
= GetCargoIDByLabel(cl
);
4928 if (ctype
== CT_INVALID
) {
4929 grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl
, 24, 8), GB(cl
, 16, 8), GB(cl
, 8, 8), GB(cl
, 0, 8));
4933 grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl
, 24, 8), GB(cl
, 16, 8), GB(cl
, 8, 8), GB(cl
, 0, 8), ctype
);
4938 static bool IsValidGroupID(uint16 groupid
, const char *function
)
4940 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4941 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
4948 static void VehicleMapSpriteGroup(ByteReader
*buf
, byte feature
, uint8 idcount
)
4950 static EngineID
*last_engines
;
4951 static uint last_engines_count
;
4952 bool wagover
= false;
4954 /* Test for 'wagon override' flag */
4955 if (HasBit(idcount
, 7)) {
4957 /* Strip off the flag */
4958 idcount
= GB(idcount
, 0, 7);
4960 if (last_engines_count
== 0) {
4961 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4965 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4966 last_engines_count
, idcount
);
4968 if (last_engines_count
!= idcount
) {
4969 last_engines
= ReallocT(last_engines
, idcount
);
4970 last_engines_count
= idcount
;
4974 EngineID
*engines
= AllocaM(EngineID
, idcount
);
4975 for (uint i
= 0; i
< idcount
; i
++) {
4976 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
4978 /* No engine could be allocated?!? Deal with it. Okay,
4979 * this might look bad. Also make sure this NewGRF
4980 * gets disabled, as a half loaded one is bad. */
4981 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
4985 engines
[i
] = e
->index
;
4986 if (!wagover
) last_engines
[i
] = engines
[i
];
4989 uint8 cidcount
= buf
->ReadByte();
4990 for (uint c
= 0; c
< cidcount
; c
++) {
4991 uint8 ctype
= buf
->ReadByte();
4992 uint16 groupid
= buf
->ReadWord();
4993 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
4995 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
4997 ctype
= TranslateCargo(feature
, ctype
);
4998 if (ctype
== CT_INVALID
) continue;
5000 for (uint i
= 0; i
< idcount
; i
++) {
5001 EngineID engine
= engines
[i
];
5003 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
5006 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5008 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
5013 uint16 groupid
= buf
->ReadWord();
5014 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return;
5016 grfmsg(8, "-- Default group id 0x%04X", groupid
);
5018 for (uint i
= 0; i
< idcount
; i
++) {
5019 EngineID engine
= engines
[i
];
5022 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5024 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
5025 SetEngineGRF(engine
, _cur
.grffile
);
5031 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5033 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
5034 for (uint i
= 0; i
< idcount
; i
++) {
5035 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
5038 uint8 cidcount
= buf
->ReadByte();
5039 buf
->Skip(cidcount
* 3);
5041 uint16 groupid
= buf
->ReadWord();
5042 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5044 for (uint i
= 0; i
< idcount
; i
++) {
5045 CanalFeature cf
= cfs
[i
];
5048 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5052 _water_feature
[cf
].grffile
= _cur
.grffile
;
5053 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5058 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5060 uint8
*stations
= AllocaM(uint8
, idcount
);
5061 for (uint i
= 0; i
< idcount
; i
++) {
5062 stations
[i
] = buf
->ReadByte();
5065 uint8 cidcount
= buf
->ReadByte();
5066 for (uint c
= 0; c
< cidcount
; c
++) {
5067 uint8 ctype
= buf
->ReadByte();
5068 uint16 groupid
= buf
->ReadWord();
5069 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5071 ctype
= TranslateCargo(GSF_STATIONS
, ctype
);
5072 if (ctype
== CT_INVALID
) continue;
5074 for (uint i
= 0; i
< idcount
; i
++) {
5075 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5077 if (statspec
== NULL
) {
5078 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5082 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5086 uint16 groupid
= buf
->ReadWord();
5087 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5089 for (uint i
= 0; i
< idcount
; i
++) {
5090 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5092 if (statspec
== NULL
) {
5093 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5097 if (statspec
->grf_prop
.grffile
!= NULL
) {
5098 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5102 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5103 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5104 statspec
->grf_prop
.local_id
= stations
[i
];
5105 StationClass::Assign(statspec
);
5110 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5112 uint8
*houses
= AllocaM(uint8
, idcount
);
5113 for (uint i
= 0; i
< idcount
; i
++) {
5114 houses
[i
] = buf
->ReadByte();
5117 /* Skip the cargo type section, we only care about the default group */
5118 uint8 cidcount
= buf
->ReadByte();
5119 buf
->Skip(cidcount
* 3);
5121 uint16 groupid
= buf
->ReadWord();
5122 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5124 if (_cur
.grffile
->housespec
== NULL
) {
5125 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5129 for (uint i
= 0; i
< idcount
; i
++) {
5130 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5133 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5137 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5141 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5143 uint8
*industries
= AllocaM(uint8
, idcount
);
5144 for (uint i
= 0; i
< idcount
; i
++) {
5145 industries
[i
] = buf
->ReadByte();
5148 /* Skip the cargo type section, we only care about the default group */
5149 uint8 cidcount
= buf
->ReadByte();
5150 buf
->Skip(cidcount
* 3);
5152 uint16 groupid
= buf
->ReadWord();
5153 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5155 if (_cur
.grffile
->industryspec
== NULL
) {
5156 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5160 for (uint i
= 0; i
< idcount
; i
++) {
5161 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5163 if (indsp
== NULL
) {
5164 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5168 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5172 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5174 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5175 for (uint i
= 0; i
< idcount
; i
++) {
5176 indtiles
[i
] = buf
->ReadByte();
5179 /* Skip the cargo type section, we only care about the default group */
5180 uint8 cidcount
= buf
->ReadByte();
5181 buf
->Skip(cidcount
* 3);
5183 uint16 groupid
= buf
->ReadWord();
5184 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5186 if (_cur
.grffile
->indtspec
== NULL
) {
5187 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5191 for (uint i
= 0; i
< idcount
; i
++) {
5192 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5194 if (indtsp
== NULL
) {
5195 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5199 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5203 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5205 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5206 for (uint i
= 0; i
< idcount
; i
++) {
5207 cargoes
[i
] = buf
->ReadByte();
5210 /* Skip the cargo type section, we only care about the default group */
5211 uint8 cidcount
= buf
->ReadByte();
5212 buf
->Skip(cidcount
* 3);
5214 uint16 groupid
= buf
->ReadWord();
5215 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5217 for (uint i
= 0; i
< idcount
; i
++) {
5218 CargoID cid
= cargoes
[i
];
5220 if (cid
>= NUM_CARGO
) {
5221 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5225 CargoSpec
*cs
= CargoSpec::Get(cid
);
5226 cs
->grffile
= _cur
.grffile
;
5227 cs
->group
= _cur
.spritegroups
[groupid
];
5231 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5233 if (_cur
.grffile
->objectspec
== NULL
) {
5234 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5238 uint8
*objects
= AllocaM(uint8
, idcount
);
5239 for (uint i
= 0; i
< idcount
; i
++) {
5240 objects
[i
] = buf
->ReadByte();
5243 uint8 cidcount
= buf
->ReadByte();
5244 for (uint c
= 0; c
< cidcount
; c
++) {
5245 uint8 ctype
= buf
->ReadByte();
5246 uint16 groupid
= buf
->ReadWord();
5247 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5249 ctype
= TranslateCargo(GSF_OBJECTS
, ctype
);
5250 if (ctype
== CT_INVALID
) continue;
5252 for (uint i
= 0; i
< idcount
; i
++) {
5253 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5256 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5260 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5264 uint16 groupid
= buf
->ReadWord();
5265 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5267 for (uint i
= 0; i
< idcount
; i
++) {
5268 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5271 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5275 if (spec
->grf_prop
.grffile
!= NULL
) {
5276 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5280 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5281 spec
->grf_prop
.grffile
= _cur
.grffile
;
5282 spec
->grf_prop
.local_id
= objects
[i
];
5286 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5288 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5289 for (uint i
= 0; i
< idcount
; i
++) {
5290 railtypes
[i
] = _cur
.grffile
->railtype_map
[buf
->ReadByte()];
5293 uint8 cidcount
= buf
->ReadByte();
5294 for (uint c
= 0; c
< cidcount
; c
++) {
5295 uint8 ctype
= buf
->ReadByte();
5296 uint16 groupid
= buf
->ReadWord();
5297 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5299 if (ctype
>= RTSG_END
) continue;
5301 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5302 for (uint i
= 0; i
< idcount
; i
++) {
5303 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5304 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5306 rti
->grffile
[ctype
] = _cur
.grffile
;
5307 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5312 /* Railtypes do not use the default group. */
5316 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5318 uint8
*airports
= AllocaM(uint8
, idcount
);
5319 for (uint i
= 0; i
< idcount
; i
++) {
5320 airports
[i
] = buf
->ReadByte();
5323 /* Skip the cargo type section, we only care about the default group */
5324 uint8 cidcount
= buf
->ReadByte();
5325 buf
->Skip(cidcount
* 3);
5327 uint16 groupid
= buf
->ReadWord();
5328 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5330 if (_cur
.grffile
->airportspec
== NULL
) {
5331 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5335 for (uint i
= 0; i
< idcount
; i
++) {
5336 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5339 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5343 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5347 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5349 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5350 for (uint i
= 0; i
< idcount
; i
++) {
5351 airptiles
[i
] = buf
->ReadByte();
5354 /* Skip the cargo type section, we only care about the default group */
5355 uint8 cidcount
= buf
->ReadByte();
5356 buf
->Skip(cidcount
* 3);
5358 uint16 groupid
= buf
->ReadWord();
5359 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5361 if (_cur
.grffile
->airtspec
== NULL
) {
5362 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5366 for (uint i
= 0; i
< idcount
; i
++) {
5367 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5369 if (airtsp
== NULL
) {
5370 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5374 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5380 static void FeatureMapSpriteGroup(ByteReader
*buf
)
5382 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5383 * id-list := [<id>] [id-list]
5384 * cargo-list := <cargo-type> <cid> [cargo-list]
5386 * B feature see action 0
5387 * B n-id bits 0-6: how many IDs this definition applies to
5388 * bit 7: if set, this is a wagon override definition (see below)
5389 * B ids the IDs for which this definition applies
5390 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5391 * can be zero, in that case the def-cid is used always
5392 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5393 * W cid cargo ID (sprite group ID) for this type of cargo
5394 * W def-cid default cargo ID (sprite group ID) */
5396 uint8 feature
= buf
->ReadByte();
5397 uint8 idcount
= buf
->ReadByte();
5399 /* If idcount is zero, this is a feature callback */
5401 /* Skip number of cargo ids? */
5403 uint16 groupid
= buf
->ReadWord();
5404 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return;
5406 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5408 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5412 /* Mark the feature as used by the grf (generic callbacks do not count) */
5413 SetBit(_cur
.grffile
->grf_features
, feature
);
5415 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5419 case GSF_ROADVEHICLES
:
5422 VehicleMapSpriteGroup(buf
, feature
, idcount
);
5426 CanalMapSpriteGroup(buf
, idcount
);
5430 StationMapSpriteGroup(buf
, idcount
);
5434 TownHouseMapSpriteGroup(buf
, idcount
);
5437 case GSF_INDUSTRIES
:
5438 IndustryMapSpriteGroup(buf
, idcount
);
5441 case GSF_INDUSTRYTILES
:
5442 IndustrytileMapSpriteGroup(buf
, idcount
);
5446 CargoMapSpriteGroup(buf
, idcount
);
5450 AirportMapSpriteGroup(buf
, idcount
);
5454 ObjectMapSpriteGroup(buf
, idcount
);
5458 RailTypeMapSpriteGroup(buf
, idcount
);
5461 case GSF_AIRPORTTILES
:
5462 AirportTileMapSpriteGroup(buf
, idcount
);
5466 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5472 static void FeatureNewName(ByteReader
*buf
)
5474 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5476 * B veh-type see action 0 (as 00..07, + 0A
5477 * But IF veh-type = 48, then generic text
5478 * B language-id If bit 6 is set, This is the extended language scheme,
5479 * with up to 64 language.
5480 * Otherwise, it is a mapping where set bits have meaning
5481 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5482 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5483 * B num-veh number of vehicles which are getting a new name
5484 * B/W offset number of the first vehicle that gets a new name
5485 * Byte : ID of vehicle to change
5486 * Word : ID of string to change/add
5487 * S data new texts, each of them zero-terminated, after
5488 * which the next name begins. */
5490 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5492 uint8 feature
= buf
->ReadByte();
5493 uint8 lang
= buf
->ReadByte();
5494 uint8 num
= buf
->ReadByte();
5495 bool generic
= HasBit(lang
, 7);
5498 id
= buf
->ReadWord();
5499 } else if (feature
<= GSF_AIRCRAFT
) {
5500 id
= buf
->ReadExtendedByte();
5502 id
= buf
->ReadByte();
5507 uint16 endid
= id
+ num
;
5509 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5510 id
, endid
, feature
, lang
);
5512 for (; id
< endid
&& buf
->HasData(); id
++) {
5513 const char *name
= buf
->ReadString();
5514 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5518 case GSF_ROADVEHICLES
:
5522 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5523 if (e
== NULL
) break;
5524 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5525 e
->info
.string_id
= string
;
5527 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5532 if (IsInsideMM(id
, 0xD000, 0xD400) || IsInsideMM(id
, 0xD800, 0xE000)) {
5533 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5537 switch (GB(id
, 8, 8)) {
5538 case 0xC4: // Station class name
5539 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5540 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5542 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5543 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5547 case 0xC5: // Station name
5548 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5549 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5551 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5555 case 0xC7: // Airporttile name
5556 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5557 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5559 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5563 case 0xC9: // House name
5564 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5565 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5567 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5572 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5581 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5582 * @param num The number of sprites to load.
5583 * @param offset Offset from the base.
5584 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5585 * @param name Used for error warnings.
5586 * @return The number of sprites that is going to be skipped.
5588 static uint16
SanitizeSpriteOffset(uint16
& num
, uint16 offset
, int max_sprites
, const char *name
)
5591 if (offset
>= max_sprites
) {
5592 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name
, max_sprites
);
5593 uint orig_num
= num
;
5598 if (offset
+ num
> max_sprites
) {
5599 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name
);
5600 uint orig_num
= num
;
5601 num
= max(max_sprites
- offset
, 0);
5602 return orig_num
- num
;
5609 /** The type of action 5 type. */
5610 enum Action5BlockType
{
5611 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5612 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5613 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5615 /** Information about a single action 5 type. */
5616 struct Action5Type
{
5617 Action5BlockType block_type
; ///< How is this Action5 type processed?
5618 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5619 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5620 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5621 const char *name
; ///< Name for error messages.
5624 /** The information about action 5 types. */
5625 static const Action5Type _action5_types
[] = {
5626 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5627 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5628 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5629 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5630 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5631 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5632 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5633 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5634 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5635 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5636 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5637 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5638 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5639 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5640 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5641 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5642 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5643 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5644 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5645 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5646 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5647 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5648 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5649 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5650 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5651 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5655 static void GraphicsNew(ByteReader
*buf
)
5657 /* <05> <graphics-type> <num-sprites> <other data...>
5659 * B graphics-type What set of graphics the sprites define.
5660 * E num-sprites How many sprites are in this set?
5661 * V other data Graphics type specific data. Currently unused. */
5664 uint8 type
= buf
->ReadByte();
5665 uint16 num
= buf
->ReadExtendedByte();
5666 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5667 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5669 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5670 /* Special not-TTDP-compatible case used in openttd.grf
5671 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5672 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5673 LoadNextSprite(SPR_SHORE_BASE
+ 0, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_S
5674 LoadNextSprite(SPR_SHORE_BASE
+ 5, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_W
5675 LoadNextSprite(SPR_SHORE_BASE
+ 7, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_WSE
5676 LoadNextSprite(SPR_SHORE_BASE
+ 10, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_N
5677 LoadNextSprite(SPR_SHORE_BASE
+ 11, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NWS
5678 LoadNextSprite(SPR_SHORE_BASE
+ 13, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_ENW
5679 LoadNextSprite(SPR_SHORE_BASE
+ 14, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_SEN
5680 LoadNextSprite(SPR_SHORE_BASE
+ 15, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_E
5681 LoadNextSprite(SPR_SHORE_BASE
+ 16, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_EW
5682 LoadNextSprite(SPR_SHORE_BASE
+ 17, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NS
5683 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5687 /* Supported type? */
5688 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5689 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5690 _cur
.skip_sprites
= num
;
5694 const Action5Type
*action5_type
= &_action5_types
[type
];
5696 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5697 * except for the long version of the shore type:
5698 * Ignore offset if not allowed */
5699 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5700 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5704 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5705 * This does not make sense, if <offset> is allowed */
5706 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5707 grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type
->name
, type
, action5_type
->min_sprites
, num
);
5708 _cur
.skip_sprites
= num
;
5712 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5713 uint16 skip_num
= SanitizeSpriteOffset(num
, offset
, action5_type
->max_sprites
, action5_type
->name
);
5714 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5716 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5717 grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset
, offset
+ num
- 1, action5_type
->name
, type
, replace
);
5719 for (; num
> 0; num
--) {
5721 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5724 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5726 _cur
.skip_sprites
= skip_num
;
5729 /* Action 0x05 (SKIP) */
5730 static void SkipAct5(ByteReader
*buf
)
5732 /* Ignore type byte */
5735 /* Skip the sprites of this action */
5736 _cur
.skip_sprites
= buf
->ReadExtendedByte();
5738 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur
.skip_sprites
);
5742 * Reads a variable common to VarAction2 and Action7/9/D.
5744 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5745 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5747 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5748 * @param value returns the value of the variable.
5749 * @param grffile NewGRF querying the variable
5750 * @return true iff the variable is known and the value is returned in 'value'.
5752 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5755 case 0x00: // current date
5756 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5759 case 0x01: // current year
5760 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5763 case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
5765 ConvertDateToYMD(_date
, &ymd
);
5766 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
5767 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5771 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5772 *value
= _settings_game
.game_creation
.landscape
;
5775 case 0x06: // road traffic side, bit 4 clear=left, set=right
5776 *value
= _settings_game
.vehicle
.road_side
<< 4;
5779 case 0x09: // date fraction
5780 *value
= _date_fract
* 885;
5783 case 0x0A: // animation counter
5784 *value
= _tick_counter
;
5787 case 0x0B: { // TTDPatch version
5790 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5792 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5796 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5797 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5800 case 0x0E: // Y-offset for train sprites
5801 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5804 case 0x0F: // Rail track type cost factors
5806 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5807 if (_settings_game
.vehicle
.disable_elrails
) {
5808 /* skip elrail multiplier - disabled */
5809 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5811 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5812 /* Skip monorail multiplier - no space in result */
5814 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5817 case 0x11: // current rail tool type
5818 *value
= 0; // constant fake value to avoid desync
5821 case 0x12: // Game mode
5822 *value
= _game_mode
;
5825 /* case 0x13: // Tile refresh offset to left not implemented */
5826 /* case 0x14: // Tile refresh offset to right not implemented */
5827 /* case 0x15: // Tile refresh offset upwards not implemented */
5828 /* case 0x16: // Tile refresh offset downwards not implemented */
5829 /* case 0x17: // temperate snow line not implemented */
5831 case 0x1A: // Always -1
5835 case 0x1B: // Display options
5836 *value
= 0x3F; // constant fake value to avoid desync
5839 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5843 case 0x1E: // Miscellaneous GRF features
5844 *value
= _misc_grf_features
;
5846 /* Add the local flags */
5847 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5848 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5851 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5853 case 0x20: { // snow line height
5854 byte snowline
= GetSnowLine();
5855 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5856 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5864 case 0x21: // OpenTTD version
5865 *value
= _openttd_newgrf_version
;
5868 case 0x22: // difficulty level
5872 case 0x23: // long format date
5876 case 0x24: // long format year
5880 default: return false;
5884 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5886 /* First handle variable common with VarAction2 */
5888 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5890 /* Non-common variable */
5892 case 0x84: { // GRF loading stage
5895 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5896 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5897 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5901 case 0x85: // TTDPatch flags, only for bit tests
5902 if (cond_val
== NULL
) {
5903 /* Supported in Action 0x07 and 0x09, not 0x0D */
5906 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5911 case 0x88: // GRF ID check
5914 /* case 0x99: Global ID offset not implemented */
5918 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5920 /* In-game variable. */
5921 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
5927 static void CfgApply(ByteReader
*buf
)
5929 /* <06> <param-num> <param-size> <offset> ... <FF>
5931 * B param-num Number of parameter to substitute (First = "zero")
5932 * Ignored if that parameter was not specified in newgrf.cfg
5933 * B param-size How many bytes to replace. If larger than 4, the
5934 * bytes of the following parameter are used. In that
5935 * case, nothing is applied unless *all* parameters
5937 * B offset Offset into data from beginning of next sprite
5938 * to place where parameter is to be stored. */
5940 /* Preload the next sprite */
5941 size_t pos
= FioGetPos();
5942 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
5943 uint8 type
= FioReadByte();
5944 byte
*preload_sprite
= NULL
;
5946 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5948 preload_sprite
= MallocT
<byte
>(num
);
5949 FioReadBlock(preload_sprite
, num
);
5952 /* Reset the file position to the start of the next sprite */
5953 FioSeekTo(pos
, SEEK_SET
);
5956 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5957 free(preload_sprite
);
5961 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
5962 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
5963 if (it
!= _grf_line_to_action6_sprite_override
.end()) {
5964 free(preload_sprite
);
5965 preload_sprite
= _grf_line_to_action6_sprite_override
[location
];
5967 _grf_line_to_action6_sprite_override
[location
] = preload_sprite
;
5970 /* Now perform the Action 0x06 on our data. */
5979 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5980 param_num
= buf
->ReadByte();
5981 if (param_num
== 0xFF) break;
5983 /* Get the size of the parameter to use. If the size covers multiple
5984 * double words, sequential parameter values are used. */
5985 param_size
= buf
->ReadByte();
5987 /* Bit 7 of param_size indicates we should add to the original value
5988 * instead of replacing it. */
5989 add_value
= HasBit(param_size
, 7);
5990 param_size
= GB(param_size
, 0, 7);
5992 /* Where to apply the data to within the pseudo sprite data. */
5993 offset
= buf
->ReadExtendedByte();
5995 /* If the parameter is a GRF parameter (not an internal variable) check
5996 * if it (and all further sequential parameters) has been defined. */
5997 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
5998 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6002 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6005 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6006 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
6007 /* Reset carry flag for each iteration of the variable (only really
6008 * matters if param_size is greater than 4) */
6009 if (i
% 4 == 0) carry
= false;
6012 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6013 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6014 /* Check if the addition overflowed */
6015 carry
= new_value
>= 256;
6017 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6024 * Disable a static NewGRF when it is influencing another (non-static)
6025 * NewGRF as this could cause desyncs.
6027 * We could just tell the NewGRF querying that the file doesn't exist,
6028 * but that might give unwanted results. Disabling the NewGRF gives the
6029 * best result as no NewGRF author can complain about that.
6030 * @param c The NewGRF to disable.
6032 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6034 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6035 error
->data
= stredup(_cur
.grfconfig
->GetName());
6040 static void SkipIf(ByteReader
*buf
)
6042 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6049 /* TODO: More params. More condition types. */
6050 uint32 cond_val
= 0;
6054 uint8 param
= buf
->ReadByte();
6055 uint8 paramsize
= buf
->ReadByte();
6056 uint8 condtype
= buf
->ReadByte();
6059 /* Always 1 for bit tests, the given value should be ignored. */
6063 switch (paramsize
) {
6064 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6065 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6066 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6067 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6071 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6072 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6076 uint32 param_val
= GetParamVal(param
, &cond_val
);
6078 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6081 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6082 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6083 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6084 * So, when the condition type is one of those, the specific variable
6085 * 0x88 code is skipped, so the "general" code for the cargo
6086 * availability conditions kicks in.
6088 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6091 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6093 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6094 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6098 if (condtype
!= 10 && c
== NULL
) {
6099 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6104 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6105 case 0x06: // Is GRFID active?
6106 result
= c
->status
== GCS_ACTIVATED
;
6109 case 0x07: // Is GRFID non-active?
6110 result
= c
->status
!= GCS_ACTIVATED
;
6113 case 0x08: // GRFID is not but will be active?
6114 result
= c
->status
== GCS_INITIALISED
;
6117 case 0x09: // GRFID is or will be active?
6118 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6121 case 0x0A: // GRFID is not nor will be active
6122 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6123 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6126 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return;
6129 /* Parameter or variable tests */
6131 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6133 case 0x01: result
= !(param_val
& (1 << cond_val
));
6135 case 0x02: result
= (param_val
& mask
) == cond_val
;
6137 case 0x03: result
= (param_val
& mask
) != cond_val
;
6139 case 0x04: result
= (param_val
& mask
) < cond_val
;
6141 case 0x05: result
= (param_val
& mask
) > cond_val
;
6143 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6145 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6147 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6149 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6152 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return;
6157 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6161 uint8 numsprites
= buf
->ReadByte();
6163 /* numsprites can be a GOTO label if it has been defined in the GRF
6164 * file. The jump will always be the first matching label that follows
6165 * the current nfo_line. If no matching label is found, the first matching
6166 * label in the file is used. */
6167 GRFLabel
*choice
= NULL
;
6168 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6169 if (label
->label
!= numsprites
) continue;
6171 /* Remember a goto before the current line */
6172 if (choice
== NULL
) choice
= label
;
6173 /* If we find a label here, this is definitely good */
6174 if (label
->nfo_line
> _cur
.nfo_line
) {
6180 if (choice
!= NULL
) {
6181 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6182 FioSeekTo(choice
->pos
, SEEK_SET
);
6183 _cur
.nfo_line
= choice
->nfo_line
;
6187 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6188 _cur
.skip_sprites
= numsprites
;
6189 if (_cur
.skip_sprites
== 0) {
6190 /* Zero means there are no sprites to skip, so
6191 * we use -1 to indicate that all further
6192 * sprites should be skipped. */
6193 _cur
.skip_sprites
= -1;
6195 /* If an action 8 hasn't been encountered yet, disable the grf. */
6196 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6203 /* Action 0x08 (GLS_FILESCAN) */
6204 static void ScanInfo(ByteReader
*buf
)
6206 uint8 grf_version
= buf
->ReadByte();
6207 uint32 grfid
= buf
->ReadDWord();
6208 const char *name
= buf
->ReadString();
6210 _cur
.grfconfig
->ident
.grfid
= grfid
;
6212 if (grf_version
< 2 || grf_version
> 8) {
6213 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6214 DEBUG(grf
, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur
.grfconfig
->filename
, name
, BSWAP32(grfid
), grf_version
);
6217 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6218 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6220 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, 0x7F, grfid
, false, name
);
6222 if (buf
->HasData()) {
6223 const char *info
= buf
->ReadString();
6224 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, 0x7F, grfid
, true, info
);
6227 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6228 _cur
.skip_sprites
= -1;
6232 static void GRFInfo(ByteReader
*buf
)
6234 /* <08> <version> <grf-id> <name> <info>
6236 * B version newgrf version, currently 06
6237 * 4*B grf-id globally unique ID of this .grf file
6238 * S name name of this .grf set
6239 * S info string describing the set, and e.g. author and copyright */
6241 uint8 version
= buf
->ReadByte();
6242 uint32 grfid
= buf
->ReadDWord();
6243 const char *name
= buf
->ReadString();
6245 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6246 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6250 if (_cur
.grffile
->grfid
!= grfid
) {
6251 DEBUG(grf
, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur
.grffile
->grfid
), BSWAP32(grfid
));
6252 _cur
.grffile
->grfid
= grfid
;
6255 _cur
.grffile
->grf_version
= version
;
6256 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6258 /* Do swap the GRFID for displaying purposes since people expect that */
6259 DEBUG(grf
, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version
, BSWAP32(grfid
), name
, (_cur
.grfconfig
->palette
& GRFP_USE_MASK
) ? "Windows" : "DOS", _cur
.grfconfig
->version
);
6263 static void SpriteReplace(ByteReader
*buf
)
6265 /* <0A> <num-sets> <set1> [<set2> ...]
6266 * <set>: <num-sprites> <first-sprite>
6268 * B num-sets How many sets of sprites to replace.
6270 * B num-sprites How many sprites are in this set
6271 * W first-sprite First sprite number to replace */
6273 uint8 num_sets
= buf
->ReadByte();
6275 for (uint i
= 0; i
< num_sets
; i
++) {
6276 uint8 num_sprites
= buf
->ReadByte();
6277 uint16 first_sprite
= buf
->ReadWord();
6279 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6280 i
, num_sprites
, first_sprite
6283 for (uint j
= 0; j
< num_sprites
; j
++) {
6284 int load_index
= first_sprite
+ j
;
6286 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6288 /* Shore sprites now located at different addresses.
6289 * So detect when the old ones get replaced. */
6290 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6291 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6297 /* Action 0x0A (SKIP) */
6298 static void SkipActA(ByteReader
*buf
)
6300 uint8 num_sets
= buf
->ReadByte();
6302 for (uint i
= 0; i
< num_sets
; i
++) {
6303 /* Skip the sprites this replaces */
6304 _cur
.skip_sprites
+= buf
->ReadByte();
6305 /* But ignore where they go */
6309 grfmsg(3, "SkipActA: Skipping %d sprites", _cur
.skip_sprites
);
6313 static void GRFLoadError(ByteReader
*buf
)
6315 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6317 * B severity 00: notice, contine loading grf file
6318 * 01: warning, continue loading grf file
6319 * 02: error, but continue loading grf file, and attempt
6320 * loading grf again when loading or starting next game
6321 * 03: error, abort loading and prevent loading again in
6322 * the future (only when restarting the patch)
6323 * B language-id see action 4, use 1F for built-in error messages
6324 * B message-id message to show, see below
6325 * S message for custom messages (message-id FF), text of the message
6326 * not present for built-in messages.
6327 * V data additional data for built-in (or custom) messages
6328 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6330 static const StringID msgstr
[] = {
6331 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6332 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6333 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6334 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6335 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6336 STR_NEWGRF_ERROR_LOAD_AFTER
,
6337 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6340 static const StringID sevstr
[] = {
6341 STR_NEWGRF_ERROR_MSG_INFO
,
6342 STR_NEWGRF_ERROR_MSG_WARNING
,
6343 STR_NEWGRF_ERROR_MSG_ERROR
,
6344 STR_NEWGRF_ERROR_MSG_FATAL
6347 byte severity
= buf
->ReadByte();
6348 byte lang
= buf
->ReadByte();
6349 byte message_id
= buf
->ReadByte();
6351 /* Skip the error if it isn't valid for the current language. */
6352 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return;
6354 /* Skip the error until the activation stage unless bit 7 of the severity
6356 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6357 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6360 ClrBit(severity
, 7);
6362 if (severity
>= lengthof(sevstr
)) {
6363 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6365 } else if (severity
== 3) {
6366 /* This is a fatal error, so make sure the GRF is deactivated and no
6367 * more of it gets loaded. */
6370 /* Make sure we show fatal errors, instead of silly infos from before */
6371 delete _cur
.grfconfig
->error
;
6372 _cur
.grfconfig
->error
= NULL
;
6375 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6376 grfmsg(7, "GRFLoadError: Invalid message id.");
6380 if (buf
->Remaining() <= 1) {
6381 grfmsg(7, "GRFLoadError: No message data supplied.");
6385 /* For now we can only show one message per newgrf file. */
6386 if (_cur
.grfconfig
->error
!= NULL
) return;
6388 GRFError
*error
= new GRFError(sevstr
[severity
]);
6390 if (message_id
== 0xFF) {
6391 /* This is a custom error message. */
6392 if (buf
->HasData()) {
6393 const char *message
= buf
->ReadString();
6395 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, NULL
, SCC_RAW_STRING_POINTER
);
6397 grfmsg(7, "GRFLoadError: No custom message supplied.");
6398 error
->custom_message
= stredup("");
6401 error
->message
= msgstr
[message_id
];
6404 if (buf
->HasData()) {
6405 const char *data
= buf
->ReadString();
6407 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6409 grfmsg(7, "GRFLoadError: No message data supplied.");
6410 error
->data
= stredup("");
6413 /* Only two parameter numbers can be used in the string. */
6414 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6415 uint param_number
= buf
->ReadByte();
6416 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6419 _cur
.grfconfig
->error
= error
;
6423 static void GRFComment(ByteReader
*buf
)
6425 /* <0C> [<ignored...>]
6427 * V ignored Anything following the 0C is ignored */
6429 if (!buf
->HasData()) return;
6431 const char *text
= buf
->ReadString();
6432 grfmsg(2, "GRFComment: %s", text
);
6435 /* Action 0x0D (GLS_SAFETYSCAN) */
6436 static void SafeParamSet(ByteReader
*buf
)
6438 uint8 target
= buf
->ReadByte();
6440 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6441 if (target
< 0x80 || target
== 0x9E) return;
6443 /* GRM could be unsafe, but as here it can only happen after other GRFs
6444 * are loaded, it should be okay. If the GRF tried to use the slots it
6445 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6446 * sprites is considered safe. */
6448 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6450 /* Skip remainder of GRF */
6451 _cur
.skip_sprites
= -1;
6455 static uint32
GetPatchVariable(uint8 param
)
6458 /* start year - 1920 */
6459 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6461 /* freight trains weight factor */
6462 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6464 /* empty wagon speed increase */
6465 case 0x0F: return 0;
6467 /* plane speed factor; our patch option is reversed from TTDPatch's,
6468 * the following is good for 1x, 2x and 4x (most common?) and...
6469 * well not really for 3x. */
6471 switch (_settings_game
.vehicle
.plane_speed
) {
6480 /* 2CC colourmap base sprite */
6481 case 0x11: return SPR_2CCMAP_BASE
;
6483 /* map size: format = -MABXYSS
6484 * M : the type of map
6485 * bit 0 : set : squared map. Bit 1 is now not relevant
6486 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6487 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6488 * clear : X is the bigger edge.
6489 * A : minimum edge(log2) of the map
6490 * B : maximum edge(log2) of the map
6491 * XY : edges(log2) of each side of the map.
6492 * SS : combination of both X and Y, thus giving the size(log2) of the map
6496 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6497 byte log_Y
= MapLogY() - 6;
6498 byte max_edge
= max(log_X
, log_Y
);
6500 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6501 SetBit(map_bits
, 0);
6503 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6506 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6507 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6510 /* The maximum height of the map. */
6512 return _settings_game
.construction
.max_heightlevel
;
6514 /* Extra foundations base sprite */
6516 return SPR_SLOPES_BASE
;
6518 /* Shore base sprite */
6520 return SPR_SHORE_BASE
;
6523 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6529 static uint32
PerformGRM(uint32
*grm
, uint16 num_ids
, uint16 count
, uint8 op
, uint8 target
, const char *type
)
6535 /* Return GRFID of set that reserved ID */
6536 return grm
[_cur
.grffile
->GetParam(target
)];
6539 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6540 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6542 for (uint i
= start
; i
< num_ids
; i
++) {
6546 if (op
== 2 || op
== 3) break;
6551 if (size
== count
) break;
6554 if (size
== count
) {
6555 /* Got the slot... */
6556 if (op
== 0 || op
== 3) {
6557 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6558 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6563 /* Unable to allocate */
6564 if (op
!= 4 && op
!= 5) {
6565 /* Deactivate GRF */
6566 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6567 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6571 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6576 /** Action 0x0D: Set parameter */
6577 static void ParamSet(ByteReader
*buf
)
6579 /* <0D> <target> <operation> <source1> <source2> [<data>]
6581 * B target parameter number where result is stored
6582 * B operation operation to perform, see below
6583 * B source1 first source operand
6584 * B source2 second source operand
6585 * D data data to use in the calculation, not necessary
6586 * if both source1 and source2 refer to actual parameters
6589 * 00 Set parameter equal to source1
6590 * 01 Addition, source1 + source2
6591 * 02 Subtraction, source1 - source2
6592 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6593 * 04 Signed multiplication, source1 * source2 (both signed)
6594 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6595 * signed quantity; left shift if positive and right shift if
6596 * negative, source1 is unsigned)
6597 * 06 Signed bit shift, source1 by source2
6598 * (source2 like in 05, and source1 as well)
6601 uint8 target
= buf
->ReadByte();
6602 uint8 oper
= buf
->ReadByte();
6603 uint32 src1
= buf
->ReadByte();
6604 uint32 src2
= buf
->ReadByte();
6607 if (buf
->Remaining() >= 4) data
= buf
->ReadDWord();
6609 /* You can add 80 to the operation to make it apply only if the target
6610 * is not defined yet. In this respect, a parameter is taken to be
6611 * defined if any of the following applies:
6612 * - it has been set to any value in the newgrf(w).cfg parameter list
6613 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6614 * an earlier action D */
6615 if (HasBit(oper
, 7)) {
6616 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6617 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6621 oper
= GB(oper
, 0, 7);
6625 if (GB(data
, 0, 8) == 0xFF) {
6626 if (data
== 0x0000FFFF) {
6627 /* Patch variables */
6628 src1
= GetPatchVariable(src1
);
6630 /* GRF Resource Management */
6632 uint8 feature
= GB(data
, 8, 8);
6633 uint16 count
= GB(data
, 16, 16);
6635 if (_cur
.stage
== GLS_RESERVE
) {
6636 if (feature
== 0x08) {
6637 /* General sprites */
6639 /* Check if the allocated sprites will fit below the original sprite limit */
6640 if (_cur
.spriteid
+ count
>= 16384) {
6641 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6642 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6646 /* Reserve space at the current sprite ID */
6647 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6648 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6649 _cur
.spriteid
+= count
;
6652 /* Ignore GRM result during reservation */
6654 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6656 case 0x00: // Trains
6657 case 0x01: // Road Vehicles
6659 case 0x03: // Aircraft
6660 if (!_settings_game
.vehicle
.dynamic_engines
) {
6661 src1
= PerformGRM(&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, "vehicles");
6662 if (_cur
.skip_sprites
== -1) return;
6664 /* GRM does not apply for dynamic engine allocation. */
6668 src1
= _cur
.grffile
->GetParam(target
);
6678 case 0x08: // General sprites
6681 /* Return space reserved during reservation stage */
6682 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6683 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6687 src1
= _cur
.spriteid
;
6691 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6697 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6698 src1
= PerformGRM(_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, "cargoes");
6699 if (_cur
.skip_sprites
== -1) return;
6702 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return;
6705 /* Ignore GRM during initialization */
6710 /* Read another GRF File's parameter */
6711 const GRFFile
*file
= GetFileByGRFID(data
);
6712 GRFConfig
*c
= GetGRFConfig(data
);
6713 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6714 /* Disable the read GRF if it is a static NewGRF. */
6715 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6717 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6719 } else if (src1
== 0xFE) {
6722 src1
= file
->GetParam(src1
);
6726 /* The source1 and source2 operands refer to the grf parameter number
6727 * like in action 6 and 7. In addition, they can refer to the special
6728 * variables available in action 7, or they can be FF to use the value
6729 * of <data>. If referring to parameters that are undefined, a value
6730 * of 0 is used instead. */
6731 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6732 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6735 /* TODO: You can access the parameters of another GRF file by using
6736 * source2=FE, source1=the other GRF's parameter number and data=GRF
6737 * ID. This is only valid with operation 00 (set). If the GRF ID
6738 * cannot be found, a value of 0 is used for the parameter value
6760 res
= (int32
)src1
* (int32
)src2
;
6764 if ((int32
)src2
< 0) {
6765 res
= src1
>> -(int32
)src2
;
6767 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6772 if ((int32
)src2
< 0) {
6773 res
= (int32
)src1
>> -(int32
)src2
;
6775 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6779 case 0x07: // Bitwise AND
6783 case 0x08: // Bitwise OR
6787 case 0x09: // Unsigned division
6795 case 0x0A: // Signed divison
6799 res
= (int32
)src1
/ (int32
)src2
;
6803 case 0x0B: // Unsigned modulo
6811 case 0x0C: // Signed modulo
6815 res
= (int32
)src1
% (int32
)src2
;
6819 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return;
6823 case 0x8E: // Y-Offset for train sprites
6824 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6827 case 0x8F: { // Rail track type cost factors
6828 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6829 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6830 if (_settings_game
.vehicle
.disable_elrails
) {
6831 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6832 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6834 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6835 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6837 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6841 /* @todo implement */
6842 case 0x93: // Tile refresh offset to left
6843 case 0x94: // Tile refresh offset to right
6844 case 0x95: // Tile refresh offset upwards
6845 case 0x96: // Tile refresh offset downwards
6846 case 0x97: // Snow line height
6847 case 0x99: // Global ID offset
6848 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6851 case 0x9E: // Miscellaneous GRF features
6852 /* Set train list engine width */
6853 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6854 /* Remove the local flags from the global flags */
6855 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6857 /* Only copy safe bits for static grfs */
6858 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6859 uint32 safe_bits
= 0;
6860 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6862 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6864 _misc_grf_features
= res
;
6868 case 0x9F: // locale-dependent settings
6869 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6873 if (target
< 0x80) {
6874 _cur
.grffile
->param
[target
] = res
;
6875 /* param is zeroed by default */
6876 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6878 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6884 /* Action 0x0E (GLS_SAFETYSCAN) */
6885 static void SafeGRFInhibit(ByteReader
*buf
)
6887 /* <0E> <num> <grfids...>
6889 * B num Number of GRFIDs that follow
6890 * D grfids GRFIDs of the files to deactivate */
6892 uint8 num
= buf
->ReadByte();
6894 for (uint i
= 0; i
< num
; i
++) {
6895 uint32 grfid
= buf
->ReadDWord();
6897 /* GRF is unsafe it if tries to deactivate other GRFs */
6898 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6899 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6901 /* Skip remainder of GRF */
6902 _cur
.skip_sprites
= -1;
6910 static void GRFInhibit(ByteReader
*buf
)
6912 /* <0E> <num> <grfids...>
6914 * B num Number of GRFIDs that follow
6915 * D grfids GRFIDs of the files to deactivate */
6917 uint8 num
= buf
->ReadByte();
6919 for (uint i
= 0; i
< num
; i
++) {
6920 uint32 grfid
= buf
->ReadDWord();
6921 GRFConfig
*file
= GetGRFConfig(grfid
);
6923 /* Unset activation flag */
6924 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
6925 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
6926 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
6927 error
->data
= stredup(_cur
.grfconfig
->GetName());
6932 /** Action 0x0F - Define Town names */
6933 static void FeatureTownName(ByteReader
*buf
)
6935 /* <0F> <id> <style-name> <num-parts> <parts>
6937 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6938 * V style-name Name of the style (only for final definition)
6939 * B num-parts Number of parts in this definition
6940 * V parts The parts */
6942 uint32 grfid
= _cur
.grffile
->grfid
;
6944 GRFTownName
*townname
= AddGRFTownName(grfid
);
6946 byte id
= buf
->ReadByte();
6947 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
6949 if (HasBit(id
, 7)) {
6950 /* Final definition */
6952 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
6954 byte lang
= buf
->ReadByte();
6956 byte nb_gen
= townname
->nb_gen
;
6960 const char *name
= buf
->ReadString();
6962 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
6963 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
6966 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6968 lang
= buf
->ReadByte();
6969 } while (lang
!= 0);
6970 townname
->id
[nb_gen
] = id
;
6974 byte nb
= buf
->ReadByte();
6975 grfmsg(6, "FeatureTownName: %u parts", nb
);
6977 townname
->nbparts
[id
] = nb
;
6978 townname
->partlist
[id
] = CallocT
<NamePartList
>(nb
);
6980 for (int i
= 0; i
< nb
; i
++) {
6981 byte nbtext
= buf
->ReadByte();
6982 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
6983 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
6984 townname
->partlist
[id
][i
].maxprob
= 0;
6985 townname
->partlist
[id
][i
].partcount
= nbtext
;
6986 townname
->partlist
[id
][i
].parts
= CallocT
<NamePart
>(nbtext
);
6987 grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i
, nbtext
, townname
->partlist
[id
][i
].bitstart
, townname
->partlist
[id
][i
].bitcount
);
6989 for (int j
= 0; j
< nbtext
; j
++) {
6990 byte prob
= buf
->ReadByte();
6992 if (HasBit(prob
, 7)) {
6993 byte ref_id
= buf
->ReadByte();
6995 if (townname
->nbparts
[ref_id
] == 0) {
6996 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
6997 DelGRFTownName(grfid
);
6998 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
7002 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7003 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7005 const char *text
= buf
->ReadString();
7006 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7007 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7009 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7010 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7012 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7016 /** Action 0x10 - Define goto label */
7017 static void DefineGotoLabel(ByteReader
*buf
)
7019 /* <10> <label> [<comment>]
7021 * B label The label to define
7022 * V comment Optional comment - ignored */
7024 byte nfo_label
= buf
->ReadByte();
7026 GRFLabel
*label
= MallocT
<GRFLabel
>(1);
7027 label
->label
= nfo_label
;
7028 label
->nfo_line
= _cur
.nfo_line
;
7029 label
->pos
= FioGetPos();
7032 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7033 if (_cur
.grffile
->label
== NULL
) {
7034 _cur
.grffile
->label
= label
;
7036 /* Attach the label to the end of the list */
7038 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
7042 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7046 * Process a sound import from another GRF file.
7047 * @param sound Destination for sound.
7049 static void ImportGRFSound(SoundEntry
*sound
)
7051 const GRFFile
*file
;
7052 uint32 grfid
= FioReadDword();
7053 SoundID sound_id
= FioReadWord();
7055 file
= GetFileByGRFID(grfid
);
7056 if (file
== NULL
|| file
->sound_offset
== 0) {
7057 grfmsg(1, "ImportGRFSound: Source file not available");
7061 if (sound_id
>= file
->num_sounds
) {
7062 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7066 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7068 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7070 /* Reset volume and priority, which TTDPatch doesn't copy */
7071 sound
->volume
= 128;
7072 sound
->priority
= 0;
7076 * Load a sound from a file.
7077 * @param offs File offset to read sound from.
7078 * @param sound Destination for sound.
7080 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7082 /* Set default volume and priority */
7083 sound
->volume
= 0x80;
7084 sound
->priority
= 0;
7086 if (offs
!= SIZE_MAX
) {
7087 /* Sound is present in the NewGRF. */
7088 sound
->file_slot
= _cur
.file_index
;
7089 sound
->file_offset
= offs
;
7090 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7095 static void GRFSound(ByteReader
*buf
)
7099 * W num Number of sound files that follow */
7101 uint16 num
= buf
->ReadWord();
7102 if (num
== 0) return;
7105 if (_cur
.grffile
->sound_offset
== 0) {
7106 _cur
.grffile
->sound_offset
= GetNumSounds();
7107 _cur
.grffile
->num_sounds
= num
;
7108 sound
= AllocateSound(num
);
7110 sound
= GetSound(_cur
.grffile
->sound_offset
);
7113 for (int i
= 0; i
< num
; i
++) {
7116 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7117 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7118 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7120 size_t offs
= FioGetPos();
7122 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7123 byte type
= FioReadByte();
7125 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7126 /* Reference to sprite section. */
7128 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7130 } else if (len
!= 4) {
7131 grfmsg(1, "GRFSound: Invalid sprite section import");
7134 uint32 id
= FioReadDword();
7135 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7141 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7143 SkipSpriteData(type
, len
- 8);
7148 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7152 byte action
= FioReadByte();
7155 /* Allocate sound only in init stage. */
7156 if (_cur
.stage
== GLS_INIT
) {
7157 if (_cur
.grf_container_ver
>= 2) {
7158 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7160 LoadGRFSound(offs
, sound
+ i
);
7163 FioSkipBytes(len
- 1); // already read <action>
7167 if (_cur
.stage
== GLS_ACTIVATION
) {
7168 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7169 * importing sounds, so this is probably all wrong... */
7170 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7171 ImportGRFSound(sound
+ i
);
7173 FioSkipBytes(len
- 1); // already read <action>
7178 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7179 FioSkipBytes(len
- 1); // already read <action>
7185 /* Action 0x11 (SKIP) */
7186 static void SkipAct11(ByteReader
*buf
)
7190 * W num Number of sound files that follow */
7192 _cur
.skip_sprites
= buf
->ReadWord();
7194 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur
.skip_sprites
);
7198 static void LoadFontGlyph(ByteReader
*buf
)
7200 /* <12> <num_def> <font_size> <num_char> <base_char>
7202 * B num_def Number of definitions
7203 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7204 * B num_char Number of consecutive glyphs
7205 * W base_char First character index */
7207 uint8 num_def
= buf
->ReadByte();
7209 for (uint i
= 0; i
< num_def
; i
++) {
7210 FontSize size
= (FontSize
)buf
->ReadByte();
7211 uint8 num_char
= buf
->ReadByte();
7212 uint16 base_char
= buf
->ReadWord();
7214 if (size
>= FS_END
) {
7215 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7218 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7220 for (uint c
= 0; c
< num_char
; c
++) {
7221 if (size
< FS_END
) SetUnicodeGlyph(size
, base_char
+ c
, _cur
.spriteid
);
7223 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7228 /** Action 0x12 (SKIP) */
7229 static void SkipAct12(ByteReader
*buf
)
7231 /* <12> <num_def> <font_size> <num_char> <base_char>
7233 * B num_def Number of definitions
7234 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7235 * B num_char Number of consecutive glyphs
7236 * W base_char First character index */
7238 uint8 num_def
= buf
->ReadByte();
7240 for (uint i
= 0; i
< num_def
; i
++) {
7241 /* Ignore 'size' byte */
7244 /* Sum up number of characters */
7245 _cur
.skip_sprites
+= buf
->ReadByte();
7247 /* Ignore 'base_char' word */
7251 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur
.skip_sprites
);
7255 static void TranslateGRFStrings(ByteReader
*buf
)
7257 /* <13> <grfid> <num-ent> <offset> <text...>
7259 * 4*B grfid The GRFID of the file whose texts are to be translated
7260 * B num-ent Number of strings
7261 * W offset First text ID
7262 * S text... Zero-terminated strings */
7264 uint32 grfid
= buf
->ReadDWord();
7265 const GRFConfig
*c
= GetGRFConfig(grfid
);
7266 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7267 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7271 if (c
->status
== GCS_INITIALISED
) {
7272 /* If the file is not active but will be activated later, give an error
7273 * and disable this file. */
7274 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER
);
7277 GetString(tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
, lastof(tmp
));
7278 error
->data
= stredup(tmp
);
7283 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7284 * to be added as a generic string, thus the language id of 0x7F. For this to work
7285 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7286 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7287 * not change anything if a string has been provided specifically for this language. */
7288 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7289 byte num_strings
= buf
->ReadByte();
7290 uint16 first_id
= buf
->ReadWord();
7292 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7293 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7297 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7298 const char *string
= buf
->ReadString();
7300 if (StrEmpty(string
)) {
7301 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7305 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7309 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7310 static bool ChangeGRFName(byte langid
, const char *str
)
7312 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7316 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7317 static bool ChangeGRFDescription(byte langid
, const char *str
)
7319 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7323 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7324 static bool ChangeGRFURL(byte langid
, const char *str
)
7326 AddGRFTextToList(&_cur
.grfconfig
->url
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7330 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7331 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7334 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7337 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7342 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7343 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7346 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7349 char data
= buf
->ReadByte();
7350 GRFPalette pal
= GRFP_GRF_UNSET
;
7353 case 'A': pal
= GRFP_GRF_ANY
; break;
7354 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7355 case 'D': pal
= GRFP_GRF_DOS
; break;
7357 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7360 if (pal
!= GRFP_GRF_UNSET
) {
7361 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7362 _cur
.grfconfig
->palette
|= pal
;
7368 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7369 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7372 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7375 char data
= buf
->ReadByte();
7376 GRFPalette pal
= GRFP_BLT_UNSET
;
7378 case '8': pal
= GRFP_BLT_UNSET
; break;
7379 case '3': pal
= GRFP_BLT_32BPP
; break;
7381 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7384 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7385 _cur
.grfconfig
->palette
|= pal
;
7390 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7391 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7394 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7397 /* Set min_loadable_version as well (default to minimal compatibility) */
7398 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7403 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7404 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7407 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7410 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7411 if (_cur
.grfconfig
->version
== 0) {
7412 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7413 _cur
.grfconfig
->min_loadable_version
= 0;
7415 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7416 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7417 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7423 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7425 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7426 static bool ChangeGRFParamName(byte langid
, const char *str
)
7428 AddGRFTextToList(&_cur_parameter
->name
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7432 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7433 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7435 AddGRFTextToList(&_cur_parameter
->desc
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7439 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7440 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7443 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7446 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7447 if (type
< PTYPE_END
) {
7448 _cur_parameter
->type
= type
;
7450 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7456 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7457 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7459 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7460 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7462 } else if (len
!= 8) {
7463 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7466 _cur_parameter
->min_value
= buf
->ReadDWord();
7467 _cur_parameter
->max_value
= buf
->ReadDWord();
7472 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7473 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7475 if (len
< 1 || len
> 3) {
7476 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7479 byte param_nr
= buf
->ReadByte();
7480 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7481 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7484 _cur_parameter
->param_nr
= param_nr
;
7485 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7486 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7493 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7494 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7497 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7500 _cur_parameter
->def_value
= buf
->ReadDWord();
7502 _cur
.grfconfig
->has_param_defaults
= true;
7506 typedef bool (*DataHandler
)(size_t, ByteReader
*); ///< Type of callback function for binary nodes
7507 typedef bool (*TextHandler
)(byte
, const char *str
); ///< Type of callback function for text nodes
7508 typedef bool (*BranchHandler
)(ByteReader
*); ///< Type of callback function for branch nodes
7511 * Data structure to store the allowed id/type combinations for action 14. The
7512 * data can be represented as a tree with 3 types of nodes:
7513 * 1. Branch nodes (identified by 'C' for choice).
7514 * 2. Binary leaf nodes (identified by 'B').
7515 * 3. Text leaf nodes (identified by 'T').
7517 struct AllowedSubtags
{
7518 /** Create empty subtags object used to identify the end of a list. */
7525 * Create a binary leaf node.
7526 * @param id The id for this node.
7527 * @param handler The callback function to call.
7529 AllowedSubtags(uint32 id
, DataHandler handler
) :
7533 this->handler
.data
= handler
;
7537 * Create a text leaf node.
7538 * @param id The id for this node.
7539 * @param handler The callback function to call.
7541 AllowedSubtags(uint32 id
, TextHandler handler
) :
7545 this->handler
.text
= handler
;
7549 * Create a branch node with a callback handler
7550 * @param id The id for this node.
7551 * @param handler The callback function to call.
7553 AllowedSubtags(uint32 id
, BranchHandler handler
) :
7557 this->handler
.call_handler
= true;
7558 this->handler
.u
.branch
= handler
;
7562 * Create a branch node with a list of sub-nodes.
7563 * @param id The id for this node.
7564 * @param subtags Array with all valid subtags.
7566 AllowedSubtags(uint32 id
, AllowedSubtags
*subtags
) :
7570 this->handler
.call_handler
= false;
7571 this->handler
.u
.subtags
= subtags
;
7574 uint32 id
; ///< The identifier for this node
7575 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7577 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7578 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7581 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7582 AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7584 bool call_handler
; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7589 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7590 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags
*tags
);
7593 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7594 * of some parameter values (type uint/enum) or the names of some bits
7595 * (type bitmask). In both cases the format is the same:
7596 * Each subnode should be a text node with the value/bit number as id.
7598 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7600 byte type
= buf
->ReadByte();
7602 uint32 id
= buf
->ReadDWord();
7603 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7604 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7605 if (!SkipUnknownInfo(buf
, type
)) return false;
7606 type
= buf
->ReadByte();
7610 byte langid
= buf
->ReadByte();
7611 const char *name_string
= buf
->ReadString();
7613 SmallPair
<uint32
, GRFText
*> *val_name
= _cur_parameter
->value_names
.Find(id
);
7614 if (val_name
!= _cur_parameter
->value_names
.End()) {
7615 AddGRFTextToList(&val_name
->second
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7617 GRFText
*list
= NULL
;
7618 AddGRFTextToList(&list
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7619 _cur_parameter
->value_names
.Insert(id
, list
);
7622 type
= buf
->ReadByte();
7627 /** Action14 parameter tags */
7628 AllowedSubtags _tags_parameters
[] = {
7629 AllowedSubtags('NAME', ChangeGRFParamName
),
7630 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7631 AllowedSubtags('TYPE', ChangeGRFParamType
),
7632 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7633 AllowedSubtags('MASK', ChangeGRFParamMask
),
7634 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7635 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7640 * Callback function for 'INFO'->'PARA' to set extra information about the
7641 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7642 * the parameter number as id. The first parameter has id 0. The maximum
7643 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7645 static bool HandleParameterInfo(ByteReader
*buf
)
7647 byte type
= buf
->ReadByte();
7649 uint32 id
= buf
->ReadDWord();
7650 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7651 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7652 if (!SkipUnknownInfo(buf
, type
)) return false;
7653 type
= buf
->ReadByte();
7657 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7658 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7659 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7660 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7662 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7663 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7665 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7666 /* Read all parameter-data and process each node. */
7667 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7668 type
= buf
->ReadByte();
7673 /** Action14 tags for the INFO node */
7674 AllowedSubtags _tags_info
[] = {
7675 AllowedSubtags('NAME', ChangeGRFName
),
7676 AllowedSubtags('DESC', ChangeGRFDescription
),
7677 AllowedSubtags('URL_', ChangeGRFURL
),
7678 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7679 AllowedSubtags('PALS', ChangeGRFPalette
),
7680 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7681 AllowedSubtags('VRSN', ChangeGRFVersion
),
7682 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7683 AllowedSubtags('PARA', HandleParameterInfo
),
7687 /** Action14 root tags */
7688 AllowedSubtags _tags_root
[] = {
7689 AllowedSubtags('INFO', _tags_info
),
7695 * Try to skip the current node and all subnodes (if it's a branch node).
7696 * @param buf Buffer.
7697 * @param type The node type to skip.
7698 * @return True if we could skip the node, false if an error occurred.
7700 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7702 /* type and id are already read */
7705 byte new_type
= buf
->ReadByte();
7706 while (new_type
!= 0) {
7707 buf
->ReadDWord(); // skip the id
7708 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7709 new_type
= buf
->ReadByte();
7715 buf
->ReadByte(); // lang
7716 buf
->ReadString(); // actual text
7720 uint16 size
= buf
->ReadWord();
7733 * Handle the nodes of an Action14
7734 * @param type Type of node.
7736 * @param buf Buffer.
7737 * @param subtags Allowed subtags.
7738 * @return Whether all tags could be handled.
7740 static bool HandleNode(byte type
, uint32 id
, ByteReader
*buf
, AllowedSubtags subtags
[])
7743 AllowedSubtags
*tag
;
7744 while ((tag
= &subtags
[i
++])->type
!= 0) {
7745 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7747 default: NOT_REACHED();
7750 byte langid
= buf
->ReadByte();
7751 return tag
->handler
.text(langid
, buf
->ReadString());
7755 size_t len
= buf
->ReadWord();
7756 if (buf
->Remaining() < len
) return false;
7757 return tag
->handler
.data(len
, buf
);
7761 if (tag
->handler
.call_handler
) {
7762 return tag
->handler
.u
.branch(buf
);
7764 return HandleNodes(buf
, tag
->handler
.u
.subtags
);
7768 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7769 return SkipUnknownInfo(buf
, type
);
7773 * Handle the contents of a 'C' choice of an Action14
7774 * @param buf Buffer.
7775 * @param subtags List of subtags.
7776 * @return Whether the nodes could all be handled.
7778 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags subtags
[])
7780 byte type
= buf
->ReadByte();
7782 uint32 id
= buf
->ReadDWord();
7783 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7784 type
= buf
->ReadByte();
7790 * Handle Action 0x14
7791 * @param buf Buffer.
7793 static void StaticGRFInfo(ByteReader
*buf
)
7795 /* <14> <type> <id> <text/data...> */
7796 HandleNodes(buf
, _tags_root
);
7800 * Set the current NewGRF as unsafe for static use
7801 * @param buf Unused.
7802 * @note Used during safety scan on unsafe actions.
7804 static void GRFUnsafe(ByteReader
*buf
)
7806 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7808 /* Skip remainder of GRF */
7809 _cur
.skip_sprites
= -1;
7813 /** Initialize the TTDPatch flags */
7814 static void InitializeGRFSpecial()
7816 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7817 | (1 << 0x0D) // newairports
7818 | (1 << 0x0E) // largestations
7819 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7820 | (0 << 0x10) // loadtime
7821 | (1 << 0x12) // presignals
7822 | (1 << 0x13) // extpresignals
7823 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7824 | (1 << 0x1B) // multihead
7825 | (1 << 0x1D) // lowmemory
7826 | (1 << 0x1E); // generalfixes
7828 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7829 | (1 << 0x08) // mammothtrains
7830 | (1 << 0x09) // trainrefit
7831 | (0 << 0x0B) // subsidiaries
7832 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7833 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7834 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7835 | (1 << 0x14) // bridgespeedlimits
7836 | (1 << 0x16) // eternalgame
7837 | (1 << 0x17) // newtrains
7838 | (1 << 0x18) // newrvs
7839 | (1 << 0x19) // newships
7840 | (1 << 0x1A) // newplanes
7841 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7842 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7844 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7845 | (1 << 0x03) // semaphores
7846 | (1 << 0x0A) // newobjects
7847 | (0 << 0x0B) // enhancedgui
7848 | (0 << 0x0C) // newagerating
7849 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7850 | (1 << 0x0E) // fullloadany
7851 | (1 << 0x0F) // planespeed
7852 | (0 << 0x10) // moreindustriesperclimate - obsolete
7853 | (0 << 0x11) // moretoylandfeatures
7854 | (1 << 0x12) // newstations
7855 | (1 << 0x13) // tracktypecostdiff
7856 | (1 << 0x14) // manualconvert
7857 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7858 | (1 << 0x16) // canals
7859 | (1 << 0x17) // newstartyear
7860 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7861 | (1 << 0x19) // newhouses
7862 | (1 << 0x1A) // newbridges
7863 | (1 << 0x1B) // newtownnames
7864 | (1 << 0x1C) // moreanimation
7865 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7866 | (1 << 0x1E) // newshistory
7867 | (0 << 0x1F); // custombridgeheads
7869 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7870 | (1 << 0x01) // windowsnap
7871 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7872 | (1 << 0x03) // pathbasedsignalling
7873 | (0 << 0x04) // aichoosechance
7874 | (1 << 0x05) // resolutionwidth
7875 | (1 << 0x06) // resolutionheight
7876 | (1 << 0x07) // newindustries
7877 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7878 | (0 << 0x09) // townroadbranchprob
7879 | (0 << 0x0A) // tempsnowline
7880 | (1 << 0x0B) // newcargo
7881 | (1 << 0x0C) // enhancemultiplayer
7882 | (1 << 0x0D) // onewayroads
7883 | (1 << 0x0E) // irregularstations
7884 | (1 << 0x0F) // statistics
7885 | (1 << 0x10) // newsounds
7886 | (1 << 0x11) // autoreplace
7887 | (1 << 0x12) // autoslope
7888 | (0 << 0x13) // followvehicle
7889 | (1 << 0x14) // trams
7890 | (0 << 0x15) // enhancetunnels
7891 | (1 << 0x16) // shortrvs
7892 | (1 << 0x17) // articulatedrvs
7893 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7894 | (1 << 0x1E) // variablerunningcosts
7895 | (1 << 0x1F); // any switch is on
7898 /** Reset and clear all NewGRF stations */
7899 static void ResetCustomStations()
7901 const GRFFile
* const *end
= _grf_files
.End();
7902 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7903 StationSpec
**&stations
= (*file
)->stations
;
7904 if (stations
== NULL
) continue;
7905 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7906 if (stations
[i
] == NULL
) continue;
7907 StationSpec
*statspec
= stations
[i
];
7909 delete[] statspec
->renderdata
;
7911 /* Release platforms and layouts */
7912 if (!statspec
->copied_layouts
) {
7913 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
7914 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
7915 free(statspec
->layouts
[l
][p
]);
7917 free(statspec
->layouts
[l
]);
7919 free(statspec
->layouts
);
7920 free(statspec
->platforms
);
7923 /* Release this station */
7927 /* Free and reset the station data */
7933 /** Reset and clear all NewGRF houses */
7934 static void ResetCustomHouses()
7936 const GRFFile
* const *end
= _grf_files
.End();
7937 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7938 HouseSpec
**&housespec
= (*file
)->housespec
;
7939 if (housespec
== NULL
) continue;
7940 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
7949 /** Reset and clear all NewGRF airports */
7950 static void ResetCustomAirports()
7952 const GRFFile
* const *end
= _grf_files
.End();
7953 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7954 AirportSpec
**aslist
= (*file
)->airportspec
;
7955 if (aslist
!= NULL
) {
7956 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
7957 AirportSpec
*as
= aslist
[i
];
7960 /* We need to remove the tiles layouts */
7961 for (int j
= 0; j
< as
->num_table
; j
++) {
7962 /* remove the individual layouts */
7966 free(as
->depot_table
);
7973 (*file
)->airportspec
= NULL
;
7976 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
7977 if (airporttilespec
!= NULL
) {
7978 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
7979 free(airporttilespec
[i
]);
7981 free(airporttilespec
);
7982 airporttilespec
= NULL
;
7987 /** Reset and clear all NewGRF industries */
7988 static void ResetCustomIndustries()
7990 const GRFFile
* const *end
= _grf_files
.End();
7991 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7992 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
7993 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
7995 /* We are verifiying both tiles and industries specs loaded from the grf file
7996 * First, let's deal with industryspec */
7997 if (industryspec
!= NULL
) {
7998 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
7999 IndustrySpec
*ind
= industryspec
[i
];
8000 if (ind
== NULL
) continue;
8002 /* We need to remove the sounds array */
8003 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
8004 free(ind
->random_sounds
);
8007 /* We need to remove the tiles layouts */
8008 CleanIndustryTileTable(ind
);
8014 industryspec
= NULL
;
8017 if (indtspec
== NULL
) continue;
8018 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8027 /** Reset and clear all NewObjects */
8028 static void ResetCustomObjects()
8030 const GRFFile
* const *end
= _grf_files
.End();
8031 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8032 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8033 if (objectspec
== NULL
) continue;
8034 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8035 free(objectspec
[i
]);
8043 /** Reset and clear all NewGRFs */
8044 static void ResetNewGRF()
8046 const GRFFile
* const *end
= _grf_files
.End();
8047 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8052 _cur
.grffile
= NULL
;
8055 /** Clear all NewGRF errors */
8056 static void ResetNewGRFErrors()
8058 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8059 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8067 * Reset all NewGRF loaded data
8070 void ResetNewGRFData()
8073 CleanUpGRFTownNames();
8075 /* Copy/reset original engine info data */
8078 /* Copy/reset original bridge info data */
8081 /* Reset rail type information */
8084 /* Allocate temporary refit/cargo class data */
8085 _gted
= CallocT
<GRFTempEngineData
>(Engine::GetPoolSize());
8087 /* Fill rail type label temporary data for default trains */
8089 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8090 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8093 /* Reset GRM reservations */
8094 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8095 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8097 /* Reset generic feature callback lists */
8098 ResetGenericCallbacks();
8100 /* Reset price base data */
8101 ResetPriceBaseMultipliers();
8103 /* Reset the curencies array */
8106 /* Reset the house array */
8107 ResetCustomHouses();
8110 /* Reset the industries structures*/
8111 ResetCustomIndustries();
8114 /* Reset the objects. */
8115 ObjectClass::Reset();
8116 ResetCustomObjects();
8119 /* Reset station classes */
8120 StationClass::Reset();
8121 ResetCustomStations();
8123 /* Reset airport-related structures */
8124 AirportClass::Reset();
8125 ResetCustomAirports();
8126 AirportSpec::ResetAirports();
8127 AirportTileSpec::ResetAirportTiles();
8129 /* Reset canal sprite groups and flags */
8130 memset(_water_feature
, 0, sizeof(_water_feature
));
8132 /* Reset the snowline table. */
8135 /* Reset NewGRF files */
8138 /* Reset NewGRF errors. */
8139 ResetNewGRFErrors();
8141 /* Set up the default cargo types */
8142 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8144 /* Reset misc GRF features and train list display variables */
8145 _misc_grf_features
= 0;
8147 _loaded_newgrf_features
.has_2CC
= false;
8148 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8149 _loaded_newgrf_features
.has_newhouses
= false;
8150 _loaded_newgrf_features
.has_newindustries
= false;
8151 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8153 /* Clear all GRF overrides */
8154 _grf_id_overrides
.clear();
8156 InitializeSoundPool();
8157 _spritegroup_pool
.CleanPool();
8161 * Reset NewGRF data which is stored persistently in savegames.
8163 void ResetPersistentNewGRFData()
8165 /* Reset override managers */
8166 _engine_mngr
.ResetToDefaultMapping();
8167 _house_mngr
.ResetMapping();
8168 _industry_mngr
.ResetMapping();
8169 _industile_mngr
.ResetMapping();
8170 _airport_mngr
.ResetMapping();
8171 _airporttile_mngr
.ResetMapping();
8175 * Construct the Cargo Mapping
8176 * @note This is the reverse of a cargo translation table
8178 static void BuildCargoTranslationMap()
8180 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8182 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8183 const CargoSpec
*cs
= CargoSpec::Get(c
);
8184 if (!cs
->IsValid()) continue;
8186 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8187 /* Default translation table, so just a straight mapping to bitnum */
8188 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8190 /* Check the translation table for this cargo's label */
8191 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8192 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8198 * Prepare loading a NewGRF file with its config
8199 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8201 static void InitNewGRFFile(const GRFConfig
*config
)
8203 GRFFile
*newfile
= GetFileByFilename(config
->filename
);
8204 if (newfile
!= NULL
) {
8205 /* We already loaded it once. */
8206 _cur
.grffile
= newfile
;
8210 newfile
= new GRFFile(config
);
8211 *_grf_files
.Append() = _cur
.grffile
= newfile
;
8215 * Constructor for GRFFile
8216 * @param config GRFConfig to copy name, grfid and parameters from.
8218 GRFFile::GRFFile(const GRFConfig
*config
)
8220 this->filename
= stredup(config
->filename
);
8221 this->grfid
= config
->ident
.grfid
;
8223 /* Initialise local settings to defaults */
8224 this->traininfo_vehicle_pitch
= 0;
8225 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8227 /* Mark price_base_multipliers as 'not set' */
8228 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8229 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8232 /* Initialise rail type map with default rail types */
8233 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8234 this->railtype_map
[0] = RAILTYPE_RAIL
;
8235 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8236 this->railtype_map
[2] = RAILTYPE_MONO
;
8237 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8239 /* Copy the initial parameter list
8240 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8241 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8243 assert(config
->num_params
<= lengthof(config
->param
));
8244 this->param_end
= config
->num_params
;
8245 if (this->param_end
> 0) {
8246 MemCpyT(this->param
, config
->param
, this->param_end
);
8252 free(this->filename
);
8253 delete[] this->language_map
;
8258 * List of what cargo labels are refittable for the given the vehicle-type.
8259 * Only currently active labels are applied.
8261 static const CargoLabel _default_refitmasks_rail
[] = {
8262 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8263 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8264 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8268 static const CargoLabel _default_refitmasks_road
[] = {
8271 static const CargoLabel _default_refitmasks_ships
[] = {
8272 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8273 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8274 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8278 static const CargoLabel _default_refitmasks_aircraft
[] = {
8279 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8280 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8283 static const CargoLabel
* const _default_refitmasks
[] = {
8284 _default_refitmasks_rail
,
8285 _default_refitmasks_road
,
8286 _default_refitmasks_ships
,
8287 _default_refitmasks_aircraft
,
8292 * Precalculate refit masks from cargo classes for all vehicles.
8294 static void CalculateRefitMasks()
8298 FOR_ALL_ENGINES(e
) {
8299 EngineID engine
= e
->index
;
8300 EngineInfo
*ei
= &e
->info
;
8301 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8303 /* Did the newgrf specify any refitting? If not, use defaults. */
8304 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8306 uint32 not_mask
= 0;
8307 uint32 xor_mask
= ei
->refit_mask
;
8309 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8310 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8311 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8313 if (_gted
[engine
].cargo_allowed
!= 0) {
8314 /* Build up the list of cargo types from the set cargo classes. */
8315 const CargoSpec
*cs
;
8316 FOR_ALL_CARGOSPECS(cs
) {
8317 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8318 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8322 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8324 /* Apply explicit refit includes/excludes. */
8325 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8326 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8328 uint32 xor_mask
= 0;
8330 /* Don't apply default refit mask to wagons nor engines with no capacity */
8331 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8332 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8333 for (uint i
= 0;; i
++) {
8334 if (cl
[i
] == 0) break;
8336 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8337 if (cargo
== CT_INVALID
) continue;
8339 SetBit(xor_mask
, cargo
);
8343 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8345 /* If the mask is zero, the vehicle shall only carry the default cargo */
8346 only_defaultcargo
= (ei
->refit_mask
== 0);
8349 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8350 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8352 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8353 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8354 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8355 ei
->cargo_type
= CT_INVALID
;
8358 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8359 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8360 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8361 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8362 const uint8
*cargo_map_for_first_refittable
= NULL
;
8364 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8365 if (file
== NULL
) file
= e
->GetGRF();
8366 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8367 cargo_map_for_first_refittable
= file
->cargo_map
;
8371 if (cargo_map_for_first_refittable
!= NULL
) {
8372 /* Use first refittable cargo from cargo translation table */
8373 byte best_local_slot
= 0xFF;
8375 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8376 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8377 if (local_slot
< best_local_slot
) {
8378 best_local_slot
= local_slot
;
8379 ei
->cargo_type
= cargo_type
;
8384 if (ei
->cargo_type
== CT_INVALID
) {
8385 /* Use first refittable cargo slot */
8386 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8389 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8391 /* Clear refit_mask for not refittable ships */
8392 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8398 /** Set to use the correct action0 properties for each canal feature */
8399 static void FinaliseCanals()
8401 for (uint i
= 0; i
< CF_END
; i
++) {
8402 if (_water_feature
[i
].grffile
!= NULL
) {
8403 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8404 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8409 /** Check for invalid engines */
8410 static void FinaliseEngineArray()
8414 FOR_ALL_ENGINES(e
) {
8415 if (e
->GetGRF() == NULL
) {
8416 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8417 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8418 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8422 /* When the train does not set property 27 (misc flags), but it
8423 * is overridden by a NewGRF graphically we want to disable the
8424 * flipping possibility. */
8425 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8426 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8429 /* Skip wagons, there livery is defined via the engine */
8430 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8431 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8432 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8433 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8435 if (e
->type
== VEH_TRAIN
) {
8436 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8443 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8448 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8451 default: NOT_REACHED();
8458 /** Check for invalid cargoes */
8459 static void FinaliseCargoArray()
8461 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8462 CargoSpec
*cs
= CargoSpec::Get(c
);
8463 if (!cs
->IsValid()) {
8464 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8465 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8466 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8472 * Check if a given housespec is valid and disable it if it's not.
8473 * The housespecs that follow it are used to check the validity of
8475 * @param hs The housespec to check.
8476 * @param next1 The housespec that follows \c hs.
8477 * @param next2 The housespec that follows \c next1.
8478 * @param next3 The housespec that follows \c next2.
8479 * @param filename The filename of the newgrf this house was defined in.
8480 * @return Whether the given housespec is valid.
8482 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8484 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8485 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8486 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8487 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8488 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8489 hs
->enabled
= false;
8490 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8494 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8495 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8496 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8497 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8498 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8499 hs
->enabled
= false;
8500 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8504 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8505 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8506 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8507 hs
->enabled
= false;
8508 DEBUG(grf
, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8512 /* Make sure that additional parts of multitile houses are not available. */
8513 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8514 hs
->enabled
= false;
8515 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8523 * Make sure there is at least one house available in the year 0 for the given
8524 * climate / housezone combination.
8525 * @param bitmask The climate and housezone to check for. Exactly one climate
8526 * bit and one housezone bit should be set.
8528 static void EnsureEarlyHouse(HouseZones bitmask
)
8530 Year min_year
= MAX_YEAR
;
8532 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8533 HouseSpec
*hs
= HouseSpec::Get(i
);
8534 if (hs
== NULL
|| !hs
->enabled
) continue;
8535 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8536 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
8539 if (min_year
== 0) return;
8541 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8542 HouseSpec
*hs
= HouseSpec::Get(i
);
8543 if (hs
== NULL
|| !hs
->enabled
) continue;
8544 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8545 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
8550 * Add all new houses to the house array. House properties can be set at any
8551 * time in the GRF file, so we can only add a house spec to the house array
8552 * after the file has finished loading. We also need to check the dates, due to
8553 * the TTDPatch behaviour described below that we need to emulate.
8555 static void FinaliseHouseArray()
8557 /* If there are no houses with start dates before 1930, then all houses
8558 * with start dates of 1930 have them reset to 0. This is in order to be
8559 * compatible with TTDPatch, where if no houses have start dates before
8560 * 1930 and the date is before 1930, the game pretends that this is 1930.
8561 * If there have been any houses defined with start dates before 1930 then
8562 * the dates are left alone.
8563 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8564 * minimum introduction date to 0.
8566 const GRFFile
* const *end
= _grf_files
.End();
8567 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8568 HouseSpec
**&housespec
= (*file
)->housespec
;
8569 if (housespec
== NULL
) continue;
8571 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8572 HouseSpec
*hs
= housespec
[i
];
8574 if (hs
== NULL
) continue;
8576 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8577 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8578 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8580 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8582 _house_mngr
.SetEntitySpec(hs
);
8586 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8587 HouseSpec
*hs
= HouseSpec::Get(i
);
8588 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8589 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8590 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8592 /* We need to check all houses again to we are sure that multitile houses
8593 * did get consecutive IDs and none of the parts are missing. */
8594 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8595 /* GetHouseNorthPart checks 3 houses that are directly before
8596 * it in the house pool. If any of those houses have multi-tile
8597 * flags set it assumes it's part of a multitile house. Since
8598 * we can have invalid houses in the pool marked as disabled, we
8599 * don't want to have them influencing valid tiles. As such set
8600 * building_flags to zero here to make sure any house following
8601 * this one in the pool is properly handled as 1x1 house. */
8602 hs
->building_flags
= TILE_NO_FLAG
;
8606 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8607 EnsureEarlyHouse(HZ_ZON1
| climate_mask
);
8608 EnsureEarlyHouse(HZ_ZON2
| climate_mask
);
8609 EnsureEarlyHouse(HZ_ZON3
| climate_mask
);
8610 EnsureEarlyHouse(HZ_ZON4
| climate_mask
);
8611 EnsureEarlyHouse(HZ_ZON5
| climate_mask
);
8613 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8614 EnsureEarlyHouse(HZ_ZON1
| HZ_SUBARTC_ABOVE
);
8615 EnsureEarlyHouse(HZ_ZON2
| HZ_SUBARTC_ABOVE
);
8616 EnsureEarlyHouse(HZ_ZON3
| HZ_SUBARTC_ABOVE
);
8617 EnsureEarlyHouse(HZ_ZON4
| HZ_SUBARTC_ABOVE
);
8618 EnsureEarlyHouse(HZ_ZON5
| HZ_SUBARTC_ABOVE
);
8623 * Add all new industries to the industry array. Industry properties can be set at any
8624 * time in the GRF file, so we can only add a industry spec to the industry array
8625 * after the file has finished loading.
8627 static void FinaliseIndustriesArray()
8629 const GRFFile
* const *end
= _grf_files
.End();
8630 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8631 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8632 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8633 if (industryspec
!= NULL
) {
8634 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8635 IndustrySpec
*indsp
= industryspec
[i
];
8637 if (indsp
!= NULL
&& indsp
->enabled
) {
8639 /* process the conversion of text at the end, so to be sure everything will be fine
8640 * and available. Check if it does not return undefind marker, which is a very good sign of a
8641 * substitute industry who has not changed the string been examined, thus using it as such */
8642 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8643 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8645 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8646 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8648 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8649 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8651 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8652 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8654 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8655 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8657 if (indsp
->station_name
!= STR_NULL
) {
8658 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8659 * station's name. Don't want to lose the value, therefore, do not process. */
8660 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8661 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8664 _industry_mngr
.SetEntitySpec(indsp
);
8665 _loaded_newgrf_features
.has_newindustries
= true;
8670 if (indtspec
!= NULL
) {
8671 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8672 IndustryTileSpec
*indtsp
= indtspec
[i
];
8673 if (indtsp
!= NULL
) {
8674 _industile_mngr
.SetEntitySpec(indtsp
);
8680 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8681 IndustrySpec
*indsp
= &_industry_specs
[j
];
8682 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8683 for (uint i
= 0; i
< 3; i
++) {
8684 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8687 if (!indsp
->enabled
) {
8688 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8694 * Add all new objects to the object array. Object properties can be set at any
8695 * time in the GRF file, so we can only add an object spec to the object array
8696 * after the file has finished loading.
8698 static void FinaliseObjectsArray()
8700 const GRFFile
* const *end
= _grf_files
.End();
8701 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8702 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8703 if (objectspec
!= NULL
) {
8704 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8705 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8706 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8714 * Add all new airports to the airport array. Airport properties can be set at any
8715 * time in the GRF file, so we can only add a airport spec to the airport array
8716 * after the file has finished loading.
8718 static void FinaliseAirportsArray()
8720 const GRFFile
* const *end
= _grf_files
.End();
8721 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8722 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8723 if (airportspec
!= NULL
) {
8724 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8725 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8726 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8731 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8732 if (airporttilespec
!= NULL
) {
8733 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8734 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8735 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8742 /* Here we perform initial decoding of some special sprites (as are they
8743 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8744 * partial implementation yet).
8745 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8746 * a crafted invalid GRF file. We should tell that to the user somehow, or
8747 * better make this more robust in the future. */
8748 static void DecodeSpecialSprite(byte
*buf
, uint num
, GrfLoadingStage stage
)
8750 /* XXX: There is a difference between staged loading in TTDPatch and
8751 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8752 * during stage 1, whilst action 3 is carried out during stage 2 (to
8753 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8754 * IDs are valid only within a given set (action 1) block, and may be
8755 * overwritten after action 3 associates them. But overwriting happens
8756 * in an earlier stage than associating, so... We just process actions
8757 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8759 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8760 * is not in memory and scanning the file every time would be too expensive.
8761 * In other stages we skip action 0x10 since it's already dealt with. */
8762 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8763 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8764 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8765 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8766 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8767 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8768 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8769 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8770 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8771 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8772 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8773 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8774 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8775 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8776 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8777 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8778 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8779 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8780 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8781 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8782 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8783 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8786 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8788 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8789 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8790 /* No preloaded sprite to work with; read the
8791 * pseudo sprite content. */
8792 FioReadBlock(buf
, num
);
8794 /* Use the preloaded sprite data. */
8795 buf
= _grf_line_to_action6_sprite_override
[location
];
8796 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8798 /* Skip the real (original) content of this action. */
8799 FioSeekTo(num
, SEEK_CUR
);
8802 ByteReader
br(buf
, buf
+ num
);
8803 ByteReader
*bufp
= &br
;
8806 byte action
= bufp
->ReadByte();
8808 if (action
== 0xFF) {
8809 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8810 } else if (action
== 0xFE) {
8811 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8812 } else if (action
>= lengthof(handlers
)) {
8813 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8814 } else if (handlers
[action
][stage
] == NULL
) {
8815 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8817 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8818 handlers
[action
][stage
](bufp
);
8821 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8822 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS
);
8827 /** Signature of a container version 2 GRF. */
8828 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8831 * Get the container version of the currently opened GRF file.
8832 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8834 byte
GetGRFContainerVersion()
8836 size_t pos
= FioGetPos();
8838 if (FioReadWord() == 0) {
8839 /* Check for GRF container version 2, which is identified by the bytes
8840 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8841 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8842 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
8848 /* Container version 1 has no header, rewind to start. */
8849 FioSeekTo(pos
, SEEK_SET
);
8854 * Load a particular NewGRF.
8855 * @param config The configuration of the to be loaded NewGRF.
8856 * @param file_index The Fio index of the first NewGRF to load.
8857 * @param stage The loading stage of the NewGRF.
8858 * @param subdir The sub directory to find the NewGRF in.
8860 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8862 const char *filename
= config
->filename
;
8864 /* A .grf file is activated only if it was active when the game was
8865 * started. If a game is loaded, only its active .grfs will be
8866 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8867 * considered active if its action 8 has been processed, i.e. its
8868 * action 8 hasn't been skipped using an action 7.
8870 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8871 * carried out. All others are ignored, because they only need to be
8872 * processed once at initialization. */
8873 if (stage
!= GLS_FILESCAN
&& stage
!= GLS_SAFETYSCAN
&& stage
!= GLS_LABELSCAN
) {
8874 _cur
.grffile
= GetFileByFilename(filename
);
8875 if (_cur
.grffile
== NULL
) usererror("File '%s' lost in cache.\n", filename
);
8876 if (stage
== GLS_RESERVE
&& config
->status
!= GCS_INITIALISED
) return;
8877 if (stage
== GLS_ACTIVATION
&& !HasBit(config
->flags
, GCF_RESERVED
)) return;
8880 if (file_index
>= MAX_FILE_SLOTS
) {
8881 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename
);
8882 config
->status
= GCS_DISABLED
;
8883 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
8887 FioOpenFile(file_index
, filename
, subdir
);
8888 _cur
.file_index
= file_index
; // XXX
8889 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8891 _cur
.grfconfig
= config
;
8893 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8895 _cur
.grf_container_ver
= GetGRFContainerVersion();
8896 if (_cur
.grf_container_ver
== 0) {
8897 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8901 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8902 /* We need the sprite offsets in the init stage for NewGRF sounds
8903 * and in the activation stage for real sprites. */
8904 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
8906 /* Skip sprite section offset if present. */
8907 if (_cur
.grf_container_ver
>= 2) FioReadDword();
8910 if (_cur
.grf_container_ver
>= 2) {
8911 /* Read compression value. */
8912 byte compression
= FioReadByte();
8913 if (compression
!= 0) {
8914 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
8919 /* Skip the first sprite; we don't care about how many sprites this
8920 * does contain; newest TTDPatches and George's longvehicles don't
8921 * neither, apparently. */
8922 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8923 if (num
== 4 && FioReadByte() == 0xFF) {
8926 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8930 _cur
.ClearDataForNextFile();
8932 ReusableBuffer
<byte
> buf
;
8934 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8935 byte type
= FioReadByte();
8939 if (_cur
.skip_sprites
== 0) {
8940 DecodeSpecialSprite(buf
.Allocate(num
), num
, stage
);
8942 /* Stop all processing if we are to skip the remaining sprites */
8943 if (_cur
.skip_sprites
== -1) break;
8950 if (_cur
.skip_sprites
== 0) {
8951 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8952 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8956 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
8957 /* Reference to data section. Container version >= 2 only. */
8961 SkipSpriteData(type
, num
- 8);
8965 if (_cur
.skip_sprites
> 0) _cur
.skip_sprites
--;
8970 * Relocates the old shore sprites at new positions.
8972 * 1. If shore sprites are neither loaded by Action5 nor ActionA, the extra sprites from openttd(w/d).grf are used. (SHORE_REPLACE_ONLY_NEW)
8973 * 2. If a newgrf replaces some shore sprites by ActionA. The (maybe also replaced) grass tiles are used for corner shores. (SHORE_REPLACE_ACTION_A)
8974 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8976 static void ActivateOldShore()
8978 /* Use default graphics, if no shore sprites were loaded.
8979 * Should not happen, as the base set's extra grf should include some. */
8980 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
8982 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
8983 DupSprite(SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1); // SLOPE_W
8984 DupSprite(SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2); // SLOPE_S
8985 DupSprite(SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3); // SLOPE_SW
8986 DupSprite(SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4); // SLOPE_E
8987 DupSprite(SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6); // SLOPE_SE
8988 DupSprite(SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8); // SLOPE_N
8989 DupSprite(SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9); // SLOPE_NW
8990 DupSprite(SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12); // SLOPE_NE
8993 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
8994 DupSprite(SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0); // SLOPE_STEEP_S
8995 DupSprite(SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5); // SLOPE_STEEP_W
8996 DupSprite(SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7); // SLOPE_WSE
8997 DupSprite(SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10); // SLOPE_STEEP_N
8998 DupSprite(SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11); // SLOPE_NWS
8999 DupSprite(SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13); // SLOPE_ENW
9000 DupSprite(SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14); // SLOPE_SEN
9001 DupSprite(SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15); // SLOPE_STEEP_E
9003 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9004 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9005 DupSprite(SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16); // SLOPE_EW
9006 DupSprite(SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17); // SLOPE_NS
9011 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9013 static void FinalisePriceBaseMultipliers()
9015 extern const PriceBaseSpec _price_base_specs
[];
9016 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9017 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
9019 /* Evaluate grf overrides */
9020 int num_grfs
= _grf_files
.Length();
9021 int *grf_overrides
= AllocaM(int, num_grfs
);
9022 for (int i
= 0; i
< num_grfs
; i
++) {
9023 grf_overrides
[i
] = -1;
9025 GRFFile
*source
= _grf_files
[i
];
9026 uint32 override
= _grf_id_overrides
[source
->grfid
];
9027 if (override
== 0) continue;
9029 GRFFile
*dest
= GetFileByGRFID(override
);
9030 if (dest
== NULL
) continue;
9032 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
9033 assert(grf_overrides
[i
] >= 0);
9036 /* Override features and price base multipliers of earlier loaded grfs */
9037 for (int i
= 0; i
< num_grfs
; i
++) {
9038 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9039 GRFFile
*source
= _grf_files
[i
];
9040 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9042 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9043 source
->grf_features
|= features
;
9044 dest
->grf_features
|= features
;
9046 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9047 /* No price defined -> nothing to do */
9048 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9049 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9050 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9054 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9055 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9056 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9057 GRFFile
*source
= _grf_files
[i
];
9058 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9060 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9061 source
->grf_features
|= features
;
9062 dest
->grf_features
|= features
;
9064 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9065 /* Already a price defined -> nothing to do */
9066 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9067 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9068 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9072 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9073 for (int i
= 0; i
< num_grfs
; i
++) {
9074 if (grf_overrides
[i
] < 0) continue;
9075 GRFFile
*source
= _grf_files
[i
];
9076 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9078 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9079 source
->grf_features
|= features
;
9080 dest
->grf_features
|= features
;
9082 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9083 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9084 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9085 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9087 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9091 /* Apply fallback prices for grf version < 8 */
9092 const GRFFile
* const *end
= _grf_files
.End();
9093 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9094 if ((*file
)->grf_version
>= 8) continue;
9095 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9096 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9097 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9098 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9099 /* No price multiplier has been set.
9100 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9101 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9106 /* Decide local/global scope of price base multipliers */
9107 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9108 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9109 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9110 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9111 /* No multiplier was set; set it to a neutral value */
9112 price_base_multipliers
[p
] = 0;
9114 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9115 /* The grf does not define any objects of the feature,
9116 * so it must be a difficulty setting. Apply it globally */
9117 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9118 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9119 price_base_multipliers
[p
] = 0;
9121 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9128 extern void InitGRFTownGeneratorNames();
9130 /** Finish loading NewGRFs and execute needed post-processing */
9131 static void AfterLoadGRFs()
9133 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9134 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9136 _string_to_grf_mapping
.Clear();
9138 /* Free the action 6 override sprites. */
9139 for (GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.begin(); it
!= _grf_line_to_action6_sprite_override
.end(); it
++) {
9142 _grf_line_to_action6_sprite_override
.clear();
9144 /* Polish cargoes */
9145 FinaliseCargoArray();
9147 /* Pre-calculate all refit masks after loading GRF files. */
9148 CalculateRefitMasks();
9150 /* Polish engines */
9151 FinaliseEngineArray();
9153 /* Set the actually used Canal properties */
9156 /* Add all new houses to the house array. */
9157 FinaliseHouseArray();
9159 /* Add all new industries to the industry array. */
9160 FinaliseIndustriesArray();
9162 /* Add all new objects to the object array. */
9163 FinaliseObjectsArray();
9165 InitializeSortedCargoSpecs();
9167 /* Sort the list of industry types. */
9168 SortIndustryTypes();
9170 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9171 BuildIndustriesLegend();
9173 /* Build the routemap legend, based on the available cargos */
9174 BuildLinkStatsLegend();
9176 /* Add all new airports to the airports array. */
9177 FinaliseAirportsArray();
9180 /* Update the townname generators list */
9181 InitGRFTownGeneratorNames();
9183 /* Run all queued vehicle list order changes */
9184 CommitVehicleListOrderChanges();
9186 /* Load old shore sprites in new position, if they were replaced by ActionA */
9189 /* Set up custom rail types */
9193 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9194 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9195 /* Set RV maximum speed from the mph/0.8 unit value */
9196 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9200 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9201 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9202 if (railtype
== INVALID_RAILTYPE
) {
9203 /* Rail type is not available, so disable this engine */
9204 e
->info
.climates
= 0;
9206 e
->u
.rail
.railtype
= railtype
;
9210 SetYearEngineAgingStops();
9212 FinalisePriceBaseMultipliers();
9214 /* Deallocate temporary loading data */
9216 _grm_sprites
.clear();
9220 * Load all the NewGRFs.
9221 * @param load_index The offset for the first sprite to add.
9222 * @param file_index The Fio index of the first NewGRF to load.
9223 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9225 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9227 /* In case of networking we need to "sync" the start values
9228 * so all NewGRFs are loaded equally. For this we use the
9229 * start date of the game and we set the counters, etc. to
9230 * 0 so they're the same too. */
9232 Year year
= _cur_year
;
9233 DateFract date_fract
= _date_fract
;
9234 uint16 tick_counter
= _tick_counter
;
9235 byte display_opt
= _display_opt
;
9238 _cur_year
= _settings_game
.game_creation
.starting_year
;
9239 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9245 InitializeGRFSpecial();
9250 * Reset the status of all files, so we can 'retry' to load them.
9251 * This is needed when one for example rearranges the NewGRFs in-game
9252 * and a previously disabled NewGRF becomes useable. If it would not
9253 * be reset, the NewGRF would remain disabled even though it should
9254 * have been enabled.
9256 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9257 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9260 _cur
.spriteid
= load_index
;
9262 /* Load newgrf sprites
9263 * in each loading stage, (try to) open each file specified in the config
9264 * and load information from it. */
9265 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9266 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9267 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9268 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9269 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9272 if (stage
== GLS_RESERVE
) {
9273 static const uint32 overrides
[][2] = {
9274 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9275 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9276 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9278 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9279 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9283 uint slot
= file_index
;
9284 uint num_non_static
= 0;
9287 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9288 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9289 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9291 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9292 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9293 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9294 c
->status
= GCS_NOT_FOUND
;
9298 if (stage
== GLS_LABELSCAN
) InitNewGRFFile(c
);
9300 if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9301 if (num_non_static
== NETWORK_MAX_GRF_COUNT
) {
9302 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9303 c
->status
= GCS_DISABLED
;
9304 c
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9309 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9310 if (stage
== GLS_RESERVE
) {
9311 SetBit(c
->flags
, GCF_RESERVED
);
9312 } else if (stage
== GLS_ACTIVATION
) {
9313 ClrBit(c
->flags
, GCF_RESERVED
);
9314 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9315 ClearTemporaryNewGRFData(_cur
.grffile
);
9316 BuildCargoTranslationMap();
9317 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9318 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9319 /* We're not going to activate this, so free whatever data we allocated */
9320 ClearTemporaryNewGRFData(_cur
.grffile
);
9325 /* Pseudo sprite processing is finished; free temporary stuff */
9326 _cur
.ClearDataForNextFile();
9328 /* Call any functions that should be run after GRFs have been loaded. */
9331 /* Now revert back to the original situation */
9334 _date_fract
= date_fract
;
9335 _tick_counter
= tick_counter
;
9336 _display_opt
= display_opt
;