OpenTTD: src/newgrf.cpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

newgrf.cpp
Go to the documentation of this file.
1 /* $Id: newgrf.cpp 27507 2016-02-08 21:05:57Z frosch $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
9
12 #include "stdafx.h"
13
14 #include <stdarg.h>
15
16 #include "debug.h"
17 #include "fileio_func.h"
18 #include "engine_func.h"
19 #include "engine_base.h"
20 #include "bridge.h"
21 #include "town.h"
22 #include "newgrf_engine.h"
23 #include "newgrf_text.h"
24 #include "fontcache.h"
25 #include "currency.h"
26 #include "landscape.h"
27 #include "newgrf_cargo.h"
28 #include "newgrf_house.h"
29 #include "newgrf_sound.h"
30 #include "newgrf_station.h"
31 #include "industrytype.h"
32 #include "newgrf_canal.h"
33 #include "newgrf_townname.h"
34 #include "newgrf_industries.h"
35 #include "newgrf_airporttiles.h"
36 #include "newgrf_airport.h"
37 #include "newgrf_object.h"
38 #include "rev.h"
39 #include "fios.h"
40 #include "strings_func.h"
41 #include "date_func.h"
42 #include "string_func.h"
43 #include "network/network.h"
44 #include <map>
45 #include "smallmap_gui.h"
46 #include "genworld.h"
47 #include "error.h"
48 #include "vehicle_func.h"
49 #include "language.h"
50 #include "vehicle_base.h"
51
52 #include "table/strings.h"
53 #include "table/build_industry.h"
54
55 #include "safeguards.h"
56
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
60 *
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
65
67 static SmallVector<GRFFile *, 16> _grf_files;
68
70 byte _misc_grf_features = 0;
71
73 static uint32 _ttdpatch_flags[8];
74
76 GRFLoadedFeatures _loaded_newgrf_features;
77
78 static const uint MAX_SPRITEGROUP = UINT8_MAX;
79
81 struct GrfProcessingState {
82 private:
84 struct SpriteSet {
85 SpriteID sprite;
86 uint num_sprites;
87 };
88
90 std::map<uint, SpriteSet> spritesets[GSF_END];
91
92 public:
93 /* Global state */
94 GrfLoadingStage stage;
95 SpriteID spriteid;
96
97 /* Local state in the file */
98 uint file_index;
99 GRFFile *grffile;
100 GRFConfig *grfconfig;
101 uint32 nfo_line;
102 byte grf_container_ver;
103
104 /* Kind of return values when processing certain actions */
105 int skip_sprites;
106
107 /* Currently referenceable spritegroups */
108 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
109
111 void ClearDataForNextFile()
112 {
113 this->nfo_line = 0;
114 this->skip_sprites = 0;
115
116 for (uint i = 0; i < GSF_END; i++) {
117 this->spritesets[i].clear();
118 }
119
120 memset(this->spritegroups, 0, sizeof(this->spritegroups));
121 }
122
131 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
132 {
133 assert(feature < GSF_END);
134 for (uint i = 0; i < numsets; i++) {
135 SpriteSet &set = this->spritesets[feature][first_set + i];
136 set.sprite = first_sprite + i * numents;
137 set.num_sprites = numents;
138 }
139 }
140
147 bool HasValidSpriteSets(byte feature) const
148 {
149 assert(feature < GSF_END);
150 return !this->spritesets[feature].empty();
151 }
152
160 bool IsValidSpriteSet(byte feature, uint set) const
161 {
162 assert(feature < GSF_END);
163 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
164 }
165
172 SpriteID GetSprite(byte feature, uint set) const
173 {
174 assert(IsValidSpriteSet(feature, set));
175 return this->spritesets[feature].find(set)->second.sprite;
176 }
177
184 uint GetNumEnts(byte feature, uint set) const
185 {
186 assert(IsValidSpriteSet(feature, set));
187 return this->spritesets[feature].find(set)->second.num_sprites;
188 }
189 };
190
191 static GrfProcessingState _cur;
192
193
200 template <VehicleType T>
201 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
202 {
203 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
204 }
205
206 class OTTDByteReaderSignal { };
207
209 class ByteReader {
210 protected:
211 byte *data;
212 byte *end;
213
214 public:
215 ByteReader(byte *data, byte *end) : data(data), end(end) { }
216
217 inline byte ReadByte()
218 {
219 if (data < end) return *(data)++;
220 throw OTTDByteReaderSignal();
221 }
222
223 uint16 ReadWord()
224 {
225 uint16 val = ReadByte();
226 return val | (ReadByte() << 8);
227 }
228
229 uint16 ReadExtendedByte()
230 {
231 uint16 val = ReadByte();
232 return val == 0xFF ? ReadWord() : val;
233 }
234
235 uint32 ReadDWord()
236 {
237 uint32 val = ReadWord();
238 return val | (ReadWord() << 16);
239 }
240
241 uint32 ReadVarSize(byte size)
242 {
243 switch (size) {
244 case 1: return ReadByte();
245 case 2: return ReadWord();
246 case 4: return ReadDWord();
247 default:
248 NOT_REACHED();
249 return 0;
250 }
251 }
252
253 const char *ReadString()
254 {
255 char *string = reinterpret_cast<char *>(data);
256 size_t string_length = ttd_strnlen(string, Remaining());
257
258 if (string_length == Remaining()) {
259 /* String was not NUL terminated, so make sure it is now. */
260 string[string_length - 1] = '\0';
261 grfmsg(7, "String was not terminated with a zero byte.");
262 } else {
263 /* Increase the string length to include the NUL byte. */
264 string_length++;
265 }
266 Skip(string_length);
267
268 return string;
269 }
270
271 inline size_t Remaining() const
272 {
273 return end - data;
274 }
275
276 inline bool HasData(size_t count = 1) const
277 {
278 return data + count <= end;
279 }
280
281 inline byte *Data()
282 {
283 return data;
284 }
285
286 inline void Skip(size_t len)
287 {
288 data += len;
289 /* It is valid to move the buffer to exactly the end of the data,
290 * as there may not be any more data read. */
291 if (data > end) throw OTTDByteReaderSignal();
292 }
293 };
294
295 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
296
297 static const uint NUM_STATIONS_PER_GRF = 255;
298
300 struct GRFTempEngineData {
302 enum Refittability {
303 UNSET = 0,
304 EMPTY,
305 NONEMPTY,
306 };
307
308 uint16 cargo_allowed;
309 uint16 cargo_disallowed;
310 RailTypeLabel railtypelabel;
311 const GRFFile *defaultcargo_grf;
312 Refittability refittability;
313 bool prop27_set;
314 uint8 rv_max_speed;
315 uint32 ctt_include_mask;
316 uint32 ctt_exclude_mask;
317
322 void UpdateRefittability(bool non_empty)
323 {
324 if (non_empty) {
325 this->refittability = NONEMPTY;
326 } else if (this->refittability == UNSET) {
327 this->refittability = EMPTY;
328 }
329 }
330 };
331
332 static GRFTempEngineData *_gted;
333
338 static uint32 _grm_engines[256];
339
341 static uint32 _grm_cargoes[NUM_CARGO * 2];
342
343 struct GRFLocation {
344 uint32 grfid;
345 uint32 nfoline;
346
347 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
348
349 bool operator<(const GRFLocation &other) const
350 {
351 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
352 }
353
354 bool operator == (const GRFLocation &other) const
355 {
356 return this->grfid == other.grfid && this->nfoline == other.nfoline;
357 }
358 };
359
360 static std::map<GRFLocation, SpriteID> _grm_sprites;
361 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
362 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
363
374 void CDECL grfmsg(int severity, const char *str, ...)
375 {
376 char buf[1024];
377 va_list va;
378
379 va_start(va, str);
380 vseprintf(buf, lastof(buf), str, va);
381 va_end(va);
382
383 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
384 }
385
391 static GRFFile *GetFileByGRFID(uint32 grfid)
392 {
393 const GRFFile * const *end = _grf_files.End();
394 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
395 if ((*file)->grfid == grfid) return *file;
396 }
397 return NULL;
398 }
399
405 static GRFFile *GetFileByFilename(const char *filename)
406 {
407 const GRFFile * const *end = _grf_files.End();
408 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
409 if (strcmp((*file)->filename, filename) == 0) return *file;
410 }
411 return NULL;
412 }
413
415 static void ClearTemporaryNewGRFData(GRFFile *gf)
416 {
417 /* Clear the GOTO labels used for GRF processing */
418 for (GRFLabel *l = gf->label; l != NULL;) {
419 GRFLabel *l2 = l->next;
420 free(l);
421 l = l2;
422 }
423 gf->label = NULL;
424 }
425
432 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
433 {
434 GRFFile *file;
435 if (config != NULL) {
436 file = GetFileByGRFID(config->ident.grfid);
437 } else {
438 config = _cur.grfconfig;
439 file = _cur.grffile;
440 }
441
442 config->status = GCS_DISABLED;
443 if (file != NULL) ClearTemporaryNewGRFData(file);
444 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
445
446 if (message != STR_NULL) {
447 delete config->error;
448 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
449 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
450 }
451
452 return config->error;
453 }
454
458 struct StringIDMapping {
459 uint32 grfid;
460 StringID source;
461 StringID *target;
462 };
463 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
464 static StringIDMappingVector _string_to_grf_mapping;
465
471 static void AddStringForMapping(StringID source, StringID *target)
472 {
473 *target = STR_UNDEFINED;
474 StringIDMapping *item = _string_to_grf_mapping.Append();
475 item->grfid = _cur.grffile->grfid;
476 item->source = source;
477 item->target = target;
478 }
479
487 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
488 {
489 /* StringID table for TextIDs 0x4E->0x6D */
490 static const StringID units_volume[] = {
491 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
499 };
500
501 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
502 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
503
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 assert_compile(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
507
508 /* We have some changes in our cargo strings, resulting in some missing. */
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
515
516 /* Map building names according to our lang file changes. There are several
517 * ranges of house ids, all of which need to be remapped to allow newgrfs
518 * to use original house names. */
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
522
523 /* Same thing for industries */
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
529
530 switch (str) {
531 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
534 }
535 #undef TEXTID_TO_STRINGID
536
537 if (str == STR_NULL) return STR_EMPTY;
538
539 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
540
541 return STR_EMPTY;
542 }
543
551 StringID MapGRFStringID(uint32 grfid, StringID str)
552 {
553 /* 0xD0 and 0xDC stand for all the TextIDs in the range
554 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
555 * These strings are unique to each grf file, and thus require to be used with the
556 * grfid in which they are declared */
557 switch (GB(str, 8, 8)) {
558 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
559 case 0xDC:
560 return GetGRFStringID(grfid, str);
561
562 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
563 /* Strings embedded via 0x81 have 0x400 added to them (no real
564 * explanation why...) */
565 return GetGRFStringID(grfid, str - 0x400);
566
567 default: break;
568 }
569
570 return TTDPStringIDToOTTDStringIDMapping(str);
571 }
572
573 static std::map<uint32, uint32> _grf_id_overrides;
574
580 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
581 {
582 _grf_id_overrides[source_grfid] = target_grfid;
583 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
584 }
585
594 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
595 {
596 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
597 * them use the same engine slots. */
598 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
599 if (_settings_game.vehicle.dynamic_engines) {
600 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
601 scope_grfid = file->grfid;
602 uint32 override = _grf_id_overrides[file->grfid];
603 if (override != 0) {
604 scope_grfid = override;
605 const GRFFile *grf_match = GetFileByGRFID(override);
606 if (grf_match == NULL) {
607 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
608 } else {
609 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
610 }
611 }
612
613 /* Check if the engine is registered in the override manager */
614 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
615 if (engine != INVALID_ENGINE) {
616 Engine *e = Engine::Get(engine);
617 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
618 return e;
619 }
620 }
621
622 /* Check if there is an unreserved slot */
623 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
624 if (engine != INVALID_ENGINE) {
625 Engine *e = Engine::Get(engine);
626
627 if (e->grf_prop.grffile == NULL) {
628 e->grf_prop.grffile = file;
629 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
630 }
631
632 /* Reserve the engine slot */
633 if (!static_access) {
634 EngineIDMapping *eid = _engine_mngr.Get(engine);
635 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
636 }
637
638 return e;
639 }
640
641 if (static_access) return NULL;
642
643 if (!Engine::CanAllocateItem()) {
644 grfmsg(0, "Can't allocate any more engines");
645 return NULL;
646 }
647
648 size_t engine_pool_size = Engine::GetPoolSize();
649
650 /* ... it's not, so create a new one based off an existing engine */
651 Engine *e = new Engine(type, internal_id);
652 e->grf_prop.grffile = file;
653
654 /* Reserve the engine slot */
655 assert(_engine_mngr.Length() == e->index);
656 EngineIDMapping *eid = _engine_mngr.Append();
657 eid->type = type;
658 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
659 eid->internal_id = internal_id;
660 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
661
662 if (engine_pool_size != Engine::GetPoolSize()) {
663 /* Resize temporary engine data ... */
664 _gted = ReallocT(_gted, Engine::GetPoolSize());
665
666 /* and blank the new block. */
667 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
668 memset(_gted + engine_pool_size, 0, len);
669 }
670 if (type == VEH_TRAIN) {
671 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
672 }
673
674 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
675
676 return e;
677 }
678
689 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
690 {
691 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
692 if (_settings_game.vehicle.dynamic_engines) {
693 scope_grfid = file->grfid;
694 uint32 override = _grf_id_overrides[file->grfid];
695 if (override != 0) scope_grfid = override;
696 }
697
698 return _engine_mngr.GetID(type, internal_id, scope_grfid);
699 }
700
705 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
706 {
707 if (HasBit(grf_sprite->pal, 14)) {
708 ClrBit(grf_sprite->pal, 14);
709 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
710 }
711
712 if (HasBit(grf_sprite->sprite, 14)) {
713 ClrBit(grf_sprite->sprite, 14);
714 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
715 }
716
717 if (HasBit(grf_sprite->sprite, 15)) {
718 ClrBit(grf_sprite->sprite, 15);
719 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
720 }
721 }
722
736 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)
737 {
738 grf_sprite->sprite = buf->ReadWord();
739 grf_sprite->pal = buf->ReadWord();
740 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
741
742 MapSpriteMappingRecolour(grf_sprite);
743
744 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
745 ClrBit(grf_sprite->pal, 15);
746 if (custom_sprite) {
747 /* Use sprite from Action 1 */
748 uint index = GB(grf_sprite->sprite, 0, 14);
749 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
750 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
751 grf_sprite->sprite = SPR_IMG_QUERY;
752 grf_sprite->pal = PAL_NONE;
753 } else {
754 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
755 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
756 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
757 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
758 }
759 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
760 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
761 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
762 return flags;
763 }
764
765 if (flags & TLF_CUSTOM_PALETTE) {
766 /* Use palette from Action 1 */
767 uint index = GB(grf_sprite->pal, 0, 14);
768 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
769 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
770 grf_sprite->pal = PAL_NONE;
771 } else {
772 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
773 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
774 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
775 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
776 }
777 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
778 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
779 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
780 return flags;
781 }
782
783 return flags;
784 }
785
794 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
795 {
796 if (!(flags & TLF_DRAWING_FLAGS)) return;
797
798 if (dts->registers == NULL) dts->AllocateRegisters();
799 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
800 regs.flags = flags & TLF_DRAWING_FLAGS;
801
802 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
803 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
804 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
805
806 if (is_parent) {
807 if (flags & TLF_BB_XY_OFFSET) {
808 regs.delta.parent[0] = buf->ReadByte();
809 regs.delta.parent[1] = buf->ReadByte();
810 }
811 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
812 } else {
813 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
814 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
815 }
816
817 if (flags & TLF_SPRITE_VAR10) {
818 regs.sprite_var10 = buf->ReadByte();
819 if (regs.sprite_var10 > TLR_MAX_VAR10) {
820 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
821 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
822 return;
823 }
824 }
825
826 if (flags & TLF_PALETTE_VAR10) {
827 regs.palette_var10 = buf->ReadByte();
828 if (regs.palette_var10 > TLR_MAX_VAR10) {
829 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
830 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
831 return;
832 }
833 }
834 }
835
847 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
848 {
849 bool has_flags = HasBit(num_building_sprites, 6);
850 ClrBit(num_building_sprites, 6);
851 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
852 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
853 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
854
855 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
856 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
857 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
858 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
859
860 /* Groundsprite */
861 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
862 if (_cur.skip_sprites < 0) return true;
863
864 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
865 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
866 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
867 return true;
868 }
869
870 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
871 if (_cur.skip_sprites < 0) return true;
872
873 for (uint i = 0; i < num_building_sprites; i++) {
874 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
875
876 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
877 if (_cur.skip_sprites < 0) return true;
878
879 if (flags & ~valid_flags) {
880 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
881 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
882 return true;
883 }
884
885 seq->delta_x = buf->ReadByte();
886 seq->delta_y = buf->ReadByte();
887
888 if (!no_z_position) seq->delta_z = buf->ReadByte();
889
890 if (seq->IsParentSprite()) {
891 seq->size_x = buf->ReadByte();
892 seq->size_y = buf->ReadByte();
893 seq->size_z = buf->ReadByte();
894 }
895
896 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
897 if (_cur.skip_sprites < 0) return true;
898 }
899
900 /* Check if the number of sprites per spriteset is consistent */
901 bool is_consistent = true;
902 dts->consistent_max_offset = 0;
903 for (uint i = 0; i < num_building_sprites + 1; i++) {
904 if (max_sprite_offset[i] > 0) {
905 if (dts->consistent_max_offset == 0) {
906 dts->consistent_max_offset = max_sprite_offset[i];
907 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
908 is_consistent = false;
909 break;
910 }
911 }
912 if (max_palette_offset[i] > 0) {
913 if (dts->consistent_max_offset == 0) {
914 dts->consistent_max_offset = max_palette_offset[i];
915 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
916 is_consistent = false;
917 break;
918 }
919 }
920 }
921
922 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
923 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
924
925 if (!is_consistent || dts->registers != NULL) {
926 dts->consistent_max_offset = 0;
927 if (dts->registers == NULL) dts->AllocateRegisters();
928
929 for (uint i = 0; i < num_building_sprites + 1; i++) {
930 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
931 regs.max_sprite_offset = max_sprite_offset[i];
932 regs.max_palette_offset = max_palette_offset[i];
933 }
934 }
935
936 return false;
937 }
938
942 static uint32 TranslateRefitMask(uint32 refit_mask)
943 {
944 uint32 result = 0;
945 uint8 bit;
946 FOR_EACH_SET_BIT(bit, refit_mask) {
947 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
948 if (cargo != CT_INVALID) SetBit(result, cargo);
949 }
950 return result;
951 }
952
960 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
961 {
962 /* Special value for 'none' */
963 if (base_pointer == 0) {
964 *index = INVALID_PRICE;
965 return;
966 }
967
968 static const uint32 start = 0x4B34;
969 static const uint32 size = 6;
970
971 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
972 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
973 return;
974 }
975
976 *index = (Price)((base_pointer - start) / size);
977 }
978
980 enum ChangeInfoResult {
981 CIR_SUCCESS,
982 CIR_DISABLED,
983 CIR_UNHANDLED,
984 CIR_UNKNOWN,
985 CIR_INVALID_ID,
986 };
987
988 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
989
997 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
998 {
999 switch (prop) {
1000 case 0x00: // Introduction date
1001 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1002 break;
1003
1004 case 0x02: // Decay speed
1005 ei->decay_speed = buf->ReadByte();
1006 break;
1007
1008 case 0x03: // Vehicle life
1009 ei->lifelength = buf->ReadByte();
1010 break;
1011
1012 case 0x04: // Model life
1013 ei->base_life = buf->ReadByte();
1014 break;
1015
1016 case 0x06: // Climates available
1017 ei->climates = buf->ReadByte();
1018 break;
1019
1020 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1021 /* Amount of cargo loaded during a vehicle's "loading tick" */
1022 ei->load_amount = buf->ReadByte();
1023 break;
1024
1025 default:
1026 return CIR_UNKNOWN;
1027 }
1028
1029 return CIR_SUCCESS;
1030 }
1031
1040 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1041 {
1042 ChangeInfoResult ret = CIR_SUCCESS;
1043
1044 for (int i = 0; i < numinfo; i++) {
1045 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1046 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1047
1048 EngineInfo *ei = &e->info;
1049 RailVehicleInfo *rvi = &e->u.rail;
1050
1051 switch (prop) {
1052 case 0x05: { // Track type
1053 uint8 tracktype = buf->ReadByte();
1054
1055 if (tracktype < _cur.grffile->railtype_list.Length()) {
1056 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1057 break;
1058 }
1059
1060 switch (tracktype) {
1061 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1062 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1063 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1064 default:
1065 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1066 break;
1067 }
1068 break;
1069 }
1070
1071 case 0x08: // AI passenger service
1072 /* Tells the AI that this engine is designed for
1073 * passenger services and shouldn't be used for freight. */
1074 rvi->ai_passenger_only = buf->ReadByte();
1075 break;
1076
1077 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1078 uint16 speed = buf->ReadWord();
1079 if (speed == 0xFFFF) speed = 0;
1080
1081 rvi->max_speed = speed;
1082 break;
1083 }
1084
1085 case PROP_TRAIN_POWER: // 0x0B Power
1086 rvi->power = buf->ReadWord();
1087
1088 /* Set engine / wagon state based on power */
1089 if (rvi->power != 0) {
1090 if (rvi->railveh_type == RAILVEH_WAGON) {
1091 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1092 }
1093 } else {
1094 rvi->railveh_type = RAILVEH_WAGON;
1095 }
1096 break;
1097
1098 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1099 rvi->running_cost = buf->ReadByte();
1100 break;
1101
1102 case 0x0E: // Running cost base
1103 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1104 break;
1105
1106 case 0x12: { // Sprite ID
1107 uint8 spriteid = buf->ReadByte();
1108 uint8 orig_spriteid = spriteid;
1109
1110 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1111 * as an array index, so we need it to be half the original value. */
1112 if (spriteid < 0xFD) spriteid >>= 1;
1113
1114 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1115 rvi->image_index = spriteid;
1116 } else {
1117 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1118 rvi->image_index = 0;
1119 }
1120 break;
1121 }
1122
1123 case 0x13: { // Dual-headed
1124 uint8 dual = buf->ReadByte();
1125
1126 if (dual != 0) {
1127 rvi->railveh_type = RAILVEH_MULTIHEAD;
1128 } else {
1129 rvi->railveh_type = rvi->power == 0 ?
1130 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1131 }
1132 break;
1133 }
1134
1135 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1136 rvi->capacity = buf->ReadByte();
1137 break;
1138
1139 case 0x15: { // Cargo type
1140 _gted[e->index].defaultcargo_grf = _cur.grffile;
1141 uint8 ctype = buf->ReadByte();
1142
1143 if (ctype == 0xFF) {
1144 /* 0xFF is specified as 'use first refittable' */
1145 ei->cargo_type = CT_INVALID;
1146 } else if (_cur.grffile->grf_version >= 8) {
1147 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1148 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1149 } else if (ctype < NUM_CARGO) {
1150 /* Use untranslated cargo. */
1151 ei->cargo_type = ctype;
1152 } else {
1153 ei->cargo_type = CT_INVALID;
1154 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1155 }
1156 break;
1157 }
1158
1159 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1160 SB(rvi->weight, 0, 8, buf->ReadByte());
1161 break;
1162
1163 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1164 rvi->cost_factor = buf->ReadByte();
1165 break;
1166
1167 case 0x18: // AI rank
1168 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1169 buf->ReadByte();
1170 break;
1171
1172 case 0x19: { // Engine traction type
1173 /* What do the individual numbers mean?
1174 * 0x00 .. 0x07: Steam
1175 * 0x08 .. 0x27: Diesel
1176 * 0x28 .. 0x31: Electric
1177 * 0x32 .. 0x37: Monorail
1178 * 0x38 .. 0x41: Maglev
1179 */
1180 uint8 traction = buf->ReadByte();
1181 EngineClass engclass;
1182
1183 if (traction <= 0x07) {
1184 engclass = EC_STEAM;
1185 } else if (traction <= 0x27) {
1186 engclass = EC_DIESEL;
1187 } else if (traction <= 0x31) {
1188 engclass = EC_ELECTRIC;
1189 } else if (traction <= 0x37) {
1190 engclass = EC_MONORAIL;
1191 } else if (traction <= 0x41) {
1192 engclass = EC_MAGLEV;
1193 } else {
1194 break;
1195 }
1196
1197 if (_cur.grffile->railtype_list.Length() == 0) {
1198 /* Use traction type to select between normal and electrified
1199 * rail only when no translation list is in place. */
1200 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1201 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1202 }
1203
1204 rvi->engclass = engclass;
1205 break;
1206 }
1207
1208 case 0x1A: // Alter purchase list sort order
1209 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1210 break;
1211
1212 case 0x1B: // Powered wagons power bonus
1213 rvi->pow_wag_power = buf->ReadWord();
1214 break;
1215
1216 case 0x1C: // Refit cost
1217 ei->refit_cost = buf->ReadByte();
1218 break;
1219
1220 case 0x1D: { // Refit cargo
1221 uint32 mask = buf->ReadDWord();
1222 _gted[e->index].UpdateRefittability(mask != 0);
1223 ei->refit_mask = TranslateRefitMask(mask);
1224 _gted[e->index].defaultcargo_grf = _cur.grffile;
1225 break;
1226 }
1227
1228 case 0x1E: // Callback
1229 ei->callback_mask = buf->ReadByte();
1230 break;
1231
1232 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1233 rvi->tractive_effort = buf->ReadByte();
1234 break;
1235
1236 case 0x20: // Air drag
1237 rvi->air_drag = buf->ReadByte();
1238 break;
1239
1240 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1241 rvi->shorten_factor = buf->ReadByte();
1242 break;
1243
1244 case 0x22: // Visual effect
1245 rvi->visual_effect = buf->ReadByte();
1246 /* Avoid accidentally setting visual_effect to the default value
1247 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1248 if (rvi->visual_effect == VE_DEFAULT) {
1249 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1250 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1251 }
1252 break;
1253
1254 case 0x23: // Powered wagons weight bonus
1255 rvi->pow_wag_weight = buf->ReadByte();
1256 break;
1257
1258 case 0x24: { // High byte of vehicle weight
1259 byte weight = buf->ReadByte();
1260
1261 if (weight > 4) {
1262 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1263 } else {
1264 SB(rvi->weight, 8, 8, weight);
1265 }
1266 break;
1267 }
1268
1269 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1270 rvi->user_def_data = buf->ReadByte();
1271 break;
1272
1273 case 0x26: // Retire vehicle early
1274 ei->retire_early = buf->ReadByte();
1275 break;
1276
1277 case 0x27: // Miscellaneous flags
1278 ei->misc_flags = buf->ReadByte();
1279 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1280 _gted[e->index].prop27_set = true;
1281 break;
1282
1283 case 0x28: // Cargo classes allowed
1284 _gted[e->index].cargo_allowed = buf->ReadWord();
1285 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1286 _gted[e->index].defaultcargo_grf = _cur.grffile;
1287 break;
1288
1289 case 0x29: // Cargo classes disallowed
1290 _gted[e->index].cargo_disallowed = buf->ReadWord();
1291 _gted[e->index].UpdateRefittability(false);
1292 break;
1293
1294 case 0x2A: // Long format introduction date (days since year 0)
1295 ei->base_intro = buf->ReadDWord();
1296 break;
1297
1298 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1299 ei->cargo_age_period = buf->ReadWord();
1300 break;
1301
1302 case 0x2C: // CTT refit include list
1303 case 0x2D: { // CTT refit exclude list
1304 uint8 count = buf->ReadByte();
1305 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1306 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1307 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1308 ctt = 0;
1309 while (count--) {
1310 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1311 if (ctype == CT_INVALID) continue;
1312 SetBit(ctt, ctype);
1313 }
1314 break;
1315 }
1316
1317 default:
1318 ret = CommonVehicleChangeInfo(ei, prop, buf);
1319 break;
1320 }
1321 }
1322
1323 return ret;
1324 }
1325
1334 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1335 {
1336 ChangeInfoResult ret = CIR_SUCCESS;
1337
1338 for (int i = 0; i < numinfo; i++) {
1339 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1340 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1341
1342 EngineInfo *ei = &e->info;
1343 RoadVehicleInfo *rvi = &e->u.road;
1344
1345 switch (prop) {
1346 case 0x08: // Speed (1 unit is 0.5 kmh)
1347 rvi->max_speed = buf->ReadByte();
1348 break;
1349
1350 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1351 rvi->running_cost = buf->ReadByte();
1352 break;
1353
1354 case 0x0A: // Running cost base
1355 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1356 break;
1357
1358 case 0x0E: { // Sprite ID
1359 uint8 spriteid = buf->ReadByte();
1360 uint8 orig_spriteid = spriteid;
1361
1362 /* cars have different custom id in the GRF file */
1363 if (spriteid == 0xFF) spriteid = 0xFD;
1364
1365 if (spriteid < 0xFD) spriteid >>= 1;
1366
1367 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1368 rvi->image_index = spriteid;
1369 } else {
1370 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1371 rvi->image_index = 0;
1372 }
1373 break;
1374 }
1375
1376 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1377 rvi->capacity = buf->ReadByte();
1378 break;
1379
1380 case 0x10: { // Cargo type
1381 _gted[e->index].defaultcargo_grf = _cur.grffile;
1382 uint8 ctype = buf->ReadByte();
1383
1384 if (ctype == 0xFF) {
1385 /* 0xFF is specified as 'use first refittable' */
1386 ei->cargo_type = CT_INVALID;
1387 } else if (_cur.grffile->grf_version >= 8) {
1388 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1389 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1390 } else if (ctype < NUM_CARGO) {
1391 /* Use untranslated cargo. */
1392 ei->cargo_type = ctype;
1393 } else {
1394 ei->cargo_type = CT_INVALID;
1395 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1396 }
1397 break;
1398 }
1399
1400 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1401 rvi->cost_factor = buf->ReadByte();
1402 break;
1403
1404 case 0x12: // SFX
1405 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1406 break;
1407
1408 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1409 rvi->power = buf->ReadByte();
1410 break;
1411
1412 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1413 rvi->weight = buf->ReadByte();
1414 break;
1415
1416 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1417 _gted[e->index].rv_max_speed = buf->ReadByte();
1418 break;
1419
1420 case 0x16: { // Cargoes available for refitting
1421 uint32 mask = buf->ReadDWord();
1422 _gted[e->index].UpdateRefittability(mask != 0);
1423 ei->refit_mask = TranslateRefitMask(mask);
1424 _gted[e->index].defaultcargo_grf = _cur.grffile;
1425 break;
1426 }
1427
1428 case 0x17: // Callback mask
1429 ei->callback_mask = buf->ReadByte();
1430 break;
1431
1432 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1433 rvi->tractive_effort = buf->ReadByte();
1434 break;
1435
1436 case 0x19: // Air drag
1437 rvi->air_drag = buf->ReadByte();
1438 break;
1439
1440 case 0x1A: // Refit cost
1441 ei->refit_cost = buf->ReadByte();
1442 break;
1443
1444 case 0x1B: // Retire vehicle early
1445 ei->retire_early = buf->ReadByte();
1446 break;
1447
1448 case 0x1C: // Miscellaneous flags
1449 ei->misc_flags = buf->ReadByte();
1450 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1451 break;
1452
1453 case 0x1D: // Cargo classes allowed
1454 _gted[e->index].cargo_allowed = buf->ReadWord();
1455 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1456 _gted[e->index].defaultcargo_grf = _cur.grffile;
1457 break;
1458
1459 case 0x1E: // Cargo classes disallowed
1460 _gted[e->index].cargo_disallowed = buf->ReadWord();
1461 _gted[e->index].UpdateRefittability(false);
1462 break;
1463
1464 case 0x1F: // Long format introduction date (days since year 0)
1465 ei->base_intro = buf->ReadDWord();
1466 break;
1467
1468 case 0x20: // Alter purchase list sort order
1469 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1470 break;
1471
1472 case 0x21: // Visual effect
1473 rvi->visual_effect = buf->ReadByte();
1474 /* Avoid accidentally setting visual_effect to the default value
1475 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1476 if (rvi->visual_effect == VE_DEFAULT) {
1477 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1478 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1479 }
1480 break;
1481
1482 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1483 ei->cargo_age_period = buf->ReadWord();
1484 break;
1485
1486 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1487 rvi->shorten_factor = buf->ReadByte();
1488 break;
1489
1490 case 0x24: // CTT refit include list
1491 case 0x25: { // CTT refit exclude list
1492 uint8 count = buf->ReadByte();
1493 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1494 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1495 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1496 ctt = 0;
1497 while (count--) {
1498 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1499 if (ctype == CT_INVALID) continue;
1500 SetBit(ctt, ctype);
1501 }
1502 break;
1503 }
1504
1505 default:
1506 ret = CommonVehicleChangeInfo(ei, prop, buf);
1507 break;
1508 }
1509 }
1510
1511 return ret;
1512 }
1513
1522 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1523 {
1524 ChangeInfoResult ret = CIR_SUCCESS;
1525
1526 for (int i = 0; i < numinfo; i++) {
1527 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1528 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1529
1530 EngineInfo *ei = &e->info;
1531 ShipVehicleInfo *svi = &e->u.ship;
1532
1533 switch (prop) {
1534 case 0x08: { // Sprite ID
1535 uint8 spriteid = buf->ReadByte();
1536 uint8 orig_spriteid = spriteid;
1537
1538 /* ships have different custom id in the GRF file */
1539 if (spriteid == 0xFF) spriteid = 0xFD;
1540
1541 if (spriteid < 0xFD) spriteid >>= 1;
1542
1543 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1544 svi->image_index = spriteid;
1545 } else {
1546 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1547 svi->image_index = 0;
1548 }
1549 break;
1550 }
1551
1552 case 0x09: // Refittable
1553 svi->old_refittable = (buf->ReadByte() != 0);
1554 break;
1555
1556 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1557 svi->cost_factor = buf->ReadByte();
1558 break;
1559
1560 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1561 svi->max_speed = buf->ReadByte();
1562 break;
1563
1564 case 0x0C: { // Cargo type
1565 _gted[e->index].defaultcargo_grf = _cur.grffile;
1566 uint8 ctype = buf->ReadByte();
1567
1568 if (ctype == 0xFF) {
1569 /* 0xFF is specified as 'use first refittable' */
1570 ei->cargo_type = CT_INVALID;
1571 } else if (_cur.grffile->grf_version >= 8) {
1572 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1573 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1574 } else if (ctype < NUM_CARGO) {
1575 /* Use untranslated cargo. */
1576 ei->cargo_type = ctype;
1577 } else {
1578 ei->cargo_type = CT_INVALID;
1579 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1580 }
1581 break;
1582 }
1583
1584 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1585 svi->capacity = buf->ReadWord();
1586 break;
1587
1588 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1589 svi->running_cost = buf->ReadByte();
1590 break;
1591
1592 case 0x10: // SFX
1593 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1594 break;
1595
1596 case 0x11: { // Cargoes available for refitting
1597 uint32 mask = buf->ReadDWord();
1598 _gted[e->index].UpdateRefittability(mask != 0);
1599 ei->refit_mask = TranslateRefitMask(mask);
1600 _gted[e->index].defaultcargo_grf = _cur.grffile;
1601 break;
1602 }
1603
1604 case 0x12: // Callback mask
1605 ei->callback_mask = buf->ReadByte();
1606 break;
1607
1608 case 0x13: // Refit cost
1609 ei->refit_cost = buf->ReadByte();
1610 break;
1611
1612 case 0x14: // Ocean speed fraction
1613 svi->ocean_speed_frac = buf->ReadByte();
1614 break;
1615
1616 case 0x15: // Canal speed fraction
1617 svi->canal_speed_frac = buf->ReadByte();
1618 break;
1619
1620 case 0x16: // Retire vehicle early
1621 ei->retire_early = buf->ReadByte();
1622 break;
1623
1624 case 0x17: // Miscellaneous flags
1625 ei->misc_flags = buf->ReadByte();
1626 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1627 break;
1628
1629 case 0x18: // Cargo classes allowed
1630 _gted[e->index].cargo_allowed = buf->ReadWord();
1631 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1632 _gted[e->index].defaultcargo_grf = _cur.grffile;
1633 break;
1634
1635 case 0x19: // Cargo classes disallowed
1636 _gted[e->index].cargo_disallowed = buf->ReadWord();
1637 _gted[e->index].UpdateRefittability(false);
1638 break;
1639
1640 case 0x1A: // Long format introduction date (days since year 0)
1641 ei->base_intro = buf->ReadDWord();
1642 break;
1643
1644 case 0x1B: // Alter purchase list sort order
1645 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1646 break;
1647
1648 case 0x1C: // Visual effect
1649 svi->visual_effect = buf->ReadByte();
1650 /* Avoid accidentally setting visual_effect to the default value
1651 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1652 if (svi->visual_effect == VE_DEFAULT) {
1653 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1654 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1655 }
1656 break;
1657
1658 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1659 ei->cargo_age_period = buf->ReadWord();
1660 break;
1661
1662 case 0x1E: // CTT refit include list
1663 case 0x1F: { // CTT refit exclude list
1664 uint8 count = buf->ReadByte();
1665 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1666 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1667 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1668 ctt = 0;
1669 while (count--) {
1670 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1671 if (ctype == CT_INVALID) continue;
1672 SetBit(ctt, ctype);
1673 }
1674 break;
1675 }
1676
1677 default:
1678 ret = CommonVehicleChangeInfo(ei, prop, buf);
1679 break;
1680 }
1681 }
1682
1683 return ret;
1684 }
1685
1694 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1695 {
1696 ChangeInfoResult ret = CIR_SUCCESS;
1697
1698 for (int i = 0; i < numinfo; i++) {
1699 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1700 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1701
1702 EngineInfo *ei = &e->info;
1703 AircraftVehicleInfo *avi = &e->u.air;
1704
1705 switch (prop) {
1706 case 0x08: { // Sprite ID
1707 uint8 spriteid = buf->ReadByte();
1708 uint8 orig_spriteid = spriteid;
1709
1710 /* aircraft have different custom id in the GRF file */
1711 if (spriteid == 0xFF) spriteid = 0xFD;
1712
1713 if (spriteid < 0xFD) spriteid >>= 1;
1714
1715 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1716 avi->image_index = spriteid;
1717 } else {
1718 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1719 avi->image_index = 0;
1720 }
1721 break;
1722 }
1723
1724 case 0x09: // Helicopter
1725 if (buf->ReadByte() == 0) {
1726 avi->subtype = AIR_HELI;
1727 } else {
1728 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1729 }
1730 break;
1731
1732 case 0x0A: // Large
1733 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1734 break;
1735
1736 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1737 avi->cost_factor = buf->ReadByte();
1738 break;
1739
1740 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1741 avi->max_speed = (buf->ReadByte() * 128) / 10;
1742 break;
1743
1744 case 0x0D: // Acceleration
1745 avi->acceleration = buf->ReadByte();
1746 break;
1747
1748 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1749 avi->running_cost = buf->ReadByte();
1750 break;
1751
1752 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1753 avi->passenger_capacity = buf->ReadWord();
1754 break;
1755
1756 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1757 avi->mail_capacity = buf->ReadByte();
1758 break;
1759
1760 case 0x12: // SFX
1761 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1762 break;
1763
1764 case 0x13: { // Cargoes available for refitting
1765 uint32 mask = buf->ReadDWord();
1766 _gted[e->index].UpdateRefittability(mask != 0);
1767 ei->refit_mask = TranslateRefitMask(mask);
1768 _gted[e->index].defaultcargo_grf = _cur.grffile;
1769 break;
1770 }
1771
1772 case 0x14: // Callback mask
1773 ei->callback_mask = buf->ReadByte();
1774 break;
1775
1776 case 0x15: // Refit cost
1777 ei->refit_cost = buf->ReadByte();
1778 break;
1779
1780 case 0x16: // Retire vehicle early
1781 ei->retire_early = buf->ReadByte();
1782 break;
1783
1784 case 0x17: // Miscellaneous flags
1785 ei->misc_flags = buf->ReadByte();
1786 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1787 break;
1788
1789 case 0x18: // Cargo classes allowed
1790 _gted[e->index].cargo_allowed = buf->ReadWord();
1791 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1792 _gted[e->index].defaultcargo_grf = _cur.grffile;
1793 break;
1794
1795 case 0x19: // Cargo classes disallowed
1796 _gted[e->index].cargo_disallowed = buf->ReadWord();
1797 _gted[e->index].UpdateRefittability(false);
1798 break;
1799
1800 case 0x1A: // Long format introduction date (days since year 0)
1801 ei->base_intro = buf->ReadDWord();
1802 break;
1803
1804 case 0x1B: // Alter purchase list sort order
1805 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1806 break;
1807
1808 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1809 ei->cargo_age_period = buf->ReadWord();
1810 break;
1811
1812 case 0x1D: // CTT refit include list
1813 case 0x1E: { // CTT refit exclude list
1814 uint8 count = buf->ReadByte();
1815 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1816 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1817 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1818 ctt = 0;
1819 while (count--) {
1820 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1821 if (ctype == CT_INVALID) continue;
1822 SetBit(ctt, ctype);
1823 }
1824 break;
1825 }
1826
1827 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1828 avi->max_range = buf->ReadWord();
1829 break;
1830
1831 default:
1832 ret = CommonVehicleChangeInfo(ei, prop, buf);
1833 break;
1834 }
1835 }
1836
1837 return ret;
1838 }
1839
1848 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1849 {
1850 ChangeInfoResult ret = CIR_SUCCESS;
1851
1852 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1853 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1854 return CIR_INVALID_ID;
1855 }
1856
1857 /* Allocate station specs if necessary */
1858 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1859
1860 for (int i = 0; i < numinfo; i++) {
1861 StationSpec *statspec = _cur.grffile->stations[stid + i];
1862
1863 /* Check that the station we are modifying is defined. */
1864 if (statspec == NULL && prop != 0x08) {
1865 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1866 return CIR_INVALID_ID;
1867 }
1868
1869 switch (prop) {
1870 case 0x08: { // Class ID
1871 StationSpec **spec = &_cur.grffile->stations[stid + i];
1872
1873 /* Property 0x08 is special; it is where the station is allocated */
1874 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1875
1876 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1877 uint32 classid = buf->ReadDWord();
1878 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1879 break;
1880 }
1881
1882 case 0x09: // Define sprite layout
1883 statspec->tiles = buf->ReadExtendedByte();
1884 delete[] statspec->renderdata; // delete earlier loaded stuff
1885 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1886
1887 for (uint t = 0; t < statspec->tiles; t++) {
1888 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1889 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1890
1891 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1892 buf->Skip(4);
1893 extern const DrawTileSprites _station_display_datas_rail[8];
1894 dts->Clone(&_station_display_datas_rail[t % 8]);
1895 continue;
1896 }
1897
1898 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1899 /* On error, bail out immediately. Temporary GRF data was already freed */
1900 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1901
1902 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1903 tmp_layout.Clear();
1904 for (;;) {
1905 /* no relative bounding box support */
1906 DrawTileSeqStruct *dtss = tmp_layout.Append();
1907 MemSetT(dtss, 0);
1908
1909 dtss->delta_x = buf->ReadByte();
1910 if (dtss->IsTerminator()) break;
1911 dtss->delta_y = buf->ReadByte();
1912 dtss->delta_z = buf->ReadByte();
1913 dtss->size_x = buf->ReadByte();
1914 dtss->size_y = buf->ReadByte();
1915 dtss->size_z = buf->ReadByte();
1916
1917 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1918 /* On error, bail out immediately. Temporary GRF data was already freed */
1919 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1920 }
1921 dts->Clone(tmp_layout.Begin());
1922 }
1923 break;
1924
1925 case 0x0A: { // Copy sprite layout
1926 byte srcid = buf->ReadByte();
1927 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1928
1929 if (srcstatspec == NULL) {
1930 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1931 continue;
1932 }
1933
1934 delete[] statspec->renderdata; // delete earlier loaded stuff
1935
1936 statspec->tiles = srcstatspec->tiles;
1937 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1938 for (uint t = 0; t < statspec->tiles; t++) {
1939 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1940 }
1941 break;
1942 }
1943
1944 case 0x0B: // Callback mask
1945 statspec->callback_mask = buf->ReadByte();
1946 break;
1947
1948 case 0x0C: // Disallowed number of platforms
1949 statspec->disallowed_platforms = buf->ReadByte();
1950 break;
1951
1952 case 0x0D: // Disallowed platform lengths
1953 statspec->disallowed_lengths = buf->ReadByte();
1954 break;
1955
1956 case 0x0E: // Define custom layout
1957 statspec->copied_layouts = false;
1958
1959 while (buf->HasData()) {
1960 byte length = buf->ReadByte();
1961 byte number = buf->ReadByte();
1962 StationLayout layout;
1963 uint l, p;
1964
1965 if (length == 0 || number == 0) break;
1966
1967 if (length > statspec->lengths) {
1968 statspec->platforms = ReallocT(statspec->platforms, length);
1969 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1970
1971 statspec->layouts = ReallocT(statspec->layouts, length);
1972 memset(statspec->layouts + statspec->lengths, 0,
1973 (length - statspec->lengths) * sizeof(*statspec->layouts));
1974
1975 statspec->lengths = length;
1976 }
1977 l = length - 1; // index is zero-based
1978
1979 if (number > statspec->platforms[l]) {
1980 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1981 /* We expect NULL being 0 here, but C99 guarantees that. */
1982 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1983 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1984
1985 statspec->platforms[l] = number;
1986 }
1987
1988 p = 0;
1989 layout = MallocT<byte>(length * number);
1990 try {
1991 for (l = 0; l < length; l++) {
1992 for (p = 0; p < number; p++) {
1993 layout[l * number + p] = buf->ReadByte();
1994 }
1995 }
1996 } catch (...) {
1997 free(layout);
1998 throw;
1999 }
2000
2001 l--;
2002 p--;
2003 free(statspec->layouts[l][p]);
2004 statspec->layouts[l][p] = layout;
2005 }
2006 break;
2007
2008 case 0x0F: { // Copy custom layout
2009 byte srcid = buf->ReadByte();
2010 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2011
2012 if (srcstatspec == NULL) {
2013 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2014 continue;
2015 }
2016
2017 statspec->lengths = srcstatspec->lengths;
2018 statspec->platforms = srcstatspec->platforms;
2019 statspec->layouts = srcstatspec->layouts;
2020 statspec->copied_layouts = true;
2021 break;
2022 }
2023
2024 case 0x10: // Little/lots cargo threshold
2025 statspec->cargo_threshold = buf->ReadWord();
2026 break;
2027
2028 case 0x11: // Pylon placement
2029 statspec->pylons = buf->ReadByte();
2030 break;
2031
2032 case 0x12: // Cargo types for random triggers
2033 statspec->cargo_triggers = buf->ReadDWord();
2034 if (_cur.grffile->grf_version >= 7) {
2035 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2036 }
2037 break;
2038
2039 case 0x13: // General flags
2040 statspec->flags = buf->ReadByte();
2041 break;
2042
2043 case 0x14: // Overhead wire placement
2044 statspec->wires = buf->ReadByte();
2045 break;
2046
2047 case 0x15: // Blocked tiles
2048 statspec->blocked = buf->ReadByte();
2049 break;
2050
2051 case 0x16: // Animation info
2052 statspec->animation.frames = buf->ReadByte();
2053 statspec->animation.status = buf->ReadByte();
2054 break;
2055
2056 case 0x17: // Animation speed
2057 statspec->animation.speed = buf->ReadByte();
2058 break;
2059
2060 case 0x18: // Animation triggers
2061 statspec->animation.triggers = buf->ReadWord();
2062 break;
2063
2064 case 0x1A: // Advanced sprite layout
2065 statspec->tiles = buf->ReadExtendedByte();
2066 delete[] statspec->renderdata; // delete earlier loaded stuff
2067 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2068
2069 for (uint t = 0; t < statspec->tiles; t++) {
2070 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2071 uint num_building_sprites = buf->ReadByte();
2072 /* On error, bail out immediately. Temporary GRF data was already freed */
2073 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2074 }
2075 break;
2076
2077 default:
2078 ret = CIR_UNKNOWN;
2079 break;
2080 }
2081 }
2082
2083 return ret;
2084 }
2085
2094 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2095 {
2096 ChangeInfoResult ret = CIR_SUCCESS;
2097
2098 if (id + numinfo > CF_END) {
2099 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2100 return CIR_INVALID_ID;
2101 }
2102
2103 for (int i = 0; i < numinfo; i++) {
2104 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2105
2106 switch (prop) {
2107 case 0x08:
2108 cp->callback_mask = buf->ReadByte();
2109 break;
2110
2111 case 0x09:
2112 cp->flags = buf->ReadByte();
2113 break;
2114
2115 default:
2116 ret = CIR_UNKNOWN;
2117 break;
2118 }
2119 }
2120
2121 return ret;
2122 }
2123
2132 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2133 {
2134 ChangeInfoResult ret = CIR_SUCCESS;
2135
2136 if (brid + numinfo > MAX_BRIDGES) {
2137 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2138 return CIR_INVALID_ID;
2139 }
2140
2141 for (int i = 0; i < numinfo; i++) {
2142 BridgeSpec *bridge = &_bridge[brid + i];
2143
2144 switch (prop) {
2145 case 0x08: { // Year of availability
2146 /* We treat '0' as always available */
2147 byte year = buf->ReadByte();
2148 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2149 break;
2150 }
2151
2152 case 0x09: // Minimum length
2153 bridge->min_length = buf->ReadByte();
2154 break;
2155
2156 case 0x0A: // Maximum length
2157 bridge->max_length = buf->ReadByte();
2158 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2159 break;
2160
2161 case 0x0B: // Cost factor
2162 bridge->price = buf->ReadByte();
2163 break;
2164
2165 case 0x0C: // Maximum speed
2166 bridge->speed = buf->ReadWord();
2167 break;
2168
2169 case 0x0D: { // Bridge sprite tables
2170 byte tableid = buf->ReadByte();
2171 byte numtables = buf->ReadByte();
2172
2173 if (bridge->sprite_table == NULL) {
2174 /* Allocate memory for sprite table pointers and zero out */
2175 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2176 }
2177
2178 for (; numtables-- != 0; tableid++) {
2179 if (tableid >= 7) { // skip invalid data
2180 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2181 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2182 continue;
2183 }
2184
2185 if (bridge->sprite_table[tableid] == NULL) {
2186 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2187 }
2188
2189 for (byte sprite = 0; sprite < 32; sprite++) {
2190 SpriteID image = buf->ReadWord();
2191 PaletteID pal = buf->ReadWord();
2192
2193 bridge->sprite_table[tableid][sprite].sprite = image;
2194 bridge->sprite_table[tableid][sprite].pal = pal;
2195
2196 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2197 }
2198 }
2199 break;
2200 }
2201
2202 case 0x0E: // Flags; bit 0 - disable far pillars
2203 bridge->flags = buf->ReadByte();
2204 break;
2205
2206 case 0x0F: // Long format year of availability (year since year 0)
2207 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2208 break;
2209
2210 case 0x10: { // purchase string
2211 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2212 if (newone != STR_UNDEFINED) bridge->material = newone;
2213 break;
2214 }
2215
2216 case 0x11: // description of bridge with rails or roads
2217 case 0x12: {
2218 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2219 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2220 break;
2221 }
2222
2223 case 0x13: // 16 bits cost multiplier
2224 bridge->price = buf->ReadWord();
2225 break;
2226
2227 default:
2228 ret = CIR_UNKNOWN;
2229 break;
2230 }
2231 }
2232
2233 return ret;
2234 }
2235
2242 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2243 {
2244 ChangeInfoResult ret = CIR_SUCCESS;
2245
2246 switch (prop) {
2247 case 0x09:
2248 case 0x0B:
2249 case 0x0C:
2250 case 0x0D:
2251 case 0x0E:
2252 case 0x0F:
2253 case 0x11:
2254 case 0x14:
2255 case 0x15:
2256 case 0x16:
2257 case 0x18:
2258 case 0x19:
2259 case 0x1A:
2260 case 0x1B:
2261 case 0x1C:
2262 case 0x1D:
2263 case 0x1F:
2264 buf->ReadByte();
2265 break;
2266
2267 case 0x0A:
2268 case 0x10:
2269 case 0x12:
2270 case 0x13:
2271 case 0x21:
2272 case 0x22:
2273 buf->ReadWord();
2274 break;
2275
2276 case 0x1E:
2277 buf->ReadDWord();
2278 break;
2279
2280 case 0x17:
2281 for (uint j = 0; j < 4; j++) buf->ReadByte();
2282 break;
2283
2284 case 0x20: {
2285 byte count = buf->ReadByte();
2286 for (byte j = 0; j < count; j++) buf->ReadByte();
2287 break;
2288 }
2289
2290 default:
2291 ret = CIR_UNKNOWN;
2292 break;
2293 }
2294 return ret;
2295 }
2296
2305 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2306 {
2307 ChangeInfoResult ret = CIR_SUCCESS;
2308
2309 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2310 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2311 return CIR_INVALID_ID;
2312 }
2313
2314 /* Allocate house specs if they haven't been allocated already. */
2315 if (_cur.grffile->housespec == NULL) {
2316 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2317 }
2318
2319 for (int i = 0; i < numinfo; i++) {
2320 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2321
2322 if (prop != 0x08 && housespec == NULL) {
2323 /* If the house property 08 is not yet set, ignore this property */
2324 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2325 if (cir > ret) ret = cir;
2326 continue;
2327 }
2328
2329 switch (prop) {
2330 case 0x08: { // Substitute building type, and definition of a new house
2331 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2332 byte subs_id = buf->ReadByte();
2333
2334 if (subs_id == 0xFF) {
2335 /* Instead of defining a new house, a substitute house id
2336 * of 0xFF disables the old house with the current id. */
2337 HouseSpec::Get(hid + i)->enabled = false;
2338 continue;
2339 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2340 /* The substitute id must be one of the original houses. */
2341 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2342 continue;
2343 }
2344
2345 /* Allocate space for this house. */
2346 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2347
2348 housespec = *house;
2349
2350 MemCpyT(housespec, HouseSpec::Get(subs_id));
2351
2352 housespec->enabled = true;
2353 housespec->grf_prop.local_id = hid + i;
2354 housespec->grf_prop.subst_id = subs_id;
2355 housespec->grf_prop.grffile = _cur.grffile;
2356 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2357 housespec->random_colour[1] = 0x08; // for all new houses
2358 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2359 housespec->random_colour[3] = 0x06;
2360
2361 /* Make sure that the third cargo type is valid in this
2362 * climate. This can cause problems when copying the properties
2363 * of a house that accepts food, where the new house is valid
2364 * in the temperate climate. */
2365 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2366 housespec->cargo_acceptance[2] = 0;
2367 }
2368
2369 _loaded_newgrf_features.has_newhouses = true;
2370 break;
2371 }
2372
2373 case 0x09: // Building flags
2374 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2375 break;
2376
2377 case 0x0A: { // Availability years
2378 uint16 years = buf->ReadWord();
2379 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2380 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2381 break;
2382 }
2383
2384 case 0x0B: // Population
2385 housespec->population = buf->ReadByte();
2386 break;
2387
2388 case 0x0C: // Mail generation multiplier
2389 housespec->mail_generation = buf->ReadByte();
2390 break;
2391
2392 case 0x0D: // Passenger acceptance
2393 case 0x0E: // Mail acceptance
2394 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2395 break;
2396
2397 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2398 int8 goods = buf->ReadByte();
2399
2400 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2401 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2402 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2403 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2404
2405 /* Make sure the cargo type is valid in this climate. */
2406 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2407
2408 housespec->accepts_cargo[2] = cid;
2409 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2410 break;
2411 }
2412
2413 case 0x10: // Local authority rating decrease on removal
2414 housespec->remove_rating_decrease = buf->ReadWord();
2415 break;
2416
2417 case 0x11: // Removal cost multiplier
2418 housespec->removal_cost = buf->ReadByte();
2419 break;
2420
2421 case 0x12: // Building name ID
2422 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2423 break;
2424
2425 case 0x13: // Building availability mask
2426 housespec->building_availability = (HouseZones)buf->ReadWord();
2427 break;
2428
2429 case 0x14: // House callback mask
2430 housespec->callback_mask |= buf->ReadByte();
2431 break;
2432
2433 case 0x15: { // House override byte
2434 byte override = buf->ReadByte();
2435
2436 /* The house being overridden must be an original house. */
2437 if (override >= NEW_HOUSE_OFFSET) {
2438 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2439 continue;
2440 }
2441
2442 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2443 break;
2444 }
2445
2446 case 0x16: // Periodic refresh multiplier
2447 housespec->processing_time = min(buf->ReadByte(), 63);
2448 break;
2449
2450 case 0x17: // Four random colours to use
2451 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2452 break;
2453
2454 case 0x18: // Relative probability of appearing
2455 housespec->probability = buf->ReadByte();
2456 break;
2457
2458 case 0x19: // Extra flags
2459 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2460 break;
2461
2462 case 0x1A: // Animation frames
2463 housespec->animation.frames = buf->ReadByte();
2464 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2465 SB(housespec->animation.frames, 7, 1, 0);
2466 break;
2467
2468 case 0x1B: // Animation speed
2469 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2470 break;
2471
2472 case 0x1C: // Class of the building type
2473 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2474 break;
2475
2476 case 0x1D: // Callback mask part 2
2477 housespec->callback_mask |= (buf->ReadByte() << 8);
2478 break;
2479
2480 case 0x1E: { // Accepted cargo types
2481 uint32 cargotypes = buf->ReadDWord();
2482
2483 /* Check if the cargo types should not be changed */
2484 if (cargotypes == 0xFFFFFFFF) break;
2485
2486 for (uint j = 0; j < 3; j++) {
2487 /* Get the cargo number from the 'list' */
2488 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2489 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2490
2491 if (cargo == CT_INVALID) {
2492 /* Disable acceptance of invalid cargo type */
2493 housespec->cargo_acceptance[j] = 0;
2494 } else {
2495 housespec->accepts_cargo[j] = cargo;
2496 }
2497 }
2498 break;
2499 }
2500
2501 case 0x1F: // Minimum life span
2502 housespec->minimum_life = buf->ReadByte();
2503 break;
2504
2505 case 0x20: { // Cargo acceptance watch list
2506 byte count = buf->ReadByte();
2507 for (byte j = 0; j < count; j++) {
2508 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2509 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2510 }
2511 break;
2512 }
2513
2514 case 0x21: // long introduction year
2515 housespec->min_year = buf->ReadWord();
2516 break;
2517
2518 case 0x22: // long maximum year
2519 housespec->max_year = buf->ReadWord();
2520 break;
2521
2522 default:
2523 ret = CIR_UNKNOWN;
2524 break;
2525 }
2526 }
2527
2528 return ret;
2529 }
2530
2537 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2538 {
2539 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2540 const GRFFile *grffile = GetFileByGRFID(grfid);
2541 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2542 }
2543
2553 template <typename T>
2554 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2555 {
2556 if (gvid != 0) {
2557 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2558 return CIR_INVALID_ID;
2559 }
2560
2561 translation_table.Clear();
2562 for (int i = 0; i < numinfo; i++) {
2563 uint32 item = buf->ReadDWord();
2564 *translation_table.Append() = BSWAP32(item);
2565 }
2566
2567 return CIR_SUCCESS;
2568 }
2569
2578 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2579 {
2580 /* Properties which are handled as a whole */
2581 switch (prop) {
2582 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2583 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2584
2585 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2586 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2587
2588 default:
2589 break;
2590 }
2591
2592 /* Properties which are handled per item */
2593 ChangeInfoResult ret = CIR_SUCCESS;
2594 for (int i = 0; i < numinfo; i++) {
2595 switch (prop) {
2596 case 0x08: { // Cost base factor
2597 int factor = buf->ReadByte();
2598 uint price = gvid + i;
2599
2600 if (price < PR_END) {
2601 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2602 } else {
2603 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2604 }
2605 break;
2606 }
2607
2608 case 0x0A: { // Currency display names
2609 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2610 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2611
2612 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2613 _currency_specs[curidx].name = newone;
2614 }
2615 break;
2616 }
2617
2618 case 0x0B: { // Currency multipliers
2619 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2620 uint32 rate = buf->ReadDWord();
2621
2622 if (curidx < CURRENCY_END) {
2623 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2624 * which OTTD does not. For this reason, divide grf value by 1000,
2625 * to be compatible */
2626 _currency_specs[curidx].rate = rate / 1000;
2627 } else {
2628 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2629 }
2630 break;
2631 }
2632
2633 case 0x0C: { // Currency options
2634 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2635 uint16 options = buf->ReadWord();
2636
2637 if (curidx < CURRENCY_END) {
2638 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2639 _currency_specs[curidx].separator[1] = '\0';
2640 /* By specifying only one bit, we prevent errors,
2641 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2642 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2643 } else {
2644 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2645 }
2646 break;
2647 }
2648
2649 case 0x0D: { // Currency prefix symbol
2650 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2651 uint32 tempfix = buf->ReadDWord();
2652
2653 if (curidx < CURRENCY_END) {
2654 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2655 _currency_specs[curidx].prefix[4] = 0;
2656 } else {
2657 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2658 }
2659 break;
2660 }
2661
2662 case 0x0E: { // Currency suffix symbol
2663 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2664 uint32 tempfix = buf->ReadDWord();
2665
2666 if (curidx < CURRENCY_END) {
2667 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2668 _currency_specs[curidx].suffix[4] = 0;
2669 } else {
2670 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2671 }
2672 break;
2673 }
2674
2675 case 0x0F: { // Euro introduction dates
2676 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2677 Year year_euro = buf->ReadWord();
2678
2679 if (curidx < CURRENCY_END) {
2680 _currency_specs[curidx].to_euro = year_euro;
2681 } else {
2682 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2683 }
2684 break;
2685 }
2686
2687 case 0x10: // Snow line height table
2688 if (numinfo > 1 || IsSnowLineSet()) {
2689 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2690 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2691 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2692 } else {
2693 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2694
2695 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2696 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2697 table[i][j] = buf->ReadByte();
2698 if (_cur.grffile->grf_version >= 8) {
2699 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2700 } else {
2701 if (table[i][j] >= 128) {
2702 /* no snow */
2703 table[i][j] = 0xFF;
2704 } else {
2705 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2706 }
2707 }
2708 }
2709 }
2710 SetSnowLine(table);
2711 }
2712 break;
2713
2714 case 0x11: // GRF match for engine allocation
2715 /* This is loaded during the reservation stage, so just skip it here. */
2716 /* Each entry is 8 bytes. */
2717 buf->Skip(8);
2718 break;
2719
2720 case 0x13: // Gender translation table
2721 case 0x14: // Case translation table
2722 case 0x15: { // Plural form translation
2723 uint curidx = gvid + i; // The current index, i.e. language.
2724 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2725 if (lang == NULL) {
2726 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2727 /* Skip over the data. */
2728 if (prop == 0x15) {
2729 buf->ReadByte();
2730 } else {
2731 while (buf->ReadByte() != 0) {
2732 buf->ReadString();
2733 }
2734 }
2735 break;
2736 }
2737
2738 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2739
2740 if (prop == 0x15) {
2741 uint plural_form = buf->ReadByte();
2742 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2743 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2744 } else {
2745 _cur.grffile->language_map[curidx].plural_form = plural_form;
2746 }
2747 break;
2748 }
2749
2750 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2751 while (newgrf_id != 0) {
2752 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2753
2754 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2755 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2756 * is just a subset of UTF8, or they need the bigger UTF8 characters
2757 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2758 WChar c;
2759 size_t len = Utf8Decode(&c, name);
2760 if (c == NFO_UTF8_IDENTIFIER) name += len;
2761
2762 LanguageMap::Mapping map;
2763 map.newgrf_id = newgrf_id;
2764 if (prop == 0x13) {
2765 map.openttd_id = lang->GetGenderIndex(name);
2766 if (map.openttd_id >= MAX_NUM_GENDERS) {
2767 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2768 } else {
2769 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2770 }
2771 } else {
2772 map.openttd_id = lang->GetCaseIndex(name);
2773 if (map.openttd_id >= MAX_NUM_CASES) {
2774 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2775 } else {
2776 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2777 }
2778 }
2779 newgrf_id = buf->ReadByte();
2780 }
2781 break;
2782 }
2783
2784 default:
2785 ret = CIR_UNKNOWN;
2786 break;
2787 }
2788 }
2789
2790 return ret;
2791 }
2792
2793 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2794 {
2795 /* Properties which are handled as a whole */
2796 switch (prop) {
2797 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2798 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2799
2800 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2801 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2802
2803 default:
2804 break;
2805 }
2806
2807 /* Properties which are handled per item */
2808 ChangeInfoResult ret = CIR_SUCCESS;
2809 for (int i = 0; i < numinfo; i++) {
2810 switch (prop) {
2811 case 0x08: // Cost base factor
2812 case 0x15: // Plural form translation
2813 buf->ReadByte();
2814 break;
2815
2816 case 0x0A: // Currency display names
2817 case 0x0C: // Currency options
2818 case 0x0F: // Euro introduction dates
2819 buf->ReadWord();
2820 break;
2821
2822 case 0x0B: // Currency multipliers
2823 case 0x0D: // Currency prefix symbol
2824 case 0x0E: // Currency suffix symbol
2825 buf->ReadDWord();
2826 break;
2827
2828 case 0x10: // Snow line height table
2829 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2830 break;
2831
2832 case 0x11: { // GRF match for engine allocation
2833 uint32 s = buf->ReadDWord();
2834 uint32 t = buf->ReadDWord();
2835 SetNewGRFOverride(s, t);
2836 break;
2837 }
2838
2839 case 0x13: // Gender translation table
2840 case 0x14: // Case translation table
2841 while (buf->ReadByte() != 0) {
2842 buf->ReadString();
2843 }
2844 break;
2845
2846 default:
2847 ret = CIR_UNKNOWN;
2848 break;
2849 }
2850 }
2851
2852 return ret;
2853 }
2854
2855
2864 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2865 {
2866 ChangeInfoResult ret = CIR_SUCCESS;
2867
2868 if (cid + numinfo > NUM_CARGO) {
2869 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2870 return CIR_INVALID_ID;
2871 }
2872
2873 for (int i = 0; i < numinfo; i++) {
2874 CargoSpec *cs = CargoSpec::Get(cid + i);
2875
2876 switch (prop) {
2877 case 0x08: // Bit number of cargo
2878 cs->bitnum = buf->ReadByte();
2879 if (cs->IsValid()) {
2880 cs->grffile = _cur.grffile;
2881 SetBit(_cargo_mask, cid + i);
2882 } else {
2883 ClrBit(_cargo_mask, cid + i);
2884 }
2885 break;
2886
2887 case 0x09: // String ID for cargo type name
2888 AddStringForMapping(buf->ReadWord(), &cs->name);
2889 break;
2890
2891 case 0x0A: // String for 1 unit of cargo
2892 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2893 break;
2894
2895 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2896 case 0x1B: // String for cargo units
2897 /* String for units of cargo. This is different in OpenTTD
2898 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2899 * Property 1B is used to set OpenTTD's behaviour. */
2900 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2901 break;
2902
2903 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2904 case 0x1C: // String for any amount of cargo
2905 /* Strings for an amount of cargo. This is different in OpenTTD
2906 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2907 * Property 1C is used to set OpenTTD's behaviour. */
2908 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2909 break;
2910
2911 case 0x0D: // String for two letter cargo abbreviation
2912 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2913 break;
2914
2915 case 0x0E: // Sprite ID for cargo icon
2916 cs->sprite = buf->ReadWord();
2917 break;
2918
2919 case 0x0F: // Weight of one unit of cargo
2920 cs->weight = buf->ReadByte();
2921 break;
2922
2923 case 0x10: // Used for payment calculation
2924 cs->transit_days[0] = buf->ReadByte();
2925 break;
2926
2927 case 0x11: // Used for payment calculation
2928 cs->transit_days[1] = buf->ReadByte();
2929 break;
2930
2931 case 0x12: // Base cargo price
2932 cs->initial_payment = buf->ReadDWord();
2933 break;
2934
2935 case 0x13: // Colour for station rating bars
2936 cs->rating_colour = buf->ReadByte();
2937 break;
2938
2939 case 0x14: // Colour for cargo graph
2940 cs->legend_colour = buf->ReadByte();
2941 break;
2942
2943 case 0x15: // Freight status
2944 cs->is_freight = (buf->ReadByte() != 0);
2945 break;
2946
2947 case 0x16: // Cargo classes
2948 cs->classes = buf->ReadWord();
2949 break;
2950
2951 case 0x17: // Cargo label
2952 cs->label = buf->ReadDWord();
2953 cs->label = BSWAP32(cs->label);
2954 break;
2955
2956 case 0x18: { // Town growth substitute type
2957 uint8 substitute_type = buf->ReadByte();
2958
2959 switch (substitute_type) {
2960 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2961 case 0x02: cs->town_effect = TE_MAIL; break;
2962 case 0x05: cs->town_effect = TE_GOODS; break;
2963 case 0x09: cs->town_effect = TE_WATER; break;
2964 case 0x0B: cs->town_effect = TE_FOOD; break;
2965 default:
2966 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2967 /* FALL THROUGH */
2968 case 0xFF: cs->town_effect = TE_NONE; break;
2969 }
2970 break;
2971 }
2972
2973 case 0x19: // Town growth coefficient
2974 cs->multipliertowngrowth = buf->ReadWord();
2975 break;
2976
2977 case 0x1A: // Bitmask of callbacks to use
2978 cs->callback_mask = buf->ReadByte();
2979 break;
2980
2981 case 0x1D: // Vehicle capacity muliplier
2982 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2983 break;
2984
2985 default:
2986 ret = CIR_UNKNOWN;
2987 break;
2988 }
2989 }
2990
2991 return ret;
2992 }
2993
2994
3003 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3004 {
3005 ChangeInfoResult ret = CIR_SUCCESS;
3006
3007 if (_cur.grffile->sound_offset == 0) {
3008 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3009 return CIR_INVALID_ID;
3010 }
3011
3012 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3013 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3014 return CIR_INVALID_ID;
3015 }
3016
3017 for (int i = 0; i < numinfo; i++) {
3018 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3019
3020 switch (prop) {
3021 case 0x08: // Relative volume
3022 sound->volume = buf->ReadByte();
3023 break;
3024
3025 case 0x09: // Priority
3026 sound->priority = buf->ReadByte();
3027 break;
3028
3029 case 0x0A: { // Override old sound
3030 SoundID orig_sound = buf->ReadByte();
3031
3032 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3033 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3034 } else {
3035 SoundEntry *old_sound = GetSound(orig_sound);
3036
3037 /* Literally copy the data of the new sound over the original */
3038 *old_sound = *sound;
3039 }
3040 break;
3041 }
3042
3043 default:
3044 ret = CIR_UNKNOWN;
3045 break;
3046 }
3047 }
3048
3049 return ret;
3050 }
3051
3058 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3059 {
3060 ChangeInfoResult ret = CIR_SUCCESS;
3061
3062 switch (prop) {
3063 case 0x09:
3064 case 0x0D:
3065 case 0x0E:
3066 case 0x10:
3067 case 0x11:
3068 case 0x12:
3069 buf->ReadByte();
3070 break;
3071
3072 case 0x0A:
3073 case 0x0B:
3074 case 0x0C:
3075 case 0x0F:
3076 buf->ReadWord();
3077 break;
3078
3079 default:
3080 ret = CIR_UNKNOWN;
3081 break;
3082 }
3083 return ret;
3084 }
3085
3094 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3095 {
3096 ChangeInfoResult ret = CIR_SUCCESS;
3097
3098 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3099 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3100 return CIR_INVALID_ID;
3101 }
3102
3103 /* Allocate industry tile specs if they haven't been allocated already. */
3104 if (_cur.grffile->indtspec == NULL) {
3105 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3106 }
3107
3108 for (int i = 0; i < numinfo; i++) {
3109 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3110
3111 if (prop != 0x08 && tsp == NULL) {
3112 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3113 if (cir > ret) ret = cir;
3114 continue;
3115 }
3116
3117 switch (prop) {
3118 case 0x08: { // Substitute industry tile type
3119 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3120 byte subs_id = buf->ReadByte();
3121
3122 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3123 /* The substitute id must be one of the original industry tile. */
3124 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3125 continue;
3126 }
3127
3128 /* Allocate space for this industry. */
3129 if (*tilespec == NULL) {
3130 *tilespec = CallocT<IndustryTileSpec>(1);
3131 tsp = *tilespec;
3132
3133 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3134 tsp->enabled = true;
3135
3136 /* A copied tile should not have the animation infos copied too.
3137 * The anim_state should be left untouched, though
3138 * It is up to the author to animate them himself */
3139 tsp->anim_production = INDUSTRYTILE_NOANIM;
3140 tsp->anim_next = INDUSTRYTILE_NOANIM;
3141
3142 tsp->grf_prop.local_id = indtid + i;
3143 tsp->grf_prop.subst_id = subs_id;
3144 tsp->grf_prop.grffile = _cur.grffile;
3145 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3146 }
3147 break;
3148 }
3149
3150 case 0x09: { // Industry tile override
3151 byte ovrid = buf->ReadByte();
3152
3153 /* The industry being overridden must be an original industry. */
3154 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3155 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3156 continue;
3157 }
3158
3159 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3160 break;
3161 }
3162
3163 case 0x0A: // Tile acceptance
3164 case 0x0B:
3165 case 0x0C: {
3166 uint16 acctp = buf->ReadWord();
3167 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3168 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3169 break;
3170 }
3171
3172 case 0x0D: // Land shape flags
3173 tsp->slopes_refused = (Slope)buf->ReadByte();
3174 break;
3175
3176 case 0x0E: // Callback mask
3177 tsp->callback_mask = buf->ReadByte();
3178 break;
3179
3180 case 0x0F: // Animation information
3181 tsp->animation.frames = buf->ReadByte();
3182 tsp->animation.status = buf->ReadByte();
3183 break;
3184
3185 case 0x10: // Animation speed
3186 tsp->animation.speed = buf->ReadByte();
3187 break;
3188
3189 case 0x11: // Triggers for callback 25
3190 tsp->animation.triggers = buf->ReadByte();
3191 break;
3192
3193 case 0x12: // Special flags
3194 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3195 break;
3196
3197 default:
3198 ret = CIR_UNKNOWN;
3199 break;
3200 }
3201 }
3202
3203 return ret;
3204 }
3205
3212 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3213 {
3214 ChangeInfoResult ret = CIR_SUCCESS;
3215
3216 switch (prop) {
3217 case 0x09:
3218 case 0x0B:
3219 case 0x0F:
3220 case 0x12:
3221 case 0x13:
3222 case 0x14:
3223 case 0x17:
3224 case 0x18:
3225 case 0x19:
3226 case 0x21:
3227 case 0x22:
3228 buf->ReadByte();
3229 break;
3230
3231 case 0x0C:
3232 case 0x0D:
3233 case 0x0E:
3234 case 0x10:
3235 case 0x1B:
3236 case 0x1F:
3237 case 0x24:
3238 buf->ReadWord();
3239 break;
3240
3241 case 0x11:
3242 case 0x1A:
3243 case 0x1C:
3244 case 0x1D:
3245 case 0x1E:
3246 case 0x20:
3247 case 0x23:
3248 buf->ReadDWord();
3249 break;
3250
3251 case 0x0A: {
3252 byte num_table = buf->ReadByte();
3253 for (byte j = 0; j < num_table; j++) {
3254 for (uint k = 0;; k++) {
3255 byte x = buf->ReadByte();
3256 if (x == 0xFE && k == 0) {
3257 buf->ReadByte();
3258 buf->ReadByte();
3259 break;
3260 }
3261
3262 byte y = buf->ReadByte();
3263 if (x == 0 && y == 0x80) break;
3264
3265 byte gfx = buf->ReadByte();
3266 if (gfx == 0xFE) buf->ReadWord();
3267 }
3268 }
3269 break;
3270 }
3271
3272 case 0x16:
3273 for (byte j = 0; j < 3; j++) buf->ReadByte();
3274 break;
3275
3276 case 0x15: {
3277 byte number_of_sounds = buf->ReadByte();
3278 for (uint8 j = 0; j < number_of_sounds; j++) {
3279 buf->ReadByte();
3280 }
3281 break;
3282 }
3283
3284 default:
3285 ret = CIR_UNKNOWN;
3286 break;
3287 }
3288 return ret;
3289 }
3290
3297 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3298 {
3299 for (int i = 0; i < size - 1; i++) {
3300 for (int j = i + 1; j < size; j++) {
3301 if (layout[i].ti.x == layout[j].ti.x &&
3302 layout[i].ti.y == layout[j].ti.y) {
3303 return false;
3304 }
3305 }
3306 }
3307 return true;
3308 }
3309
3311 static void CleanIndustryTileTable(IndustrySpec *ind)
3312 {
3313 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3314 for (int j = 0; j < ind->num_table; j++) {
3315 /* remove the individual layouts */
3316 free(ind->table[j]);
3317 }
3318 /* remove the layouts pointers */
3319 free(ind->table);
3320 ind->table = NULL;
3321 }
3322 }
3323
3332 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3333 {
3334 ChangeInfoResult ret = CIR_SUCCESS;
3335
3336 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3337 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3338 return CIR_INVALID_ID;
3339 }
3340
3341 /* Allocate industry specs if they haven't been allocated already. */
3342 if (_cur.grffile->industryspec == NULL) {
3343 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3344 }
3345
3346 for (int i = 0; i < numinfo; i++) {
3347 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3348
3349 if (prop != 0x08 && indsp == NULL) {
3350 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3351 if (cir > ret) ret = cir;
3352 continue;
3353 }
3354
3355 switch (prop) {
3356 case 0x08: { // Substitute industry type
3357 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3358 byte subs_id = buf->ReadByte();
3359
3360 if (subs_id == 0xFF) {
3361 /* Instead of defining a new industry, a substitute industry id
3362 * of 0xFF disables the old industry with the current id. */
3363 _industry_specs[indid + i].enabled = false;
3364 continue;
3365 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3366 /* The substitute id must be one of the original industry. */
3367 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3368 continue;
3369 }
3370
3371 /* Allocate space for this industry.
3372 * Only need to do it once. If ever it is called again, it should not
3373 * do anything */
3374 if (*indspec == NULL) {
3375 *indspec = CallocT<IndustrySpec>(1);
3376 indsp = *indspec;
3377
3378 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3379 indsp->enabled = true;
3380 indsp->grf_prop.local_id = indid + i;
3381 indsp->grf_prop.subst_id = subs_id;
3382 indsp->grf_prop.grffile = _cur.grffile;
3383 /* If the grf industry needs to check its surounding upon creation, it should
3384 * rely on callbacks, not on the original placement functions */
3385 indsp->check_proc = CHECK_NOTHING;
3386 }
3387 break;
3388 }
3389
3390 case 0x09: { // Industry type override
3391 byte ovrid = buf->ReadByte();
3392
3393 /* The industry being overridden must be an original industry. */
3394 if (ovrid >= NEW_INDUSTRYOFFSET) {
3395 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3396 continue;
3397 }
3398 indsp->grf_prop.override = ovrid;
3399 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3400 break;
3401 }
3402
3403 case 0x0A: { // Set industry layout(s)
3404 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3405 /* We read the total size in bytes, but we can't rely on the
3406 * newgrf to provide a sane value. First assume the value is
3407 * sane but later on we make sure we enlarge the array if the
3408 * newgrf contains more data. Each tile uses either 3 or 5
3409 * bytes, so to play it safe we assume 3. */
3410 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3411 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3412 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3413 uint size;
3414 const IndustryTileTable *copy_from;
3415
3416 try {
3417 for (byte j = 0; j < new_num_layouts; j++) {
3418 for (uint k = 0;; k++) {
3419 if (k >= def_num_tiles) {
3420 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3421 /* Size reported by newgrf was not big enough so enlarge the array. */
3422 def_num_tiles *= 2;
3423 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3424 }
3425
3426 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3427
3428 if (itt[k].ti.x == 0xFE && k == 0) {
3429 /* This means we have to borrow the layout from an old industry */
3430 IndustryType type = buf->ReadByte(); // industry holding required layout
3431 byte laynbr = buf->ReadByte(); // layout number to borrow
3432
3433 copy_from = _origin_industry_specs[type].table[laynbr];
3434 for (size = 1;; size++) {
3435 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3436 }
3437 break;
3438 }
3439
3440 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3441
3442 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3443 /* Not the same terminator. The one we are using is rather
3444 x = -80, y = x . So, adjust it. */
3445 itt[k].ti.x = -0x80;
3446 itt[k].ti.y = 0;
3447 itt[k].gfx = 0;
3448
3449 size = k + 1;
3450 copy_from = itt;
3451 break;
3452 }
3453
3454 itt[k].gfx = buf->ReadByte();
3455
3456 if (itt[k].gfx == 0xFE) {
3457 /* Use a new tile from this GRF */
3458 int local_tile_id = buf->ReadWord();
3459
3460 /* Read the ID from the _industile_mngr. */
3461 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3462
3463 if (tempid == INVALID_INDUSTRYTILE) {
3464 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3465 } else {
3466 /* Declared as been valid, can be used */
3467 itt[k].gfx = tempid;
3468 size = k + 1;
3469 copy_from = itt;
3470 }
3471 } else if (itt[k].gfx == 0xFF) {
3472 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3473 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3474
3475 /* When there were only 256x256 maps, TileIndex was a uint16 and
3476 * itt[k].ti was just a TileIndexDiff that was added to it.
3477 * As such negative "x" values were shifted into the "y" position.
3478 * x = -1, y = 1 -> x = 255, y = 0
3479 * Since GRF version 8 the position is interpreted as pair of independent int8.
3480 * For GRF version < 8 we need to emulate the old shifting behaviour.
3481 */
3482 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3483 }
3484 }
3485
3486 if (!ValidateIndustryLayout(copy_from, size)) {
3487 /* The industry layout was not valid, so skip this one. */
3488 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3489 new_num_layouts--;
3490 j--;
3491 } else {
3492 tile_table[j] = CallocT<IndustryTileTable>(size);
3493 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3494 }
3495 }
3496 } catch (...) {
3497 for (int i = 0; i < new_num_layouts; i++) {
3498 free(tile_table[i]);
3499 }
3500 free(tile_table);
3501 free(itt);
3502 throw;
3503 }
3504
3505 /* Clean the tile table if it was already set by a previous prop A. */
3506 CleanIndustryTileTable(indsp);
3507 /* Install final layout construction in the industry spec */
3508 indsp->num_table = new_num_layouts;
3509 indsp->table = tile_table;
3510 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3511 free(itt);
3512 break;
3513 }
3514
3515 case 0x0B: // Industry production flags
3516 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3517 break;
3518
3519 case 0x0C: // Industry closure message
3520 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3521 break;
3522
3523 case 0x0D: // Production increase message
3524 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3525 break;
3526
3527 case 0x0E: // Production decrease message
3528 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3529 break;
3530
3531 case 0x0F: // Fund cost multiplier
3532 indsp->cost_multiplier = buf->ReadByte();
3533 break;
3534
3535 case 0x10: // Production cargo types
3536 for (byte j = 0; j < 2; j++) {
3537 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3538 }
3539 break;
3540
3541 case 0x11: // Acceptance cargo types
3542 for (byte j = 0; j < 3; j++) {
3543 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3544 }
3545 buf->ReadByte(); // Unnused, eat it up
3546 break;
3547
3548 case 0x12: // Production multipliers
3549 case 0x13:
3550 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3551 break;
3552
3553 case 0x14: // Minimal amount of cargo distributed
3554 indsp->minimal_cargo = buf->ReadByte();
3555 break;
3556
3557 case 0x15: { // Random sound effects
3558 indsp->number_of_sounds = buf->ReadByte();
3559 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3560
3561 try {
3562 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3563 sounds[j] = buf->ReadByte();
3564 }
3565 } catch (...) {
3566 free(sounds);
3567 throw;
3568 }
3569
3570 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3571 free(indsp->random_sounds);
3572 }
3573 indsp->random_sounds = sounds;
3574 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3575 break;
3576 }
3577
3578 case 0x16: // Conflicting industry types
3579 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3580 break;
3581
3582 case 0x17: // Probability in random game
3583 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3584 break;
3585
3586 case 0x18: // Probability during gameplay
3587 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3588 break;
3589
3590 case 0x19: // Map colour
3591 indsp->map_colour = buf->ReadByte();
3592 break;
3593
3594 case 0x1A: // Special industry flags to define special behavior
3595 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3596 break;
3597
3598 case 0x1B: // New industry text ID
3599 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3600 break;
3601
3602 case 0x1C: // Input cargo multipliers for the three input cargo types
3603 case 0x1D:
3604 case 0x1E: {
3605 uint32 multiples = buf->ReadDWord();
3606 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3607 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3608 break;
3609 }
3610
3611 case 0x1F: // Industry name
3612 AddStringForMapping(buf->ReadWord(), &indsp->name);
3613 break;
3614
3615 case 0x20: // Prospecting success chance
3616 indsp->prospecting_chance = buf->ReadDWord();
3617 break;
3618
3619 case 0x21: // Callback mask
3620 case 0x22: { // Callback additional mask
3621 byte aflag = buf->ReadByte();
3622 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3623 break;
3624 }
3625
3626 case 0x23: // removal cost multiplier
3627 indsp->removal_cost_multiplier = buf->ReadDWord();
3628 break;
3629
3630 case 0x24: { // name for nearby station
3631 uint16 str = buf->ReadWord();
3632 if (str == 0) {
3633 indsp->station_name = STR_NULL;
3634 } else {
3635 AddStringForMapping(str, &indsp->station_name);
3636 }
3637 break;
3638 }
3639
3640 default:
3641 ret = CIR_UNKNOWN;
3642 break;
3643 }
3644 }
3645
3646 return ret;
3647 }
3648
3654 static void DuplicateTileTable(AirportSpec *as)
3655 {
3656 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3657 for (int i = 0; i < as->num_table; i++) {
3658 uint num_tiles = 1;
3659 const AirportTileTable *it = as->table[0];
3660 do {
3661 num_tiles++;
3662 } while ((++it)->ti.x != -0x80);
3663 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3664 MemCpyT(table_list[i], as->table[i], num_tiles);
3665 }
3666 as->table = table_list;
3667 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3668 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3669 as->depot_table = depot_table;
3670 }
3671
3680 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3681 {
3682 ChangeInfoResult ret = CIR_SUCCESS;
3683
3684 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3685 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3686 return CIR_INVALID_ID;
3687 }
3688
3689 /* Allocate industry specs if they haven't been allocated already. */
3690 if (_cur.grffile->airportspec == NULL) {
3691 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3692 }
3693
3694 for (int i = 0; i < numinfo; i++) {
3695 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3696
3697 if (as == NULL && prop != 0x08 && prop != 0x09) {
3698 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3699 return CIR_INVALID_ID;
3700 }
3701
3702 switch (prop) {
3703 case 0x08: { // Modify original airport
3704 byte subs_id = buf->ReadByte();
3705
3706 if (subs_id == 0xFF) {
3707 /* Instead of defining a new airport, an airport id
3708 * of 0xFF disables the old airport with the current id. */
3709 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3710 continue;
3711 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3712 /* The substitute id must be one of the original airports. */
3713 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3714 continue;
3715 }
3716
3717 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3718 /* Allocate space for this airport.
3719 * Only need to do it once. If ever it is called again, it should not
3720 * do anything */
3721 if (*spec == NULL) {
3722 *spec = MallocT<AirportSpec>(1);
3723 as = *spec;
3724
3725 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3726 as->enabled = true;
3727 as->grf_prop.local_id = airport + i;
3728 as->grf_prop.subst_id = subs_id;
3729 as->grf_prop.grffile = _cur.grffile;
3730 /* override the default airport */
3731 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3732 /* Create a copy of the original tiletable so it can be freed later. */
3733 DuplicateTileTable(as);
3734 }
3735 break;
3736 }
3737
3738 case 0x0A: { // Set airport layout
3739 as->num_table = buf->ReadByte(); // Number of layaouts
3740 as->rotation = MallocT<Direction>(as->num_table);
3741 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3742 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3743 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3744 int size;
3745 const AirportTileTable *copy_from;
3746 try {
3747 for (byte j = 0; j < as->num_table; j++) {
3748 as->rotation[j] = (Direction)buf->ReadByte();
3749 for (int k = 0;; k++) {
3750 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3751 att[k].ti.y = buf->ReadByte();
3752
3753 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3754 /* Not the same terminator. The one we are using is rather
3755 * x = -80, y = 0 . So, adjust it. */
3756 att[k].ti.x = -0x80;
3757 att[k].ti.y = 0;
3758 att[k].gfx = 0;
3759
3760 size = k + 1;
3761 copy_from = att;
3762 break;
3763 }
3764
3765 att[k].gfx = buf->ReadByte();
3766
3767 if (att[k].gfx == 0xFE) {
3768 /* Use a new tile from this GRF */
3769 int local_tile_id = buf->ReadWord();
3770
3771 /* Read the ID from the _airporttile_mngr. */
3772 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3773
3774 if (tempid == INVALID_AIRPORTTILE) {
3775 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3776 } else {
3777 /* Declared as been valid, can be used */
3778 att[k].gfx = tempid;
3779 size = k + 1;
3780 copy_from = att;
3781 }
3782 } else if (att[k].gfx == 0xFF) {
3783 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3784 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3785 }
3786
3787 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3788 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3789 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3790 } else {
3791 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3792 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3793 }
3794 }
3795 tile_table[j] = CallocT<AirportTileTable>(size);
3796 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3797 }
3798 /* Install final layout construction in the airport spec */
3799 as->table = tile_table;
3800 free(att);
3801 } catch (...) {
3802 for (int i = 0; i < as->num_table; i++) {
3803 free(tile_table[i]);
3804 }
3805 free(tile_table);
3806 free(att);
3807 throw;
3808 }
3809 break;
3810 }
3811
3812 case 0x0C:
3813 as->min_year = buf->ReadWord();
3814 as->max_year = buf->ReadWord();
3815 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3816 break;
3817
3818 case 0x0D:
3819 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3820 break;
3821
3822 case 0x0E:
3823 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3824 break;
3825
3826 case 0x0F:
3827 as->noise_level = buf->ReadByte();
3828 break;
3829
3830 case 0x10:
3831 AddStringForMapping(buf->ReadWord(), &as->name);
3832 break;
3833
3834 case 0x11: // Maintenance cost factor
3835 as->maintenance_cost = buf->ReadWord();
3836 break;
3837
3838 default:
3839 ret = CIR_UNKNOWN;
3840 break;
3841 }
3842 }
3843
3844 return ret;
3845 }
3846
3853 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3854 {
3855 ChangeInfoResult ret = CIR_SUCCESS;
3856
3857 switch (prop) {
3858 case 0x0B:
3859 case 0x0C:
3860 case 0x0D:
3861 case 0x12:
3862 case 0x14:
3863 case 0x16:
3864 case 0x17:
3865 buf->ReadByte();
3866 break;
3867
3868 case 0x09:
3869 case 0x0A:
3870 case 0x10:
3871 case 0x11:
3872 case 0x13:
3873 case 0x15:
3874 buf->ReadWord();
3875 break;
3876
3877 case 0x08:
3878 case 0x0E:
3879 case 0x0F:
3880 buf->ReadDWord();
3881 break;
3882
3883 default:
3884 ret = CIR_UNKNOWN;
3885 break;
3886 }
3887
3888 return ret;
3889 }
3890
3899 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3900 {
3901 ChangeInfoResult ret = CIR_SUCCESS;
3902
3903 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3904 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3905 return CIR_INVALID_ID;
3906 }
3907
3908 /* Allocate object specs if they haven't been allocated already. */
3909 if (_cur.grffile->objectspec == NULL) {
3910 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3911 }
3912
3913 for (int i = 0; i < numinfo; i++) {
3914 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3915
3916 if (prop != 0x08 && spec == NULL) {
3917 /* If the object property 08 is not yet set, ignore this property */
3918 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3919 if (cir > ret) ret = cir;
3920 continue;
3921 }
3922
3923 switch (prop) {
3924 case 0x08: { // Class ID
3925 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3926
3927 /* Allocate space for this object. */
3928 if (*ospec == NULL) {
3929 *ospec = CallocT<ObjectSpec>(1);
3930 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3931 }
3932
3933 /* Swap classid because we read it in BE. */
3934 uint32 classid = buf->ReadDWord();
3935 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3936 (*ospec)->enabled = true;
3937 break;
3938 }
3939
3940 case 0x09: { // Class name
3941 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3942 AddStringForMapping(buf->ReadWord(), &objclass->name);
3943 break;
3944 }
3945
3946 case 0x0A: // Object name
3947 AddStringForMapping(buf->ReadWord(), &spec->name);
3948 break;
3949
3950 case 0x0B: // Climate mask
3951 spec->climate = buf->ReadByte();
3952 break;
3953
3954 case 0x0C: // Size
3955 spec->size = buf->ReadByte();
3956 break;
3957
3958 case 0x0D: // Build cost multipler
3959 spec->build_cost_multiplier = buf->ReadByte();
3960 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3961 break;
3962
3963 case 0x0E: // Introduction date
3964 spec->introduction_date = buf->ReadDWord();
3965 break;
3966
3967 case 0x0F: // End of life
3968 spec->end_of_life_date = buf->ReadDWord();
3969 break;
3970
3971 case 0x10: // Flags
3972 spec->flags = (ObjectFlags)buf->ReadWord();
3973 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3974 break;
3975
3976 case 0x11: // Animation info
3977 spec->animation.frames = buf->ReadByte();
3978 spec->animation.status = buf->ReadByte();
3979 break;
3980
3981 case 0x12: // Animation speed
3982 spec->animation.speed = buf->ReadByte();
3983 break;
3984
3985 case 0x13: // Animation triggers
3986 spec->animation.triggers = buf->ReadWord();
3987 break;
3988
3989 case 0x14: // Removal cost multiplier
3990 spec->clear_cost_multiplier = buf->ReadByte();
3991 break;
3992
3993 case 0x15: // Callback mask
3994 spec->callback_mask = buf->ReadWord();
3995 break;
3996
3997 case 0x16: // Building height
3998 spec->height = buf->ReadByte();
3999 break;
4000
4001 case 0x17: // Views
4002 spec->views = buf->ReadByte();
4003 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4004 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4005 spec->views = 1;
4006 }
4007 break;
4008
4009 case 0x18: // Amount placed on 256^2 map on map creation
4010 spec->generate_amount = buf->ReadByte();
4011 break;
4012
4013 default:
4014 ret = CIR_UNKNOWN;
4015 break;
4016 }
4017 }
4018
4019 return ret;
4020 }
4021
4030 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4031 {
4032 ChangeInfoResult ret = CIR_SUCCESS;
4033
4034 extern RailtypeInfo _railtypes[RAILTYPE_END];
4035
4036 if (id + numinfo > RAILTYPE_END) {
4037 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4038 return CIR_INVALID_ID;
4039 }
4040
4041 for (int i = 0; i < numinfo; i++) {
4042 RailType rt = _cur.grffile->railtype_map[id + i];
4043 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4044
4045 RailtypeInfo *rti = &_railtypes[rt];
4046
4047 switch (prop) {
4048 case 0x08: // Label of rail type
4049 /* Skipped here as this is loaded during reservation stage. */
4050 buf->ReadDWord();
4051 break;
4052
4053 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4054 uint16 str = buf->ReadWord();
4055 AddStringForMapping(str, &rti->strings.toolbar_caption);
4056 if (_cur.grffile->grf_version < 8) {
4057 AddStringForMapping(str, &rti->strings.name);
4058 }
4059 break;
4060 }
4061
4062 case 0x0A: // Menu text of railtype
4063 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4064 break;
4065
4066 case 0x0B: // Build window caption
4067 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4068 break;
4069
4070 case 0x0C: // Autoreplace text
4071 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4072 break;
4073
4074 case 0x0D: // New locomotive text
4075 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4076 break;
4077
4078 case 0x0E: // Compatible railtype list
4079 case 0x0F: // Powered railtype list
4080 case 0x18: // Railtype list required for date introduction
4081 case 0x19: // Introduced railtype list
4082 {
4083 /* Rail type compatibility bits are added to the existing bits
4084 * to allow multiple GRFs to modify compatibility with the
4085 * default rail types. */
4086 int n = buf->ReadByte();
4087 for (int j = 0; j != n; j++) {
4088 RailTypeLabel label = buf->ReadDWord();
4089 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4090 if (rt != INVALID_RAILTYPE) {
4091 switch (prop) {
4092 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4093 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4094 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4095 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4096 }
4097 }
4098 }
4099 break;
4100 }
4101
4102 case 0x10: // Rail Type flags
4103 rti->flags = (RailTypeFlags)buf->ReadByte();
4104 break;
4105
4106 case 0x11: // Curve speed advantage
4107 rti->curve_speed = buf->ReadByte();
4108 break;
4109
4110 case 0x12: // Station graphic
4111 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4112 break;
4113
4114 case 0x13: // Construction cost factor
4115 rti->cost_multiplier = buf->ReadWord();
4116 break;
4117
4118 case 0x14: // Speed limit
4119 rti->max_speed = buf->ReadWord();
4120 break;
4121
4122 case 0x15: // Acceleration model
4123 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4124 break;
4125
4126 case 0x16: // Map colour
4127 rti->map_colour = buf->ReadByte();
4128 break;
4129
4130 case 0x17: // Introduction date
4131 rti->introduction_date = buf->ReadDWord();
4132 break;
4133
4134 case 0x1A: // Sort order
4135 rti->sorting_order = buf->ReadByte();
4136 break;
4137
4138 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4139 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4140 break;
4141
4142 case 0x1C: // Maintenance cost factor
4143 rti->maintenance_multiplier = buf->ReadWord();
4144 break;
4145
4146 case 0x1D: // Alternate rail type label list
4147 /* Skipped here as this is loaded during reservation stage. */
4148 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4149 break;
4150
4151 default:
4152 ret = CIR_UNKNOWN;
4153 break;
4154 }
4155 }
4156
4157 return ret;
4158 }
4159
4160 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4161 {
4162 ChangeInfoResult ret = CIR_SUCCESS;
4163
4164 extern RailtypeInfo _railtypes[RAILTYPE_END];
4165
4166 if (id + numinfo > RAILTYPE_END) {
4167 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4168 return CIR_INVALID_ID;
4169 }
4170
4171 for (int i = 0; i < numinfo; i++) {
4172 switch (prop) {
4173 case 0x08: // Label of rail type
4174 {
4175 RailTypeLabel rtl = buf->ReadDWord();
4176 rtl = BSWAP32(rtl);
4177
4178 RailType rt = GetRailTypeByLabel(rtl, false);
4179 if (rt == INVALID_RAILTYPE) {
4180 /* Set up new rail type */
4181 rt = AllocateRailType(rtl);
4182 }
4183
4184 _cur.grffile->railtype_map[id + i] = rt;
4185 break;
4186 }
4187
4188 case 0x09: // Toolbar caption of railtype
4189 case 0x0A: // Menu text
4190 case 0x0B: // Build window caption
4191 case 0x0C: // Autoreplace text
4192 case 0x0D: // New loco
4193 case 0x13: // Construction cost
4194 case 0x14: // Speed limit
4195 case 0x1B: // Name of railtype
4196 case 0x1C: // Maintenance cost factor
4197 buf->ReadWord();
4198 break;
4199
4200 case 0x1D: // Alternate rail type label list
4201 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4202 int n = buf->ReadByte();
4203 for (int j = 0; j != n; j++) {
4204 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4205 }
4206 break;
4207 }
4208 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4209 /* FALL THROUGH */
4210
4211 case 0x0E: // Compatible railtype list
4212 case 0x0F: // Powered railtype list
4213 case 0x18: // Railtype list required for date introduction
4214 case 0x19: // Introduced railtype list
4215 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4216 break;
4217
4218 case 0x10: // Rail Type flags
4219 case 0x11: // Curve speed advantage
4220 case 0x12: // Station graphic
4221 case 0x15: // Acceleration model
4222 case 0x16: // Map colour
4223 case 0x1A: // Sort order
4224 buf->ReadByte();
4225 break;
4226
4227 case 0x17: // Introduction date
4228 buf->ReadDWord();
4229 break;
4230
4231 default:
4232 ret = CIR_UNKNOWN;
4233 break;
4234 }
4235 }
4236
4237 return ret;
4238 }
4239
4240 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4241 {
4242 ChangeInfoResult ret = CIR_SUCCESS;
4243
4244 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4245 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4246 return CIR_INVALID_ID;
4247 }
4248
4249 /* Allocate airport tile specs if they haven't been allocated already. */
4250 if (_cur.grffile->airtspec == NULL) {
4251 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4252 }
4253
4254 for (int i = 0; i < numinfo; i++) {
4255 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4256
4257 if (prop != 0x08 && tsp == NULL) {
4258 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4259 return CIR_INVALID_ID;
4260 }
4261
4262 switch (prop) {
4263 case 0x08: { // Substitute airport tile type
4264 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4265 byte subs_id = buf->ReadByte();
4266
4267 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4268 /* The substitute id must be one of the original airport tiles. */
4269 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4270 continue;
4271 }
4272
4273 /* Allocate space for this airport tile. */
4274 if (*tilespec == NULL) {
4275 *tilespec = CallocT<AirportTileSpec>(1);
4276 tsp = *tilespec;
4277
4278 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4279 tsp->enabled = true;
4280
4281 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4282
4283 tsp->grf_prop.local_id = airtid + i;
4284 tsp->grf_prop.subst_id = subs_id;
4285 tsp->grf_prop.grffile = _cur.grffile;
4286 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4287 }
4288 break;
4289 }
4290
4291 case 0x09: { // Airport tile override
4292 byte override = buf->ReadByte();
4293
4294 /* The airport tile being overridden must be an original airport tile. */
4295 if (override >= NEW_AIRPORTTILE_OFFSET) {
4296 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4297 continue;
4298 }
4299
4300 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4301 break;
4302 }
4303
4304 case 0x0E: // Callback mask
4305 tsp->callback_mask = buf->ReadByte();
4306 break;
4307
4308 case 0x0F: // Animation information
4309 tsp->animation.frames = buf->ReadByte();
4310 tsp->animation.status = buf->ReadByte();
4311 break;
4312
4313 case 0x10: // Animation speed
4314 tsp->animation.speed = buf->ReadByte();
4315 break;
4316
4317 case 0x11: // Animation triggers
4318 tsp->animation.triggers = buf->ReadByte();
4319 break;
4320
4321 default:
4322 ret = CIR_UNKNOWN;
4323 break;
4324 }
4325 }
4326
4327 return ret;
4328 }
4329
4330 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4331 {
4332 switch (cir) {
4333 default: NOT_REACHED();
4334
4335 case CIR_DISABLED:
4336 /* Error has already been printed; just stop parsing */
4337 return true;
4338
4339 case CIR_SUCCESS:
4340 return false;
4341
4342 case CIR_UNHANDLED:
4343 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4344 return false;
4345
4346 case CIR_UNKNOWN:
4347 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4348 /* FALL THROUGH */
4349
4350 case CIR_INVALID_ID: {
4351 /* No debug message for an invalid ID, as it has already been output */
4352 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4353 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4354 return true;
4355 }
4356 }
4357 }
4358
4359 /* Action 0x00 */
4360 static void FeatureChangeInfo(ByteReader *buf)
4361 {
4362 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4363 *
4364 * B feature
4365 * B num-props how many properties to change per vehicle/station
4366 * B num-info how many vehicles/stations to change
4367 * E id ID of first vehicle/station to change, if num-info is
4368 * greater than one, this one and the following
4369 * vehicles/stations will be changed
4370 * B property what property to change, depends on the feature
4371 * V new-info new bytes of info (variable size; depends on properties) */
4372
4373 static const VCI_Handler handler[] = {
4374 /* GSF_TRAINS */ RailVehicleChangeInfo,
4375 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4376 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4377 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4378 /* GSF_STATIONS */ StationChangeInfo,
4379 /* GSF_CANALS */ CanalChangeInfo,
4380 /* GSF_BRIDGES */ BridgeChangeInfo,
4381 /* GSF_HOUSES */ TownHouseChangeInfo,
4382 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4383 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4384 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4385 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4386 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4387 /* GSF_AIRPORTS */ AirportChangeInfo,
4388 /* GSF_SIGNALS */ NULL,
4389 /* GSF_OBJECTS */ ObjectChangeInfo,
4390 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4391 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4392 };
4393
4394 uint8 feature = buf->ReadByte();
4395 uint8 numprops = buf->ReadByte();
4396 uint numinfo = buf->ReadByte();
4397 uint engine = buf->ReadExtendedByte();
4398
4399 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4400 feature, numprops, engine, numinfo);
4401
4402 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4403 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4404 return;
4405 }
4406
4407 /* Mark the feature as used by the grf */
4408 SetBit(_cur.grffile->grf_features, feature);
4409
4410 while (numprops-- && buf->HasData()) {
4411 uint8 prop = buf->ReadByte();
4412
4413 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4414 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4415 }
4416 }
4417
4418 /* Action 0x00 (GLS_SAFETYSCAN) */
4419 static void SafeChangeInfo(ByteReader *buf)
4420 {
4421 uint8 feature = buf->ReadByte();
4422 uint8 numprops = buf->ReadByte();
4423 uint numinfo = buf->ReadByte();
4424 buf->ReadExtendedByte(); // id
4425
4426 if (feature == GSF_BRIDGES && numprops == 1) {
4427 uint8 prop = buf->ReadByte();
4428 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4429 * is considered safe. */
4430 if (prop == 0x0D) return;
4431 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4432 uint8 prop = buf->ReadByte();
4433 /* Engine ID Mappings are safe, if the source is static */
4434 if (prop == 0x11) {
4435 bool is_safe = true;
4436 for (uint i = 0; i < numinfo; i++) {
4437 uint32 s = buf->ReadDWord();
4438 buf->ReadDWord(); // dest
4439 const GRFConfig *grfconfig = GetGRFConfig(s);
4440 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4441 is_safe = false;
4442 break;
4443 }
4444 }
4445 if (is_safe) return;
4446 }
4447 }
4448
4449 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4450
4451 /* Skip remainder of GRF */
4452 _cur.skip_sprites = -1;
4453 }
4454
4455 /* Action 0x00 (GLS_RESERVE) */
4456 static void ReserveChangeInfo(ByteReader *buf)
4457 {
4458 uint8 feature = buf->ReadByte();
4459
4460 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4461
4462 uint8 numprops = buf->ReadByte();
4463 uint8 numinfo = buf->ReadByte();
4464 uint8 index = buf->ReadExtendedByte();
4465
4466 while (numprops-- && buf->HasData()) {
4467 uint8 prop = buf->ReadByte();
4468 ChangeInfoResult cir = CIR_SUCCESS;
4469
4470 switch (feature) {
4471 default: NOT_REACHED();
4472 case GSF_CARGOES:
4473 cir = CargoChangeInfo(index, numinfo, prop, buf);
4474 break;
4475
4476 case GSF_GLOBALVAR:
4477 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4478 break;
4479
4480 case GSF_RAILTYPES:
4481 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4482 break;
4483 }
4484
4485 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4486 }
4487 }
4488
4489 /* Action 0x01 */
4490 static void NewSpriteSet(ByteReader *buf)
4491 {
4492 /* Basic format: <01> <feature> <num-sets> <num-ent>
4493 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4494 *
4495 * B feature feature to define sprites for
4496 * 0, 1, 2, 3: veh-type, 4: train stations
4497 * E first-set first sprite set to define
4498 * B num-sets number of sprite sets (extended byte in extended format)
4499 * E num-ent how many entries per sprite set
4500 * For vehicles, this is the number of different
4501 * vehicle directions in each sprite set
4502 * Set num-dirs=8, unless your sprites are symmetric.
4503 * In that case, use num-dirs=4.
4504 */
4505
4506 uint8 feature = buf->ReadByte();
4507 uint16 num_sets = buf->ReadByte();
4508 uint16 first_set = 0;
4509
4510 if (num_sets == 0 && buf->HasData(3)) {
4511 /* Extended Action1 format.
4512 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4513 first_set = buf->ReadExtendedByte();
4514 num_sets = buf->ReadExtendedByte();
4515 }
4516 uint16 num_ents = buf->ReadExtendedByte();
4517
4518 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4519
4520 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4521 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4522 );
4523
4524 for (int i = 0; i < num_sets * num_ents; i++) {
4525 _cur.nfo_line++;
4526 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4527 }
4528 }
4529
4530 /* Action 0x01 (SKIP) */
4531 static void SkipAct1(ByteReader *buf)
4532 {
4533 buf->ReadByte();
4534 uint16 num_sets = buf->ReadByte();
4535
4536 if (num_sets == 0 && buf->HasData(3)) {
4537 /* Extended Action1 format.
4538 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4539 buf->ReadExtendedByte(); // first_set
4540 num_sets = buf->ReadExtendedByte();
4541 }
4542 uint16 num_ents = buf->ReadExtendedByte();
4543
4544 _cur.skip_sprites = num_sets * num_ents;
4545
4546 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4547 }
4548
4549 /* Helper function to either create a callback or link to a previously
4550 * defined spritegroup. */
4551 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4552 {
4553 if (HasBit(groupid, 15)) {
4554 assert(CallbackResultSpriteGroup::CanAllocateItem());
4555 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4556 }
4557
4558 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4559 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4560 return NULL;
4561 }
4562
4563 return _cur.spritegroups[groupid];
4564 }
4565
4574 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4575 {
4576 if (HasBit(spriteid, 15)) {
4577 assert(CallbackResultSpriteGroup::CanAllocateItem());
4578 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4579 }
4580
4581 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4582 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4583 return NULL;
4584 }
4585
4586 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4587 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4588
4589 /* Ensure that the sprites are loeded */
4590 assert(spriteset_start + num_sprites <= _cur.spriteid);
4591
4592 assert(ResultSpriteGroup::CanAllocateItem());
4593 return new ResultSpriteGroup(spriteset_start, num_sprites);
4594 }
4595
4596 /* Action 0x02 */
4597 static void NewSpriteGroup(ByteReader *buf)
4598 {
4599 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4600 *
4601 * B feature see action 1
4602 * B set-id ID of this particular definition
4603 * B type/num-entries
4604 * if 80 or greater, this is a randomized or variational
4605 * list definition, see below
4606 * otherwise it specifies a number of entries, the exact
4607 * meaning depends on the feature
4608 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4609 SpriteGroup *act_group = NULL;
4610
4611 uint8 feature = buf->ReadByte();
4612 uint8 setid = buf->ReadByte();
4613 uint8 type = buf->ReadByte();
4614
4615 /* Sprite Groups are created here but they are allocated from a pool, so
4616 * we do not need to delete anything if there is an exception from the
4617 * ByteReader. */
4618
4619 switch (type) {
4620 /* Deterministic Sprite Group */
4621 case 0x81: // Self scope, byte
4622 case 0x82: // Parent scope, byte
4623 case 0x85: // Self scope, word
4624 case 0x86: // Parent scope, word
4625 case 0x89: // Self scope, dword
4626 case 0x8A: // Parent scope, dword
4627 {
4628 byte varadjust;
4629 byte varsize;
4630
4631 assert(DeterministicSpriteGroup::CanAllocateItem());
4632 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4633 act_group = group;
4634 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4635
4636 switch (GB(type, 2, 2)) {
4637 default: NOT_REACHED();
4638 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4639 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4640 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4641 }
4642
4643 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4644 adjusts.Clear();
4645
4646 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4647 * from the outset, so we shall have to keep reallocing. */
4648 do {
4649 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4650
4651 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4652 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4653 adjust->variable = buf->ReadByte();
4654 if (adjust->variable == 0x7E) {
4655 /* Link subroutine group */
4656 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4657 } else {
4658 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4659 }
4660
4661 varadjust = buf->ReadByte();
4662 adjust->shift_num = GB(varadjust, 0, 5);
4663 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4664 adjust->and_mask = buf->ReadVarSize(varsize);
4665
4666 if (adjust->type != DSGA_TYPE_NONE) {
4667 adjust->add_val = buf->ReadVarSize(varsize);
4668 adjust->divmod_val = buf->ReadVarSize(varsize);
4669 } else {
4670 adjust->add_val = 0;
4671 adjust->divmod_val = 0;
4672 }
4673
4674 /* Continue reading var adjusts while bit 5 is set. */
4675 } while (HasBit(varadjust, 5));
4676
4677 group->num_adjusts = adjusts.Length();
4678 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4679 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4680
4681 group->num_ranges = buf->ReadByte();
4682 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4683
4684 for (uint i = 0; i < group->num_ranges; i++) {
4685 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4686 group->ranges[i].low = buf->ReadVarSize(varsize);
4687 group->ranges[i].high = buf->ReadVarSize(varsize);
4688 }
4689
4690 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4691 break;
4692 }
4693
4694 /* Randomized Sprite Group */
4695 case 0x80: // Self scope
4696 case 0x83: // Parent scope
4697 case 0x84: // Relative scope
4698 {
4699 assert(RandomizedSpriteGroup::CanAllocateItem());
4700 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4701 act_group = group;
4702 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4703
4704 if (HasBit(type, 2)) {
4705 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4706 group->count = buf->ReadByte();
4707 }
4708
4709 uint8 triggers = buf->ReadByte();
4710 group->triggers = GB(triggers, 0, 7);
4711 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4712 group->lowest_randbit = buf->ReadByte();
4713 group->num_groups = buf->ReadByte();
4714 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4715
4716 for (uint i = 0; i < group->num_groups; i++) {
4717 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4718 }
4719
4720 break;
4721 }
4722
4723 /* Neither a variable or randomized sprite group... must be a real group */
4724 default:
4725 {
4726 switch (feature) {
4727 case GSF_TRAINS:
4728 case GSF_ROADVEHICLES:
4729 case GSF_SHIPS:
4730 case GSF_AIRCRAFT:
4731 case GSF_STATIONS:
4732 case GSF_CANALS:
4733 case GSF_CARGOES:
4734 case GSF_AIRPORTS:
4735 case GSF_RAILTYPES:
4736 {
4737 byte num_loaded = type;
4738 byte num_loading = buf->ReadByte();
4739
4740 if (!_cur.HasValidSpriteSets(feature)) {
4741 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4742 return;
4743 }
4744
4745 assert(RealSpriteGroup::CanAllocateItem());
4746 RealSpriteGroup *group = new RealSpriteGroup();
4747 act_group = group;
4748
4749 group->num_loaded = num_loaded;
4750 group->num_loading = num_loading;
4751 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4752 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4753
4754 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4755 setid, num_loaded, num_loading);
4756
4757 for (uint i = 0; i < num_loaded; i++) {
4758 uint16 spriteid = buf->ReadWord();
4759 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4760 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4761 }
4762
4763 for (uint i = 0; i < num_loading; i++) {
4764 uint16 spriteid = buf->ReadWord();
4765 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4766 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4767 }
4768
4769 break;
4770 }
4771
4772 case GSF_HOUSES:
4773 case GSF_AIRPORTTILES:
4774 case GSF_OBJECTS:
4775 case GSF_INDUSTRYTILES: {
4776 byte num_building_sprites = max((uint8)1, type);
4777
4778 assert(TileLayoutSpriteGroup::CanAllocateItem());
4779 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4780 act_group = group;
4781
4782 /* On error, bail out immediately. Temporary GRF data was already freed */
4783 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4784 break;
4785 }
4786
4787 case GSF_INDUSTRIES: {
4788 if (type > 1) {
4789 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4790 break;
4791 }
4792
4793 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4794 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4795 act_group = group;
4796 group->version = type;
4797 if (type == 0) {
4798 for (uint i = 0; i < 3; i++) {
4799 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4800 }
4801 for (uint i = 0; i < 2; i++) {
4802 group->add_output[i] = buf->ReadWord(); // unsigned
4803 }
4804 group->again = buf->ReadByte();
4805 } else {
4806 for (uint i = 0; i < 3; i++) {
4807 group->subtract_input[i] = buf->ReadByte();
4808 }
4809 for (uint i = 0; i < 2; i++) {
4810 group->add_output[i] = buf->ReadByte();
4811 }
4812 group->again = buf->ReadByte();
4813 }
4814 break;
4815 }
4816
4817 /* Loading of Tile Layout and Production Callback groups would happen here */
4818 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4819 }
4820 }
4821 }
4822
4823 _cur.spritegroups[setid] = act_group;
4824 }
4825
4826 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4827 {
4828 if (feature == GSF_OBJECTS) {
4829 switch (ctype) {
4830 case 0: return 0;
4831 case 0xFF: return CT_PURCHASE_OBJECT;
4832 default:
4833 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4834 return CT_INVALID;
4835 }
4836 }
4837 /* Special cargo types for purchase list and stations */
4838 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4839 if (ctype == 0xFF) return CT_PURCHASE;
4840
4841 if (_cur.grffile->cargo_list.Length() == 0) {
4842 /* No cargo table, so use bitnum values */
4843 if (ctype >= 32) {
4844 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4845 return CT_INVALID;
4846 }
4847
4848 const CargoSpec *cs;
4849 FOR_ALL_CARGOSPECS(cs) {
4850 if (cs->bitnum == ctype) {
4851 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4852 return cs->Index();
4853 }
4854 }
4855
4856 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4857 return CT_INVALID;
4858 }
4859
4860 /* Check if the cargo type is out of bounds of the cargo translation table */
4861 if (ctype >= _cur.grffile->cargo_list.Length()) {
4862 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4863 return CT_INVALID;
4864 }
4865
4866 /* Look up the cargo label from the translation table */
4867 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4868 if (cl == 0) {
4869 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4870 return CT_INVALID;
4871 }
4872
4873 ctype = GetCargoIDByLabel(cl);
4874 if (ctype == CT_INVALID) {
4875 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));
4876 return CT_INVALID;
4877 }
4878
4879 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);
4880 return ctype;
4881 }
4882
4883
4884 static bool IsValidGroupID(uint16 groupid, const char *function)
4885 {
4886 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4887 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4888 return false;
4889 }
4890
4891 return true;
4892 }
4893
4894 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4895 {
4896 static EngineID *last_engines;
4897 static uint last_engines_count;
4898 bool wagover = false;
4899
4900 /* Test for 'wagon override' flag */
4901 if (HasBit(idcount, 7)) {
4902 wagover = true;
4903 /* Strip off the flag */
4904 idcount = GB(idcount, 0, 7);
4905
4906 if (last_engines_count == 0) {
4907 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4908 return;
4909 }
4910
4911 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4912 last_engines_count, idcount);
4913 } else {
4914 if (last_engines_count != idcount) {
4915 last_engines = ReallocT(last_engines, idcount);
4916 last_engines_count = idcount;
4917 }
4918 }
4919
4920 EngineID *engines = AllocaM(EngineID, idcount);
4921 for (uint i = 0; i < idcount; i++) {
4922 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4923 if (e == NULL) {
4924 /* No engine could be allocated?!? Deal with it. Okay,
4925 * this might look bad. Also make sure this NewGRF
4926 * gets disabled, as a half loaded one is bad. */
4927 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4928 return;
4929 }
4930
4931 engines[i] = e->index;
4932 if (!wagover) last_engines[i] = engines[i];
4933 }
4934
4935 uint8 cidcount = buf->ReadByte();
4936 for (uint c = 0; c < cidcount; c++) {
4937 uint8 ctype = buf->ReadByte();
4938 uint16 groupid = buf->ReadWord();
4939 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4940
4941 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4942
4943 ctype = TranslateCargo(feature, ctype);
4944 if (ctype == CT_INVALID) continue;
4945
4946 for (uint i = 0; i < idcount; i++) {
4947 EngineID engine = engines[i];
4948
4949 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4950
4951 if (wagover) {
4952 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4953 } else {
4954 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4955 }
4956 }
4957 }
4958
4959 uint16 groupid = buf->ReadWord();
4960 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
4961
4962 grfmsg(8, "-- Default group id 0x%04X", groupid);
4963
4964 for (uint i = 0; i < idcount; i++) {
4965 EngineID engine = engines[i];
4966
4967 if (wagover) {
4968 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4969 } else {
4970 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4971 SetEngineGRF(engine, _cur.grffile);
4972 }
4973 }
4974 }
4975
4976
4977 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4978 {
4979 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
4980 for (uint i = 0; i < idcount; i++) {
4981 cfs[i] = (CanalFeature)buf->ReadByte();
4982 }
4983
4984 uint8 cidcount = buf->ReadByte();
4985 buf->Skip(cidcount * 3);
4986
4987 uint16 groupid = buf->ReadWord();
4988 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
4989
4990 for (uint i = 0; i < idcount; i++) {
4991 CanalFeature cf = cfs[i];
4992
4993 if (cf >= CF_END) {
4994 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
4995 continue;
4996 }
4997
4998 _water_feature[cf].grffile = _cur.grffile;
4999 _water_feature[cf].group = _cur.spritegroups[groupid];
5000 }
5001 }
5002
5003
5004 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5005 {
5006 uint8 *stations = AllocaM(uint8, idcount);
5007 for (uint i = 0; i < idcount; i++) {
5008 stations[i] = buf->ReadByte();
5009 }
5010
5011 uint8 cidcount = buf->ReadByte();
5012 for (uint c = 0; c < cidcount; c++) {
5013 uint8 ctype = buf->ReadByte();
5014 uint16 groupid = buf->ReadWord();
5015 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5016
5017 ctype = TranslateCargo(GSF_STATIONS, ctype);
5018 if (ctype == CT_INVALID) continue;
5019
5020 for (uint i = 0; i < idcount; i++) {
5021 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5022
5023 if (statspec == NULL) {
5024 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5025 continue;
5026 }
5027
5028 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5029 }
5030 }
5031
5032 uint16 groupid = buf->ReadWord();
5033 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5034
5035 for (uint i = 0; i < idcount; i++) {
5036 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5037
5038 if (statspec == NULL) {
5039 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5040 continue;
5041 }
5042
5043 if (statspec->grf_prop.grffile != NULL) {
5044 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5045 continue;
5046 }
5047
5048 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5049 statspec->grf_prop.grffile = _cur.grffile;
5050 statspec->grf_prop.local_id = stations[i];
5051 StationClass::Assign(statspec);
5052 }
5053 }
5054
5055
5056 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5057 {
5058 uint8 *houses = AllocaM(uint8, idcount);
5059 for (uint i = 0; i < idcount; i++) {
5060 houses[i] = buf->ReadByte();
5061 }
5062
5063 /* Skip the cargo type section, we only care about the default group */
5064 uint8 cidcount = buf->ReadByte();
5065 buf->Skip(cidcount * 3);
5066
5067 uint16 groupid = buf->ReadWord();
5068 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5069
5070 if (_cur.grffile->housespec == NULL) {
5071 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5072 return;
5073 }
5074
5075 for (uint i = 0; i < idcount; i++) {
5076 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5077
5078 if (hs == NULL) {
5079 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5080 continue;
5081 }
5082
5083 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5084 }
5085 }
5086
5087 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5088 {
5089 uint8 *industries = AllocaM(uint8, idcount);
5090 for (uint i = 0; i < idcount; i++) {
5091 industries[i] = buf->ReadByte();
5092 }
5093
5094 /* Skip the cargo type section, we only care about the default group */
5095 uint8 cidcount = buf->ReadByte();
5096 buf->Skip(cidcount * 3);
5097
5098 uint16 groupid = buf->ReadWord();
5099 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5100
5101 if (_cur.grffile->industryspec == NULL) {
5102 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5103 return;
5104 }
5105
5106 for (uint i = 0; i < idcount; i++) {
5107 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5108
5109 if (indsp == NULL) {
5110 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5111 continue;
5112 }
5113
5114 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5115 }
5116 }
5117
5118 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5119 {
5120 uint8 *indtiles = AllocaM(uint8, idcount);
5121 for (uint i = 0; i < idcount; i++) {
5122 indtiles[i] = buf->ReadByte();
5123 }
5124
5125 /* Skip the cargo type section, we only care about the default group */
5126 uint8 cidcount = buf->ReadByte();
5127 buf->Skip(cidcount * 3);
5128
5129 uint16 groupid = buf->ReadWord();
5130 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5131
5132 if (_cur.grffile->indtspec == NULL) {
5133 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5134 return;
5135 }
5136
5137 for (uint i = 0; i < idcount; i++) {
5138 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5139
5140 if (indtsp == NULL) {
5141 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5142 continue;
5143 }
5144
5145 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5146 }
5147 }
5148
5149 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5150 {
5151 CargoID *cargoes = AllocaM(CargoID, idcount);
5152 for (uint i = 0; i < idcount; i++) {
5153 cargoes[i] = buf->ReadByte();
5154 }
5155
5156 /* Skip the cargo type section, we only care about the default group */
5157 uint8 cidcount = buf->ReadByte();
5158 buf->Skip(cidcount * 3);
5159
5160 uint16 groupid = buf->ReadWord();
5161 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5162
5163 for (uint i = 0; i < idcount; i++) {
5164 CargoID cid = cargoes[i];
5165
5166 if (cid >= NUM_CARGO) {
5167 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5168 continue;
5169 }
5170
5171 CargoSpec *cs = CargoSpec::Get(cid);
5172 cs->grffile = _cur.grffile;
5173 cs->group = _cur.spritegroups[groupid];
5174 }
5175 }
5176
5177 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5178 {
5179 if (_cur.grffile->objectspec == NULL) {
5180 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5181 return;
5182 }
5183
5184 uint8 *objects = AllocaM(uint8, idcount);
5185 for (uint i = 0; i < idcount; i++) {
5186 objects[i] = buf->ReadByte();
5187 }
5188
5189 uint8 cidcount = buf->ReadByte();
5190 for (uint c = 0; c < cidcount; c++) {
5191 uint8 ctype = buf->ReadByte();
5192 uint16 groupid = buf->ReadWord();
5193 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5194
5195 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5196 if (ctype == CT_INVALID) continue;
5197
5198 for (uint i = 0; i < idcount; i++) {
5199 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5200
5201 if (spec == NULL) {
5202 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5203 continue;
5204 }
5205
5206 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5207 }
5208 }
5209
5210 uint16 groupid = buf->ReadWord();
5211 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5212
5213 for (uint i = 0; i < idcount; i++) {
5214 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5215
5216 if (spec == NULL) {
5217 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5218 continue;
5219 }
5220
5221 if (spec->grf_prop.grffile != NULL) {
5222 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5223 continue;
5224 }
5225
5226 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5227 spec->grf_prop.grffile = _cur.grffile;
5228 spec->grf_prop.local_id = objects[i];
5229 }
5230 }
5231
5232 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5233 {
5234 uint8 *railtypes = AllocaM(uint8, idcount);
5235 for (uint i = 0; i < idcount; i++) {
5236 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5237 }
5238
5239 uint8 cidcount = buf->ReadByte();
5240 for (uint c = 0; c < cidcount; c++) {
5241 uint8 ctype = buf->ReadByte();
5242 uint16 groupid = buf->ReadWord();
5243 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5244
5245 if (ctype >= RTSG_END) continue;
5246
5247 extern RailtypeInfo _railtypes[RAILTYPE_END];
5248 for (uint i = 0; i < idcount; i++) {
5249 if (railtypes[i] != INVALID_RAILTYPE) {
5250 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5251
5252 rti->grffile[ctype] = _cur.grffile;
5253 rti->group[ctype] = _cur.spritegroups[groupid];
5254 }
5255 }
5256 }
5257
5258 /* Railtypes do not use the default group. */
5259 buf->ReadWord();
5260 }
5261
5262 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5263 {
5264 uint8 *airports = AllocaM(uint8, idcount);
5265 for (uint i = 0; i < idcount; i++) {
5266 airports[i] = buf->ReadByte();
5267 }
5268
5269 /* Skip the cargo type section, we only care about the default group */
5270 uint8 cidcount = buf->ReadByte();
5271 buf->Skip(cidcount * 3);
5272
5273 uint16 groupid = buf->ReadWord();
5274 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5275
5276 if (_cur.grffile->airportspec == NULL) {
5277 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5278 return;
5279 }
5280
5281 for (uint i = 0; i < idcount; i++) {
5282 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5283
5284 if (as == NULL) {
5285 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5286 continue;
5287 }
5288
5289 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5290 }
5291 }
5292
5293 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5294 {
5295 uint8 *airptiles = AllocaM(uint8, idcount);
5296 for (uint i = 0; i < idcount; i++) {
5297 airptiles[i] = buf->ReadByte();
5298 }
5299
5300 /* Skip the cargo type section, we only care about the default group */
5301 uint8 cidcount = buf->ReadByte();
5302 buf->Skip(cidcount * 3);
5303
5304 uint16 groupid = buf->ReadWord();
5305 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5306
5307 if (_cur.grffile->airtspec == NULL) {
5308 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5309 return;
5310 }
5311
5312 for (uint i = 0; i < idcount; i++) {
5313 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5314
5315 if (airtsp == NULL) {
5316 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5317 continue;
5318 }
5319
5320 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5321 }
5322 }
5323
5324
5325 /* Action 0x03 */
5326 static void FeatureMapSpriteGroup(ByteReader *buf)
5327 {
5328 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5329 * id-list := [<id>] [id-list]
5330 * cargo-list := <cargo-type> <cid> [cargo-list]
5331 *
5332 * B feature see action 0
5333 * B n-id bits 0-6: how many IDs this definition applies to
5334 * bit 7: if set, this is a wagon override definition (see below)
5335 * B ids the IDs for which this definition applies
5336 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5337 * can be zero, in that case the def-cid is used always
5338 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5339 * W cid cargo ID (sprite group ID) for this type of cargo
5340 * W def-cid default cargo ID (sprite group ID) */
5341
5342 uint8 feature = buf->ReadByte();
5343 uint8 idcount = buf->ReadByte();
5344
5345 /* If idcount is zero, this is a feature callback */
5346 if (idcount == 0) {
5347 /* Skip number of cargo ids? */
5348 buf->ReadByte();
5349 uint16 groupid = buf->ReadWord();
5350 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5351
5352 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5353
5354 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5355 return;
5356 }
5357
5358 /* Mark the feature as used by the grf (generic callbacks do not count) */
5359 SetBit(_cur.grffile->grf_features, feature);
5360
5361 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5362
5363 switch (feature) {
5364 case GSF_TRAINS:
5365 case GSF_ROADVEHICLES:
5366 case GSF_SHIPS:
5367 case GSF_AIRCRAFT:
5368 VehicleMapSpriteGroup(buf, feature, idcount);
5369 return;
5370
5371 case GSF_CANALS:
5372 CanalMapSpriteGroup(buf, idcount);
5373 return;
5374
5375 case GSF_STATIONS:
5376 StationMapSpriteGroup(buf, idcount);
5377 return;
5378
5379 case GSF_HOUSES:
5380 TownHouseMapSpriteGroup(buf, idcount);
5381 return;
5382
5383 case GSF_INDUSTRIES:
5384 IndustryMapSpriteGroup(buf, idcount);
5385 return;
5386
5387 case GSF_INDUSTRYTILES:
5388 IndustrytileMapSpriteGroup(buf, idcount);
5389 return;
5390
5391 case GSF_CARGOES:
5392 CargoMapSpriteGroup(buf, idcount);
5393 return;
5394
5395 case GSF_AIRPORTS:
5396 AirportMapSpriteGroup(buf, idcount);
5397 return;
5398
5399 case GSF_OBJECTS:
5400 ObjectMapSpriteGroup(buf, idcount);
5401 break;
5402
5403 case GSF_RAILTYPES:
5404 RailTypeMapSpriteGroup(buf, idcount);
5405 break;
5406
5407 case GSF_AIRPORTTILES:
5408 AirportTileMapSpriteGroup(buf, idcount);
5409 return;
5410
5411 default:
5412 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5413 return;
5414 }
5415 }
5416
5417 /* Action 0x04 */
5418 static void FeatureNewName(ByteReader *buf)
5419 {
5420 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5421 *
5422 * B veh-type see action 0 (as 00..07, + 0A
5423 * But IF veh-type = 48, then generic text
5424 * B language-id If bit 6 is set, This is the extended language scheme,
5425 * with up to 64 language.
5426 * Otherwise, it is a mapping where set bits have meaning
5427 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5428 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5429 * B num-veh number of vehicles which are getting a new name
5430 * B/W offset number of the first vehicle that gets a new name
5431 * Byte : ID of vehicle to change
5432 * Word : ID of string to change/add
5433 * S data new texts, each of them zero-terminated, after
5434 * which the next name begins. */
5435
5436 bool new_scheme = _cur.grffile->grf_version >= 7;
5437
5438 uint8 feature = buf->ReadByte();
5439 uint8 lang = buf->ReadByte();
5440 uint8 num = buf->ReadByte();
5441 bool generic = HasBit(lang, 7);
5442 uint16 id;
5443 if (generic) {
5444 id = buf->ReadWord();
5445 } else if (feature <= GSF_AIRCRAFT) {
5446 id = buf->ReadExtendedByte();
5447 } else {
5448 id = buf->ReadByte();
5449 }
5450
5451 ClrBit(lang, 7);
5452
5453 uint16 endid = id + num;
5454
5455 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5456 id, endid, feature, lang);
5457
5458 for (; id < endid && buf->HasData(); id++) {
5459 const char *name = buf->ReadString();
5460 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5461
5462 switch (feature) {
5463 case GSF_TRAINS:
5464 case GSF_ROADVEHICLES:
5465 case GSF_SHIPS:
5466 case GSF_AIRCRAFT:
5467 if (!generic) {
5468 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5469 if (e == NULL) break;
5470 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5471 e->info.string_id = string;
5472 } else {
5473 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5474 }
5475 break;
5476
5477 case GSF_INDUSTRIES: {
5478 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5479 break;
5480 }
5481
5482 case GSF_HOUSES:
5483 default:
5484 switch (GB(id, 8, 8)) {
5485 case 0xC4: // Station class name
5486 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5487 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5488 } else {
5489 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5490 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5491 }
5492 break;
5493
5494 case 0xC5: // Station name
5495 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5496 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5497 } else {
5498 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5499 }
5500 break;
5501
5502 case 0xC7: // Airporttile name
5503 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5504 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5505 } else {
5506 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5507 }
5508 break;
5509
5510 case 0xC9: // House name
5511 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5512 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5513 } else {
5514 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5515 }
5516 break;
5517
5518 case 0xD0:
5519 case 0xD1:
5520 case 0xD2:
5521 case 0xD3:
5522 case 0xDC:
5523 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5524 break;
5525
5526 default:
5527 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5528 break;
5529 }
5530 break;
5531 }
5532 }
5533 }
5534
5543 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5544 {
5545
5546 if (offset >= max_sprites) {
5547 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5548 uint orig_num = num;
5549 num = 0;
5550 return orig_num;
5551 }
5552
5553 if (offset + num > max_sprites) {
5554 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5555 uint orig_num = num;
5556 num = max(max_sprites - offset, 0);
5557 return orig_num - num;
5558 }
5559
5560 return 0;
5561 }
5562
5563
5565 enum Action5BlockType {
5566 A5BLOCK_FIXED,
5567 A5BLOCK_ALLOW_OFFSET,
5568 A5BLOCK_INVALID,
5569 };
5571 struct Action5Type {
5572 Action5BlockType block_type;
5573 SpriteID sprite_base;
5574 uint16 min_sprites;
5575 uint16 max_sprites;
5576 const char *name;
5577 };
5578
5580 static const Action5Type _action5_types[] = {
5581 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5582 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5583 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5584 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5585 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5586 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5587 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
5588 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5589 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5590 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5591 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5592 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5593 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5594 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5595 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5596 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5597 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5598 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5599 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5600 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5601 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5602 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5603 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5604 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5605 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5606 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5607 };
5608
5609 /* Action 0x05 */
5610 static void GraphicsNew(ByteReader *buf)
5611 {
5612 /* <05> <graphics-type> <num-sprites> <other data...>
5613 *
5614 * B graphics-type What set of graphics the sprites define.
5615 * E num-sprites How many sprites are in this set?
5616 * V other data Graphics type specific data. Currently unused. */
5617 /* TODO */
5618
5619 uint8 type = buf->ReadByte();
5620 uint16 num = buf->ReadExtendedByte();
5621 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5622 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5623
5624 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
5625 /* Special not-TTDP-compatible case used in openttd.grf
5626 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5627 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5628 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5629 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5630 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5631 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5632 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5633 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5634 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5635 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5636 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5637 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5638 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5639 return;
5640 }
5641
5642 /* Supported type? */
5643 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5644 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5645 _cur.skip_sprites = num;
5646 return;
5647 }
5648
5649 const Action5Type *action5_type = &_action5_types[type];
5650
5651 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5652 * except for the long version of the shore type:
5653 * Ignore offset if not allowed */
5654 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5655 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5656 offset = 0;
5657 }
5658
5659 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5660 * This does not make sense, if <offset> is allowed */
5661 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5662 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);
5663 _cur.skip_sprites = num;
5664 return;
5665 }
5666
5667 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5668 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5669 SpriteID replace = action5_type->sprite_base + offset;
5670
5671 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5672 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);
5673
5674 for (; num > 0; num--) {
5675 _cur.nfo_line++;
5676 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5677 }
5678
5679 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5680
5681 _cur.skip_sprites = skip_num;
5682 }
5683
5684 /* Action 0x05 (SKIP) */
5685 static void SkipAct5(ByteReader *buf)
5686 {
5687 /* Ignore type byte */
5688 buf->ReadByte();
5689
5690 /* Skip the sprites of this action */
5691 _cur.skip_sprites = buf->ReadExtendedByte();
5692
5693 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5694 }
5695
5701 void CheckForMissingSprites()
5702 {
5703 /* Don't break out quickly, but allow to check the other
5704 * sprites as well, so we can give the best information. */
5705 bool missing = false;
5706 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
5707 const Action5Type *type = &_action5_types[i];
5708 if (type->block_type == A5BLOCK_INVALID) continue;
5709
5710 for (uint j = 0; j < type->max_sprites; j++) {
5711 if (!SpriteExists(type->sprite_base + j)) {
5712 DEBUG(grf, 0, "%s sprites are missing", type->name);
5713 missing = true;
5714 /* No need to log more of the same. */
5715 break;
5716 }
5717 }
5718 }
5719
5720 if (missing) {
5721 ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
5722 }
5723 }
5724
5736 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5737 {
5738 switch (param) {
5739 case 0x00: // current date
5740 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5741 return true;
5742
5743 case 0x01: // current year
5744 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5745 return true;
5746
5747 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)
5748 YearMonthDay ymd;
5749 ConvertDateToYMD(_date, &ymd);
5750 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5751 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5752 return true;
5753 }
5754
5755 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5756 *value = _settings_game.game_creation.landscape;
5757 return true;
5758
5759 case 0x06: // road traffic side, bit 4 clear=left, set=right
5760 *value = _settings_game.vehicle.road_side << 4;
5761 return true;
5762
5763 case 0x09: // date fraction
5764 *value = _date_fract * 885;
5765 return true;
5766
5767 case 0x0A: // animation counter
5768 *value = _tick_counter;
5769 return true;
5770
5771 case 0x0B: { // TTDPatch version
5772 uint major = 2;
5773 uint minor = 6;
5774 uint revision = 1; // special case: 2.0.1 is 2.0.10
5775 uint build = 1382;
5776 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5777 return true;
5778 }
5779
5780 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5781 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5782 return true;
5783
5784 case 0x0E: // Y-offset for train sprites
5785 *value = _cur.grffile->traininfo_vehicle_pitch;
5786 return true;
5787
5788 case 0x0F: // Rail track type cost factors
5789 *value = 0;
5790 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5791 if (_settings_game.vehicle.disable_elrails) {
5792 /* skip elrail multiplier - disabled */
5793 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5794 } else {
5795 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5796 /* Skip monorail multiplier - no space in result */
5797 }
5798 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5799 return true;
5800
5801 case 0x11: // current rail tool type
5802 *value = 0; // constant fake value to avoid desync
5803 return true;
5804
5805 case 0x12: // Game mode
5806 *value = _game_mode;
5807 return true;
5808
5809 /* case 0x13: // Tile refresh offset to left not implemented */
5810 /* case 0x14: // Tile refresh offset to right not implemented */
5811 /* case 0x15: // Tile refresh offset upwards not implemented */
5812 /* case 0x16: // Tile refresh offset downwards not implemented */
5813 /* case 0x17: // temperate snow line not implemented */
5814
5815 case 0x1A: // Always -1
5816 *value = UINT_MAX;
5817 return true;
5818
5819 case 0x1B: // Display options
5820 *value = 0x3F; // constant fake value to avoid desync
5821 return true;
5822
5823 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5824 *value = 1;
5825 return true;
5826
5827 case 0x1E: // Miscellaneous GRF features
5828 *value = _misc_grf_features;
5829
5830 /* Add the local flags */
5831 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5832 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5833 return true;
5834
5835 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5836
5837 case 0x20: { // snow line height
5838 byte snowline = GetSnowLine();
5839 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5840 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5841 } else {
5842 /* No snow */
5843 *value = 0xFF;
5844 }
5845 return true;
5846 }
5847
5848 case 0x21: // OpenTTD version
5849 *value = _openttd_newgrf_version;
5850 return true;
5851
5852 case 0x22: // difficulty level
5853 *value = SP_CUSTOM;
5854 return true;
5855
5856 case 0x23: // long format date
5857 *value = _date;
5858 return true;
5859
5860 case 0x24: // long format year
5861 *value = _cur_year;
5862 return true;
5863
5864 default: return false;
5865 }
5866 }
5867
5868 static uint32 GetParamVal(byte param, uint32 *cond_val)
5869 {
5870 /* First handle variable common with VarAction2 */
5871 uint32 value;
5872 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5873
5874 /* Non-common variable */
5875 switch (param) {
5876 case 0x84: { // GRF loading stage
5877 uint32 res = 0;
5878
5879 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5880 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5881 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5882 return res;
5883 }
5884
5885 case 0x85: // TTDPatch flags, only for bit tests
5886 if (cond_val == NULL) {
5887 /* Supported in Action 0x07 and 0x09, not 0x0D */
5888 return 0;
5889 } else {
5890 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5891 *cond_val %= 0x20;
5892 return param_val;
5893 }
5894
5895 case 0x88: // GRF ID check
5896 return 0;
5897
5898 /* case 0x99: Global ID offset not implemented */
5899
5900 default:
5901 /* GRF Parameter */
5902 if (param < 0x80) return _cur.grffile->GetParam(param);
5903
5904 /* In-game variable. */
5905 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5906 return UINT_MAX;
5907 }
5908 }
5909
5910 /* Action 0x06 */
5911 static void CfgApply(ByteReader *buf)
5912 {
5913 /* <06> <param-num> <param-size> <offset> ... <FF>
5914 *
5915 * B param-num Number of parameter to substitute (First = "zero")
5916 * Ignored if that parameter was not specified in newgrf.cfg
5917 * B param-size How many bytes to replace. If larger than 4, the
5918 * bytes of the following parameter are used. In that
5919 * case, nothing is applied unless *all* parameters
5920 * were specified.
5921 * B offset Offset into data from beginning of next sprite
5922 * to place where parameter is to be stored. */
5923
5924 /* Preload the next sprite */
5925 size_t pos = FioGetPos();
5926 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5927 uint8 type = FioReadByte();
5928 byte *preload_sprite = NULL;
5929
5930 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5931 if (type == 0xFF) {
5932 preload_sprite = MallocT<byte>(num);
5933 FioReadBlock(preload_sprite, num);
5934 }
5935
5936 /* Reset the file position to the start of the next sprite */
5937 FioSeekTo(pos, SEEK_SET);
5938
5939 if (type != 0xFF) {
5940 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5941 free(preload_sprite);
5942 return;
5943 }
5944
5945 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5946 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5947 if (it != _grf_line_to_action6_sprite_override.end()) {
5948 free(preload_sprite);
5949 preload_sprite = _grf_line_to_action6_sprite_override[location];
5950 } else {
5951 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5952 }
5953
5954 /* Now perform the Action 0x06 on our data. */
5955
5956 for (;;) {
5957 uint i;
5958 uint param_num;
5959 uint param_size;
5960 uint offset;
5961 bool add_value;
5962
5963 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5964 param_num = buf->ReadByte();
5965 if (param_num == 0xFF) break;
5966
5967 /* Get the size of the parameter to use. If the size covers multiple
5968 * double words, sequential parameter values are used. */
5969 param_size = buf->ReadByte();
5970
5971 /* Bit 7 of param_size indicates we should add to the original value
5972 * instead of replacing it. */
5973 add_value = HasBit(param_size, 7);
5974 param_size = GB(param_size, 0, 7);
5975
5976 /* Where to apply the data to within the pseudo sprite data. */
5977 offset = buf->ReadExtendedByte();
5978
5979 /* If the parameter is a GRF parameter (not an internal variable) check
5980 * if it (and all further sequential parameters) has been defined. */
5981 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5982 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5983 break;
5984 }
5985
5986 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5987
5988 bool carry = false;
5989 for (i = 0; i < param_size && offset + i < num; i++) {
5990 uint32 value = GetParamVal(param_num + i / 4, NULL);
5991 /* Reset carry flag for each iteration of the variable (only really
5992 * matters if param_size is greater than 4) */
5993 if (i % 4 == 0) carry = false;
5994
5995 if (add_value) {
5996 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5997 preload_sprite[offset + i] = GB(new_value, 0, 8);
5998 /* Check if the addition overflowed */
5999 carry = new_value >= 256;
6000 } else {
6001 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6002 }
6003 }
6004 }
6005 }
6006
6016 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6017 {
6018 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6019 error->data = stredup(_cur.grfconfig->GetName());
6020 }
6021
6022 /* Action 0x07
6023 * Action 0x09 */
6024 static void SkipIf(ByteReader *buf)
6025 {
6026 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6027 *
6028 * B param-num
6029 * B param-size
6030 * B condition-type
6031 * V value
6032 * B num-sprites */
6033 /* TODO: More params. More condition types. */
6034 uint32 cond_val = 0;
6035 uint32 mask = 0;
6036 bool result;
6037
6038 uint8 param = buf->ReadByte();
6039 uint8 paramsize = buf->ReadByte();
6040 uint8 condtype = buf->ReadByte();
6041
6042 if (condtype < 2) {
6043 /* Always 1 for bit tests, the given value should be ignored. */
6044 paramsize = 1;
6045 }
6046
6047 switch (paramsize) {
6048 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6049 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6050 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6051 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6052 default: break;
6053 }
6054
6055 if (param < 0x80 && _cur.grffile->param_end <= param) {
6056 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6057 return;
6058 }
6059
6060 uint32 param_val = GetParamVal(param, &cond_val);
6061
6062 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6063
6064 /*
6065 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6066 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6067 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6068 * So, when the condition type is one of those, the specific variable
6069 * 0x88 code is skipped, so the "general" code for the cargo
6070 * availability conditions kicks in.
6071 */
6072 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6073 /* GRF ID checks */
6074
6075 GRFConfig *c = GetGRFConfig(cond_val, mask);
6076
6077 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6078 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6079 c = NULL;
6080 }
6081
6082 if (condtype != 10 && c == NULL) {
6083 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6084 return;
6085 }
6086
6087 switch (condtype) {
6088 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6089 case 0x06: // Is GRFID active?
6090 result = c->status == GCS_ACTIVATED;
6091 break;
6092
6093 case 0x07: // Is GRFID non-active?
6094 result = c->status != GCS_ACTIVATED;
6095 break;
6096
6097 case 0x08: // GRFID is not but will be active?
6098 result = c->status == GCS_INITIALISED;
6099 break;
6100
6101 case 0x09: // GRFID is or will be active?
6102 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6103 break;
6104
6105 case 0x0A: // GRFID is not nor will be active
6106 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6107 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6108 break;
6109
6110 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6111 }
6112 } else {
6113 /* Parameter or variable tests */
6114 switch (condtype) {
6115 case 0x00: result = !!(param_val & (1 << cond_val));
6116 break;
6117 case 0x01: result = !(param_val & (1 << cond_val));
6118 break;
6119 case 0x02: result = (param_val & mask) == cond_val;
6120 break;
6121 case 0x03: result = (param_val & mask) != cond_val;
6122 break;
6123 case 0x04: result = (param_val & mask) < cond_val;
6124 break;
6125 case 0x05: result = (param_val & mask) > cond_val;
6126 break;
6127 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6128 break;
6129 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6130 break;
6131 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6132 break;
6133 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6134 break;
6135
6136 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6137 }
6138 }
6139
6140 if (!result) {
6141 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6142 return;
6143 }
6144
6145 uint8 numsprites = buf->ReadByte();
6146
6147 /* numsprites can be a GOTO label if it has been defined in the GRF
6148 * file. The jump will always be the first matching label that follows
6149 * the current nfo_line. If no matching label is found, the first matching
6150 * label in the file is used. */
6151 GRFLabel *choice = NULL;
6152 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6153 if (label->label != numsprites) continue;
6154
6155 /* Remember a goto before the current line */
6156 if (choice == NULL) choice = label;
6157 /* If we find a label here, this is definitely good */
6158 if (label->nfo_line > _cur.nfo_line) {
6159 choice = label;
6160 break;
6161 }
6162 }
6163
6164 if (choice != NULL) {
6165 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6166 FioSeekTo(choice->pos, SEEK_SET);
6167 _cur.nfo_line = choice->nfo_line;
6168 return;
6169 }
6170
6171 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6172 _cur.skip_sprites = numsprites;
6173 if (_cur.skip_sprites == 0) {
6174 /* Zero means there are no sprites to skip, so
6175 * we use -1 to indicate that all further
6176 * sprites should be skipped. */
6177 _cur.skip_sprites = -1;
6178
6179 /* If an action 8 hasn't been encountered yet, disable the grf. */
6180 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6181 DisableGrf();
6182 }
6183 }
6184 }
6185
6186
6187 /* Action 0x08 (GLS_FILESCAN) */
6188 static void ScanInfo(ByteReader *buf)
6189 {
6190 uint8 grf_version = buf->ReadByte();
6191 uint32 grfid = buf->ReadDWord();
6192 const char *name = buf->ReadString();
6193
6194 _cur.grfconfig->ident.grfid = grfid;
6195
6196 if (grf_version < 2 || grf_version > 8) {
6197 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6198 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);
6199 }
6200
6201 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6202 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6203
6204 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6205
6206 if (buf->HasData()) {
6207 const char *info = buf->ReadString();
6208 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6209 }
6210
6211 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6212 _cur.skip_sprites = -1;
6213 }
6214
6215 /* Action 0x08 */
6216 static void GRFInfo(ByteReader *buf)
6217 {
6218 /* <08> <version> <grf-id> <name> <info>
6219 *
6220 * B version newgrf version, currently 06
6221 * 4*B grf-id globally unique ID of this .grf file
6222 * S name name of this .grf set
6223 * S info string describing the set, and e.g. author and copyright */
6224
6225 uint8 version = buf->ReadByte();
6226 uint32 grfid = buf->ReadDWord();
6227 const char *name = buf->ReadString();
6228
6229 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6230 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6231 return;
6232 }
6233
6234 if (_cur.grffile->grfid != grfid) {
6235 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));
6236 _cur.grffile->grfid = grfid;
6237 }
6238
6239 _cur.grffile->grf_version = version;
6240 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6241
6242 /* Do swap the GRFID for displaying purposes since people expect that */
6243 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);
6244 }
6245
6246 /* Action 0x0A */
6247 static void SpriteReplace(ByteReader *buf)
6248 {
6249 /* <0A> <num-sets> <set1> [<set2> ...]
6250 * <set>: <num-sprites> <first-sprite>
6251 *
6252 * B num-sets How many sets of sprites to replace.
6253 * Each set:
6254 * B num-sprites How many sprites are in this set
6255 * W first-sprite First sprite number to replace */
6256
6257 uint8 num_sets = buf->ReadByte();
6258
6259 for (uint i = 0; i < num_sets; i++) {
6260 uint8 num_sprites = buf->ReadByte();
6261 uint16 first_sprite = buf->ReadWord();
6262
6263 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6264 i, num_sprites, first_sprite
6265 );
6266
6267 for (uint j = 0; j < num_sprites; j++) {
6268 int load_index = first_sprite + j;
6269 _cur.nfo_line++;
6270 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6271
6272 /* Shore sprites now located at different addresses.
6273 * So detect when the old ones get replaced. */
6274 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6275 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6276 }
6277 }
6278 }
6279 }
6280
6281 /* Action 0x0A (SKIP) */
6282 static void SkipActA(ByteReader *buf)
6283 {
6284 uint8 num_sets = buf->ReadByte();
6285
6286 for (uint i = 0; i < num_sets; i++) {
6287 /* Skip the sprites this replaces */
6288 _cur.skip_sprites += buf->ReadByte();
6289 /* But ignore where they go */
6290 buf->ReadWord();
6291 }
6292
6293 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6294 }
6295
6296 /* Action 0x0B */
6297 static void GRFLoadError(ByteReader *buf)
6298 {
6299 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6300 *
6301 * B severity 00: notice, contine loading grf file
6302 * 01: warning, continue loading grf file
6303 * 02: error, but continue loading grf file, and attempt
6304 * loading grf again when loading or starting next game
6305 * 03: error, abort loading and prevent loading again in
6306 * the future (only when restarting the patch)
6307 * B language-id see action 4, use 1F for built-in error messages
6308 * B message-id message to show, see below
6309 * S message for custom messages (message-id FF), text of the message
6310 * not present for built-in messages.
6311 * V data additional data for built-in (or custom) messages
6312 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6313
6314 static const StringID msgstr[] = {
6315 STR_NEWGRF_ERROR_VERSION_NUMBER,
6316 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6317 STR_NEWGRF_ERROR_UNSET_SWITCH,
6318 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6319 STR_NEWGRF_ERROR_LOAD_BEFORE,
6320 STR_NEWGRF_ERROR_LOAD_AFTER,
6321 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6322 };
6323
6324 static const StringID sevstr[] = {
6325 STR_NEWGRF_ERROR_MSG_INFO,
6326 STR_NEWGRF_ERROR_MSG_WARNING,
6327 STR_NEWGRF_ERROR_MSG_ERROR,
6328 STR_NEWGRF_ERROR_MSG_FATAL
6329 };
6330
6331 byte severity = buf->ReadByte();
6332 byte lang = buf->ReadByte();
6333 byte message_id = buf->ReadByte();
6334
6335 /* Skip the error if it isn't valid for the current language. */
6336 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6337
6338 /* Skip the error until the activation stage unless bit 7 of the severity
6339 * is set. */
6340 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6341 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6342 return;
6343 }
6344 ClrBit(severity, 7);
6345
6346 if (severity >= lengthof(sevstr)) {
6347 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6348 severity = 2;
6349 } else if (severity == 3) {
6350 /* This is a fatal error, so make sure the GRF is deactivated and no
6351 * more of it gets loaded. */
6352 DisableGrf();
6353
6354 /* Make sure we show fatal errors, instead of silly infos from before */
6355 delete _cur.grfconfig->error;
6356 _cur.grfconfig->error = NULL;
6357 }
6358
6359 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6360 grfmsg(7, "GRFLoadError: Invalid message id.");
6361 return;
6362 }
6363
6364 if (buf->Remaining() <= 1) {
6365 grfmsg(7, "GRFLoadError: No message data supplied.");
6366 return;
6367 }
6368
6369 /* For now we can only show one message per newgrf file. */
6370 if (_cur.grfconfig->error != NULL) return;
6371
6372 GRFError *error = new GRFError(sevstr[severity]);
6373
6374 if (message_id == 0xFF) {
6375 /* This is a custom error message. */
6376 if (buf->HasData()) {
6377 const char *message = buf->ReadString();
6378
6379 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6380 } else {
6381 grfmsg(7, "GRFLoadError: No custom message supplied.");
6382 error->custom_message = stredup("");
6383 }
6384 } else {
6385 error->message = msgstr[message_id];
6386 }
6387
6388 if (buf->HasData()) {
6389 const char *data = buf->ReadString();
6390
6391 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6392 } else {
6393 grfmsg(7, "GRFLoadError: No message data supplied.");
6394 error->data = stredup("");
6395 }
6396
6397 /* Only two parameter numbers can be used in the string. */
6398 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6399 uint param_number = buf->ReadByte();
6400 error->param_value[i] = _cur.grffile->GetParam(param_number);
6401 }
6402
6403 _cur.grfconfig->error = error;
6404 }
6405
6406 /* Action 0x0C */
6407 static void GRFComment(ByteReader *buf)
6408 {
6409 /* <0C> [<ignored...>]
6410 *
6411 * V ignored Anything following the 0C is ignored */
6412
6413 if (!buf->HasData()) return;
6414
6415 const char *text = buf->ReadString();
6416 grfmsg(2, "GRFComment: %s", text);
6417 }
6418
6419 /* Action 0x0D (GLS_SAFETYSCAN) */
6420 static void SafeParamSet(ByteReader *buf)
6421 {
6422 uint8 target = buf->ReadByte();
6423
6424 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6425 if (target < 0x80 || target == 0x9E) return;
6426
6427 /* GRM could be unsafe, but as here it can only happen after other GRFs
6428 * are loaded, it should be okay. If the GRF tried to use the slots it
6429 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6430 * sprites is considered safe. */
6431
6432 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6433
6434 /* Skip remainder of GRF */
6435 _cur.skip_sprites = -1;
6436 }
6437
6438
6439 static uint32 GetPatchVariable(uint8 param)
6440 {
6441 switch (param) {
6442 /* start year - 1920 */
6443 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6444
6445 /* freight trains weight factor */
6446 case 0x0E: return _settings_game.vehicle.freight_trains;
6447
6448 /* empty wagon speed increase */
6449 case 0x0F: return 0;
6450
6451 /* plane speed factor; our patch option is reversed from TTDPatch's,
6452 * the following is good for 1x, 2x and 4x (most common?) and...
6453 * well not really for 3x. */
6454 case 0x10:
6455 switch (_settings_game.vehicle.plane_speed) {
6456 default:
6457 case 4: return 1;
6458 case 3: return 2;
6459 case 2: return 2;
6460 case 1: return 4;
6461 }
6462
6463
6464 /* 2CC colourmap base sprite */
6465 case 0x11: return SPR_2CCMAP_BASE;
6466
6467 /* map size: format = -MABXYSS
6468 * M : the type of map
6469 * bit 0 : set : squared map. Bit 1 is now not relevant
6470 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6471 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6472 * clear : X is the bigger edge.
6473 * A : minimum edge(log2) of the map
6474 * B : maximum edge(log2) of the map
6475 * XY : edges(log2) of each side of the map.
6476 * SS : combination of both X and Y, thus giving the size(log2) of the map
6477 */
6478 case 0x13: {
6479 byte map_bits = 0;
6480 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6481 byte log_Y = MapLogY() - 6;
6482 byte max_edge = max(log_X, log_Y);
6483
6484 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6485 SetBit(map_bits, 0);
6486 } else {
6487 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6488 }
6489
6490 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6491 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6492 }
6493
6494 /* The maximum height of the map. */
6495 case 0x14:
6496 return _settings_game.construction.max_heightlevel;
6497
6498 /* Extra foundations base sprite */
6499 case 0x15:
6500 return SPR_SLOPES_BASE;
6501
6502 /* Shore base sprite */
6503 case 0x16:
6504 return SPR_SHORE_BASE;
6505
6506 default:
6507 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6508 return 0;
6509 }
6510 }
6511
6512
6513 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6514 {
6515 uint start = 0;
6516 uint size = 0;
6517
6518 if (op == 6) {
6519 /* Return GRFID of set that reserved ID */
6520 return grm[_cur.grffile->GetParam(target)];
6521 }
6522
6523 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6524 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6525
6526 for (uint i = start; i < num_ids; i++) {
6527 if (grm[i] == 0) {
6528 size++;
6529 } else {
6530 if (op == 2 || op == 3) break;
6531 start = i + 1;
6532 size = 0;
6533 }
6534
6535 if (size == count) break;
6536 }
6537
6538 if (size == count) {
6539 /* Got the slot... */
6540 if (op == 0 || op == 3) {
6541 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6542 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6543 }
6544 return start;
6545 }
6546
6547 /* Unable to allocate */
6548 if (op != 4 && op != 5) {
6549 /* Deactivate GRF */
6550 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6551 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6552 return UINT_MAX;
6553 }
6554
6555 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6556 return UINT_MAX;
6557 }
6558
6559
6561 static void ParamSet(ByteReader *buf)
6562 {
6563 /* <0D> <target> <operation> <source1> <source2> [<data>]
6564 *
6565 * B target parameter number where result is stored
6566 * B operation operation to perform, see below
6567 * B source1 first source operand
6568 * B source2 second source operand
6569 * D data data to use in the calculation, not necessary
6570 * if both source1 and source2 refer to actual parameters
6571 *
6572 * Operations
6573 * 00 Set parameter equal to source1
6574 * 01 Addition, source1 + source2
6575 * 02 Subtraction, source1 - source2
6576 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6577 * 04 Signed multiplication, source1 * source2 (both signed)
6578 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6579 * signed quantity; left shift if positive and right shift if
6580 * negative, source1 is unsigned)
6581 * 06 Signed bit shift, source1 by source2
6582 * (source2 like in 05, and source1 as well)
6583 */
6584
6585 uint8 target = buf->ReadByte();
6586 uint8 oper = buf->ReadByte();
6587 uint32 src1 = buf->ReadByte();
6588 uint32 src2 = buf->ReadByte();
6589
6590 uint32 data = 0;
6591 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6592
6593 /* You can add 80 to the operation to make it apply only if the target
6594 * is not defined yet. In this respect, a parameter is taken to be
6595 * defined if any of the following applies:
6596 * - it has been set to any value in the newgrf(w).cfg parameter list
6597 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6598 * an earlier action D */
6599 if (HasBit(oper, 7)) {
6600 if (target < 0x80 && target < _cur.grffile->param_end) {
6601 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6602 return;
6603 }
6604
6605 oper = GB(oper, 0, 7);
6606 }
6607
6608 if (src2 == 0xFE) {
6609 if (GB(data, 0, 8) == 0xFF) {
6610 if (data == 0x0000FFFF) {
6611 /* Patch variables */
6612 src1 = GetPatchVariable(src1);
6613 } else {
6614 /* GRF Resource Management */
6615 uint8 op = src1;
6616 uint8 feature = GB(data, 8, 8);
6617 uint16 count = GB(data, 16, 16);
6618
6619 if (_cur.stage == GLS_RESERVE) {
6620 if (feature == 0x08) {
6621 /* General sprites */
6622 if (op == 0) {
6623 /* Check if the allocated sprites will fit below the original sprite limit */
6624 if (_cur.spriteid + count >= 16384) {
6625 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6626 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6627 return;
6628 }
6629
6630 /* Reserve space at the current sprite ID */
6631 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6632 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6633 _cur.spriteid += count;
6634 }
6635 }
6636 /* Ignore GRM result during reservation */
6637 src1 = 0;
6638 } else if (_cur.stage == GLS_ACTIVATION) {
6639 switch (feature) {
6640 case 0x00: // Trains
6641 case 0x01: // Road Vehicles
6642 case 0x02: // Ships
6643 case 0x03: // Aircraft
6644 if (!_settings_game.vehicle.dynamic_engines) {
6645 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6646 if (_cur.skip_sprites == -1) return;
6647 } else {
6648 /* GRM does not apply for dynamic engine allocation. */
6649 switch (op) {
6650 case 2:
6651 case 3:
6652 src1 = _cur.grffile->GetParam(target);
6653 break;
6654
6655 default:
6656 src1 = 0;
6657 break;
6658 }
6659 }
6660 break;
6661
6662 case 0x08: // General sprites
6663 switch (op) {
6664 case 0:
6665 /* Return space reserved during reservation stage */
6666 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6667 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6668 break;
6669
6670 case 1:
6671 src1 = _cur.spriteid;
6672 break;
6673
6674 default:
6675 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6676 return;
6677 }
6678 break;
6679
6680 case 0x0B: // Cargo
6681 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6682 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6683 if (_cur.skip_sprites == -1) return;
6684 break;
6685
6686 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6687 }
6688 } else {
6689 /* Ignore GRM during initialization */
6690 src1 = 0;
6691 }
6692 }
6693 } else {
6694 /* Read another GRF File's parameter */
6695 const GRFFile *file = GetFileByGRFID(data);
6696 GRFConfig *c = GetGRFConfig(data);
6697 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6698 /* Disable the read GRF if it is a static NewGRF. */
6699 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6700 src1 = 0;
6701 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6702 src1 = 0;
6703 } else if (src1 == 0xFE) {
6704 src1 = c->version;
6705 } else {
6706 src1 = file->GetParam(src1);
6707 }
6708 }
6709 } else {
6710 /* The source1 and source2 operands refer to the grf parameter number
6711 * like in action 6 and 7. In addition, they can refer to the special
6712 * variables available in action 7, or they can be FF to use the value
6713 * of <data>. If referring to parameters that are undefined, a value
6714 * of 0 is used instead. */
6715 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6716 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6717 }
6718
6719 /* TODO: You can access the parameters of another GRF file by using
6720 * source2=FE, source1=the other GRF's parameter number and data=GRF
6721 * ID. This is only valid with operation 00 (set). If the GRF ID
6722 * cannot be found, a value of 0 is used for the parameter value
6723 * instead. */
6724
6725 uint32 res;
6726 switch (oper) {
6727 case 0x00:
6728 res = src1;
6729 break;
6730
6731 case 0x01:
6732 res = src1 + src2;
6733 break;
6734
6735 case 0x02:
6736 res = src1 - src2;
6737 break;
6738
6739 case 0x03:
6740 res = src1 * src2;
6741 break;
6742
6743 case 0x04:
6744 res = (int32)src1 * (int32)src2;
6745 break;
6746
6747 case 0x05:
6748 if ((int32)src2 < 0) {
6749 res = src1 >> -(int32)src2;
6750 } else {
6751 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6752 }
6753 break;
6754
6755 case 0x06:
6756 if ((int32)src2 < 0) {
6757 res = (int32)src1 >> -(int32)src2;
6758 } else {
6759 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6760 }
6761 break;
6762
6763 case 0x07: // Bitwise AND
6764 res = src1 & src2;
6765 break;
6766
6767 case 0x08: // Bitwise OR
6768 res = src1 | src2;
6769 break;
6770
6771 case 0x09: // Unsigned division
6772 if (src2 == 0) {
6773 res = src1;
6774 } else {
6775 res = src1 / src2;
6776 }
6777 break;
6778
6779 case 0x0A: // Signed divison
6780 if (src2 == 0) {
6781 res = src1;
6782 } else {
6783 res = (int32)src1 / (int32)src2;
6784 }
6785 break;
6786
6787 case 0x0B: // Unsigned modulo
6788 if (src2 == 0) {
6789 res = src1;
6790 } else {
6791 res = src1 % src2;
6792 }
6793 break;
6794
6795 case 0x0C: // Signed modulo
6796 if (src2 == 0) {
6797 res = src1;
6798 } else {
6799 res = (int32)src1 % (int32)src2;
6800 }
6801 break;
6802
6803 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6804 }
6805
6806 switch (target) {
6807 case 0x8E: // Y-Offset for train sprites
6808 _cur.grffile->traininfo_vehicle_pitch = res;
6809 break;
6810
6811 case 0x8F: { // Rail track type cost factors
6812 extern RailtypeInfo _railtypes[RAILTYPE_END];
6813 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6814 if (_settings_game.vehicle.disable_elrails) {
6815 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6816 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6817 } else {
6818 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6819 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6820 }
6821 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6822 break;
6823 }
6824
6825 /* @todo implement */
6826 case 0x93: // Tile refresh offset to left
6827 case 0x94: // Tile refresh offset to right
6828 case 0x95: // Tile refresh offset upwards
6829 case 0x96: // Tile refresh offset downwards
6830 case 0x97: // Snow line height
6831 case 0x99: // Global ID offset
6832 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6833 break;
6834
6835 case 0x9E: // Miscellaneous GRF features
6836 /* Set train list engine width */
6837 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6838 /* Remove the local flags from the global flags */
6839 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6840
6841 /* Only copy safe bits for static grfs */
6842 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6843 uint32 safe_bits = 0;
6844 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6845
6846 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6847 } else {
6848 _misc_grf_features = res;
6849 }
6850 break;
6851
6852 case 0x9F: // locale-dependent settings
6853 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6854 break;
6855
6856 default:
6857 if (target < 0x80) {
6858 _cur.grffile->param[target] = res;
6859 /* param is zeroed by default */
6860 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6861 } else {
6862 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6863 }
6864 break;
6865 }
6866 }
6867
6868 /* Action 0x0E (GLS_SAFETYSCAN) */
6869 static void SafeGRFInhibit(ByteReader *buf)
6870 {
6871 /* <0E> <num> <grfids...>
6872 *
6873 * B num Number of GRFIDs that follow
6874 * D grfids GRFIDs of the files to deactivate */
6875
6876 uint8 num = buf->ReadByte();
6877
6878 for (uint i = 0; i < num; i++) {
6879 uint32 grfid = buf->ReadDWord();
6880
6881 /* GRF is unsafe it if tries to deactivate other GRFs */
6882 if (grfid != _cur.grfconfig->ident.grfid) {
6883 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6884
6885 /* Skip remainder of GRF */
6886 _cur.skip_sprites = -1;
6887
6888 return;
6889 }
6890 }
6891 }
6892
6893 /* Action 0x0E */
6894 static void GRFInhibit(ByteReader *buf)
6895 {
6896 /* <0E> <num> <grfids...>
6897 *
6898 * B num Number of GRFIDs that follow
6899 * D grfids GRFIDs of the files to deactivate */
6900
6901 uint8 num = buf->ReadByte();
6902
6903 for (uint i = 0; i < num; i++) {
6904 uint32 grfid = buf->ReadDWord();
6905 GRFConfig *file = GetGRFConfig(grfid);
6906
6907 /* Unset activation flag */
6908 if (file != NULL && file != _cur.grfconfig) {
6909 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6910 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6911 error->data = stredup(_cur.grfconfig->GetName());
6912 }
6913 }
6914 }
6915
6917 static void FeatureTownName(ByteReader *buf)
6918 {
6919 /* <0F> <id> <style-name> <num-parts> <parts>
6920 *
6921 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6922 * V style-name Name of the style (only for final definition)
6923 * B num-parts Number of parts in this definition
6924 * V parts The parts */
6925
6926 uint32 grfid = _cur.grffile->grfid;
6927
6928 GRFTownName *townname = AddGRFTownName(grfid);
6929
6930 byte id = buf->ReadByte();
6931 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6932
6933 if (HasBit(id, 7)) {
6934 /* Final definition */
6935 ClrBit(id, 7);
6936 bool new_scheme = _cur.grffile->grf_version >= 7;
6937
6938 byte lang = buf->ReadByte();
6939
6940 byte nb_gen = townname->nb_gen;
6941 do {
6942 ClrBit(lang, 7);
6943
6944 const char *name = buf->ReadString();
6945
6946 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6947 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6948 free(lang_name);
6949
6950 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6951
6952 lang = buf->ReadByte();
6953 } while (lang != 0);
6954 townname->id[nb_gen] = id;
6955 townname->nb_gen++;
6956 }
6957
6958 byte nb = buf->ReadByte();
6959 grfmsg(6, "FeatureTownName: %u parts", nb);
6960
6961 townname->nbparts[id] = nb;
6962 townname->partlist[id] = CallocT<NamePartList>(nb);
6963
6964 for (int i = 0; i < nb; i++) {
6965 byte nbtext = buf->ReadByte();
6966 townname->partlist[id][i].bitstart = buf->ReadByte();
6967 townname->partlist[id][i].bitcount = buf->ReadByte();
6968 townname->partlist[id][i].maxprob = 0;
6969 townname->partlist[id][i].partcount = nbtext;
6970 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6971 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);
6972
6973 for (int j = 0; j < nbtext; j++) {
6974 byte prob = buf->ReadByte();
6975
6976 if (HasBit(prob, 7)) {
6977 byte ref_id = buf->ReadByte();
6978
6979 if (townname->nbparts[ref_id] == 0) {
6980 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6981 DelGRFTownName(grfid);
6982 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6983 return;
6984 }
6985
6986 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6987 townname->partlist[id][i].parts[j].data.id = ref_id;
6988 } else {
6989 const char *text = buf->ReadString();
6990 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6991 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6992 }
6993 townname->partlist[id][i].parts[j].prob = prob;
6994 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6995 }
6996 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6997 }
6998 }
6999
7001 static void DefineGotoLabel(ByteReader *buf)
7002 {
7003 /* <10> <label> [<comment>]
7004 *
7005 * B label The label to define
7006 * V comment Optional comment - ignored */
7007
7008 byte nfo_label = buf->ReadByte();
7009
7010 GRFLabel *label = MallocT<GRFLabel>(1);
7011 label->label = nfo_label;
7012 label->nfo_line = _cur.nfo_line;
7013 label->pos = FioGetPos();
7014 label->next = NULL;
7015
7016 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7017 if (_cur.grffile->label == NULL) {
7018 _cur.grffile->label = label;
7019 } else {
7020 /* Attach the label to the end of the list */
7021 GRFLabel *l;
7022 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7023 l->next = label;
7024 }
7025
7026 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7027 }
7028
7033 static void ImportGRFSound(SoundEntry *sound)
7034 {
7035 const GRFFile *file;
7036 uint32 grfid = FioReadDword();
7037 SoundID sound_id = FioReadWord();
7038
7039 file = GetFileByGRFID(grfid);
7040 if (file == NULL || file->sound_offset == 0) {
7041 grfmsg(1, "ImportGRFSound: Source file not available");
7042 return;
7043 }
7044
7045 if (sound_id >= file->num_sounds) {
7046 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7047 return;
7048 }
7049
7050 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7051
7052 *sound = *GetSound(file->sound_offset + sound_id);
7053
7054 /* Reset volume and priority, which TTDPatch doesn't copy */
7055 sound->volume = 128;
7056 sound->priority = 0;
7057 }
7058
7064 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7065 {
7066 /* Set default volume and priority */
7067 sound->volume = 0x80;
7068 sound->priority = 0;
7069
7070 if (offs != SIZE_MAX) {
7071 /* Sound is present in the NewGRF. */
7072 sound->file_slot = _cur.file_index;
7073 sound->file_offset = offs;
7074 sound->grf_container_ver = _cur.grf_container_ver;
7075 }
7076 }
7077
7078 /* Action 0x11 */
7079 static void GRFSound(ByteReader *buf)
7080 {
7081 /* <11> <num>
7082 *
7083 * W num Number of sound files that follow */
7084
7085 uint16 num = buf->ReadWord();
7086 if (num == 0) return;
7087
7088 SoundEntry *sound;
7089 if (_cur.grffile->sound_offset == 0) {
7090 _cur.grffile->sound_offset = GetNumSounds();
7091 _cur.grffile->num_sounds = num;
7092 sound = AllocateSound(num);
7093 } else {
7094 sound = GetSound(_cur.grffile->sound_offset);
7095 }
7096
7097 for (int i = 0; i < num; i++) {
7098 _cur.nfo_line++;
7099
7100 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7101 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7102 bool invalid = i >= _cur.grffile->num_sounds;
7103
7104 size_t offs = FioGetPos();
7105
7106 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7107 byte type = FioReadByte();
7108
7109 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7110 /* Reference to sprite section. */
7111 if (invalid) {
7112 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7113 FioSkipBytes(len);
7114 } else if (len != 4) {
7115 grfmsg(1, "GRFSound: Invalid sprite section import");
7116 FioSkipBytes(len);
7117 } else {
7118 uint32 id = FioReadDword();
7119 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7120 }
7121 continue;
7122 }
7123
7124 if (type != 0xFF) {
7125 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7126 FioSkipBytes(7);
7127 SkipSpriteData(type, len - 8);
7128 continue;
7129 }
7130
7131 if (invalid) {
7132 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7133 FioSkipBytes(len);
7134 }
7135
7136 byte action = FioReadByte();
7137 switch (action) {
7138 case 0xFF:
7139 /* Allocate sound only in init stage. */
7140 if (_cur.stage == GLS_INIT) {
7141 if (_cur.grf_container_ver >= 2) {
7142 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7143 } else {
7144 LoadGRFSound(offs, sound + i);
7145 }
7146 }
7147 FioSkipBytes(len - 1); // already read <action>
7148 break;
7149
7150 case 0xFE:
7151 if (_cur.stage == GLS_ACTIVATION) {
7152 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7153 * importing sounds, so this is probably all wrong... */
7154 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7155 ImportGRFSound(sound + i);
7156 } else {
7157 FioSkipBytes(len - 1); // already read <action>
7158 }
7159 break;
7160
7161 default:
7162 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7163 FioSkipBytes(len - 1); // already read <action>
7164 break;
7165 }
7166 }
7167 }
7168
7169 /* Action 0x11 (SKIP) */
7170 static void SkipAct11(ByteReader *buf)
7171 {
7172 /* <11> <num>
7173 *
7174 * W num Number of sound files that follow */
7175
7176 _cur.skip_sprites = buf->ReadWord();
7177
7178 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7179 }
7180
7182 static void LoadFontGlyph(ByteReader *buf)
7183 {
7184 /* <12> <num_def> <font_size> <num_char> <base_char>
7185 *
7186 * B num_def Number of definitions
7187 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7188 * B num_char Number of consecutive glyphs
7189 * W base_char First character index */
7190
7191 uint8 num_def = buf->ReadByte();
7192
7193 for (uint i = 0; i < num_def; i++) {
7194 FontSize size = (FontSize)buf->ReadByte();
7195 uint8 num_char = buf->ReadByte();
7196 uint16 base_char = buf->ReadWord();
7197
7198 if (size >= FS_END) {
7199 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7200 }
7201
7202 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7203
7204 for (uint c = 0; c < num_char; c++) {
7205 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7206 _cur.nfo_line++;
7207 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7208 }
7209 }
7210 }
7211
7213 static void SkipAct12(ByteReader *buf)
7214 {
7215 /* <12> <num_def> <font_size> <num_char> <base_char>
7216 *
7217 * B num_def Number of definitions
7218 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7219 * B num_char Number of consecutive glyphs
7220 * W base_char First character index */
7221
7222 uint8 num_def = buf->ReadByte();
7223
7224 for (uint i = 0; i < num_def; i++) {
7225 /* Ignore 'size' byte */
7226 buf->ReadByte();
7227
7228 /* Sum up number of characters */
7229 _cur.skip_sprites += buf->ReadByte();
7230
7231 /* Ignore 'base_char' word */
7232 buf->ReadWord();
7233 }
7234
7235 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7236 }
7237
7239 static void TranslateGRFStrings(ByteReader *buf)
7240 {
7241 /* <13> <grfid> <num-ent> <offset> <text...>
7242 *
7243 * 4*B grfid The GRFID of the file whose texts are to be translated
7244 * B num-ent Number of strings
7245 * W offset First text ID
7246 * S text... Zero-terminated strings */
7247
7248 uint32 grfid = buf->ReadDWord();
7249 const GRFConfig *c = GetGRFConfig(grfid);
7250 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7251 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7252 return;
7253 }
7254
7255 if (c->status == GCS_INITIALISED) {
7256 /* If the file is not active but will be activated later, give an error
7257 * and disable this file. */
7258 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7259
7260 char tmp[256];
7261 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7262 error->data = stredup(tmp);
7263
7264 return;
7265 }
7266
7267 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7268 * to be added as a generic string, thus the language id of 0x7F. For this to work
7269 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7270 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7271 * not change anything if a string has been provided specifically for this language. */
7272 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7273 byte num_strings = buf->ReadByte();
7274 uint16 first_id = buf->ReadWord();
7275
7276 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7277 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7278 return;
7279 }
7280
7281 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7282 const char *string = buf->ReadString();
7283
7284 if (StrEmpty(string)) {
7285 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7286 continue;
7287 }
7288
7289 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7290 }
7291 }
7292
7294 static bool ChangeGRFName(byte langid, const char *str)
7295 {
7296 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7297 return true;
7298 }
7299
7301 static bool ChangeGRFDescription(byte langid, const char *str)
7302 {
7303 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7304 return true;
7305 }
7306
7308 static bool ChangeGRFURL(byte langid, const char *str)
7309 {
7310 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7311 return true;
7312 }
7313
7315 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7316 {
7317 if (len != 1) {
7318 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7319 buf->Skip(len);
7320 } else {
7321 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7322 }
7323 return true;
7324 }
7325
7327 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7328 {
7329 if (len != 1) {
7330 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7331 buf->Skip(len);
7332 } else {
7333 char data = buf->ReadByte();
7334 GRFPalette pal = GRFP_GRF_UNSET;
7335 switch (data) {
7336 case '*':
7337 case 'A': pal = GRFP_GRF_ANY; break;
7338 case 'W': pal = GRFP_GRF_WINDOWS; break;
7339 case 'D': pal = GRFP_GRF_DOS; break;
7340 default:
7341 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7342 break;
7343 }
7344 if (pal != GRFP_GRF_UNSET) {
7345 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7346 _cur.grfconfig->palette |= pal;
7347 }
7348 }
7349 return true;
7350 }
7351
7353 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7354 {
7355 if (len != 1) {
7356 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7357 buf->Skip(len);
7358 } else {
7359 char data = buf->ReadByte();
7360 GRFPalette pal = GRFP_BLT_UNSET;
7361 switch (data) {
7362 case '8': pal = GRFP_BLT_UNSET; break;
7363 case '3': pal = GRFP_BLT_32BPP; break;
7364 default:
7365 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7366 return true;
7367 }
7368 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7369 _cur.grfconfig->palette |= pal;
7370 }
7371 return true;
7372 }
7373
7375 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7376 {
7377 if (len != 4) {
7378 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7379 buf->Skip(len);
7380 } else {
7381 /* Set min_loadable_version as well (default to minimal compatibility) */
7382 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7383 }
7384 return true;
7385 }
7386
7388 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7389 {
7390 if (len != 4) {
7391 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7392 buf->Skip(len);
7393 } else {
7394 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7395 if (_cur.grfconfig->version == 0) {
7396 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7397 _cur.grfconfig->min_loadable_version = 0;
7398 }
7399 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7400 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7401 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7402 }
7403 }
7404 return true;
7405 }
7406
7407 static GRFParameterInfo *_cur_parameter;
7408
7410 static bool ChangeGRFParamName(byte langid, const char *str)
7411 {
7412 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7413 return true;
7414 }
7415
7417 static bool ChangeGRFParamDescription(byte langid, const char *str)
7418 {
7419 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7420 return true;
7421 }
7422
7424 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7425 {
7426 if (len != 1) {
7427 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7428 buf->Skip(len);
7429 } else {
7430 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7431 if (type < PTYPE_END) {
7432 _cur_parameter->type = type;
7433 } else {
7434 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7435 }
7436 }
7437 return true;
7438 }
7439
7441 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7442 {
7443 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7444 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7445 buf->Skip(len);
7446 } else if (len != 8) {
7447 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7448 buf->Skip(len);
7449 } else {
7450 _cur_parameter->min_value = buf->ReadDWord();
7451 _cur_parameter->max_value = buf->ReadDWord();
7452 }
7453 return true;
7454 }
7455
7457 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7458 {
7459 if (len < 1 || len > 3) {
7460 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7461 buf->Skip(len);
7462 } else {
7463 byte param_nr = buf->ReadByte();
7464 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7465 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7466 buf->Skip(len - 1);
7467 } else {
7468 _cur_parameter->param_nr = param_nr;
7469 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7470 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7471 }
7472 }
7473
7474 return true;
7475 }
7476
7478 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7479 {
7480 if (len != 4) {
7481 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7482 buf->Skip(len);
7483 } else {
7484 _cur_parameter->def_value = buf->ReadDWord();
7485 }
7486 _cur.grfconfig->has_param_defaults = true;
7487 return true;
7488 }
7489
7490 typedef bool (*DataHandler)(size_t, ByteReader *);
7491 typedef bool (*TextHandler)(byte, const char *str);
7492 typedef bool (*BranchHandler)(ByteReader *);
7493
7501 struct AllowedSubtags {
7503 AllowedSubtags() :
7504 id(0),
7505 type(0)
7506 {}
7507
7513 AllowedSubtags(uint32 id, DataHandler handler) :
7514 id(id),
7515 type('B')
7516 {
7517 this->handler.data = handler;
7518 }
7519
7525 AllowedSubtags(uint32 id, TextHandler handler) :
7526 id(id),
7527 type('T')
7528 {
7529 this->handler.text = handler;
7530 }
7531
7537 AllowedSubtags(uint32 id, BranchHandler handler) :
7538 id(id),
7539 type('C')
7540 {
7541 this->handler.call_handler = true;
7542 this->handler.u.branch = handler;
7543 }
7544
7550 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7551 id(id),
7552 type('C')
7553 {
7554 this->handler.call_handler = false;
7555 this->handler.u.subtags = subtags;
7556 }
7557
7558 uint32 id;
7559 byte type;
7560 union {
7561 DataHandler data;
7562 TextHandler text;
7563 struct {
7564 union {
7565 BranchHandler branch;
7566 AllowedSubtags *subtags;
7567 } u;
7568 bool call_handler;
7569 };
7570 } handler;
7571 };
7572
7573 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7574 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7575
7582 static bool ChangeGRFParamValueNames(ByteReader *buf)
7583 {
7584 byte type = buf->ReadByte();
7585 while (type != 0) {
7586 uint32 id = buf->ReadDWord();
7587 if (type != 'T' || id > _cur_parameter->max_value) {
7588 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7589 if (!SkipUnknownInfo(buf, type)) return false;
7590 type = buf->ReadByte();
7591 continue;
7592 }
7593
7594 byte langid = buf->ReadByte();
7595 const char *name_string = buf->ReadString();
7596
7597 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7598 if (val_name != _cur_parameter->value_names.End()) {
7599 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7600 } else {
7601 GRFText *list = NULL;
7602 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7603 _cur_parameter->value_names.Insert(id, list);
7604 }
7605
7606 type = buf->ReadByte();
7607 }
7608 return true;
7609 }
7610
7612 AllowedSubtags _tags_parameters[] = {
7613 AllowedSubtags('NAME', ChangeGRFParamName),
7614 AllowedSubtags('DESC', ChangeGRFParamDescription),
7615 AllowedSubtags('TYPE', ChangeGRFParamType),
7616 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7617 AllowedSubtags('MASK', ChangeGRFParamMask),
7618 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7619 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7620 AllowedSubtags()
7621 };
7622
7629 static bool HandleParameterInfo(ByteReader *buf)
7630 {
7631 byte type = buf->ReadByte();
7632 while (type != 0) {
7633 uint32 id = buf->ReadDWord();
7634 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7635 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7636 if (!SkipUnknownInfo(buf, type)) return false;
7637 type = buf->ReadByte();
7638 continue;
7639 }
7640
7641 if (id >= _cur.grfconfig->param_info.Length()) {
7642 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7643 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7644 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7645 }
7646 if (_cur.grfconfig->param_info[id] == NULL) {
7647 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7648 }
7649 _cur_parameter = _cur.grfconfig->param_info[id];
7650 /* Read all parameter-data and process each node. */
7651 if (!HandleNodes(buf, _tags_parameters)) return false;
7652 type = buf->ReadByte();
7653 }
7654 return true;
7655 }
7656
7658 AllowedSubtags _tags_info[] = {
7659 AllowedSubtags('NAME', ChangeGRFName),
7660 AllowedSubtags('DESC', ChangeGRFDescription),
7661 AllowedSubtags('URL_', ChangeGRFURL),
7662 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7663 AllowedSubtags('PALS', ChangeGRFPalette),
7664 AllowedSubtags('BLTR', ChangeGRFBlitter),
7665 AllowedSubtags('VRSN', ChangeGRFVersion),
7666 AllowedSubtags('MINV', ChangeGRFMinVersion),
7667 AllowedSubtags('PARA', HandleParameterInfo),
7668 AllowedSubtags()
7669 };
7670
7672 AllowedSubtags _tags_root[] = {
7673 AllowedSubtags('INFO', _tags_info),
7674 AllowedSubtags()
7675 };
7676
7677
7684 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7685 {
7686 /* type and id are already read */
7687 switch (type) {
7688 case 'C': {
7689 byte new_type = buf->ReadByte();
7690 while (new_type != 0) {
7691 buf->ReadDWord(); // skip the id
7692 if (!SkipUnknownInfo(buf, new_type)) return false;
7693 new_type = buf->ReadByte();
7694 }
7695 break;
7696 }
7697
7698 case 'T':
7699 buf->ReadByte(); // lang
7700 buf->ReadString(); // actual text
7701 break;
7702
7703 case 'B': {
7704 uint16 size = buf->ReadWord();
7705 buf->Skip(size);
7706 break;
7707 }
7708
7709 default:
7710 return false;
7711 }
7712
7713 return true;
7714 }
7715
7724 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7725 {
7726 uint i = 0;
7727 AllowedSubtags *tag;
7728 while ((tag = &subtags[i++])->type != 0) {
7729 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7730 switch (type) {
7731 default: NOT_REACHED();
7732
7733 case 'T': {
7734 byte langid = buf->ReadByte();
7735 return tag->handler.text(langid, buf->ReadString());
7736 }
7737
7738 case 'B': {
7739 size_t len = buf->ReadWord();
7740 if (buf->Remaining() < len) return false;
7741 return tag->handler.data(len, buf);
7742 }
7743
7744 case 'C': {
7745 if (tag->handler.call_handler) {
7746 return tag->handler.u.branch(buf);
7747 }
7748 return HandleNodes(buf, tag->handler.u.subtags);
7749 }
7750 }
7751 }
7752 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7753 return SkipUnknownInfo(buf, type);
7754 }
7755
7762 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7763 {
7764 byte type = buf->ReadByte();
7765 while (type != 0) {
7766 uint32 id = buf->ReadDWord();
7767 if (!HandleNode(type, id, buf, subtags)) return false;
7768 type = buf->ReadByte();
7769 }
7770 return true;
7771 }
7772
7777 static void StaticGRFInfo(ByteReader *buf)
7778 {
7779 /* <14> <type> <id> <text/data...> */
7780 HandleNodes(buf, _tags_root);
7781 }
7782
7788 static void GRFUnsafe(ByteReader *buf)
7789 {
7790 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7791
7792 /* Skip remainder of GRF */
7793 _cur.skip_sprites = -1;
7794 }
7795
7796
7798 static void InitializeGRFSpecial()
7799 {
7800 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7801 | (1 << 0x0D) // newairports
7802 | (1 << 0x0E) // largestations
7803 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7804 | (0 << 0x10) // loadtime
7805 | (1 << 0x12) // presignals
7806 | (1 << 0x13) // extpresignals
7807 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7808 | (1 << 0x1B) // multihead
7809 | (1 << 0x1D) // lowmemory
7810 | (1 << 0x1E); // generalfixes
7811
7812 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7813 | (1 << 0x08) // mammothtrains
7814 | (1 << 0x09) // trainrefit
7815 | (0 << 0x0B) // subsidiaries
7816 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7817 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7818 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7819 | (1 << 0x14) // bridgespeedlimits
7820 | (1 << 0x16) // eternalgame
7821 | (1 << 0x17) // newtrains
7822 | (1 << 0x18) // newrvs
7823 | (1 << 0x19) // newships
7824 | (1 << 0x1A) // newplanes
7825 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7826 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7827
7828 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7829 | (1 << 0x03) // semaphores
7830 | (1 << 0x0A) // newobjects
7831 | (0 << 0x0B) // enhancedgui
7832 | (0 << 0x0C) // newagerating
7833 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7834 | (1 << 0x0E) // fullloadany
7835 | (1 << 0x0F) // planespeed
7836 | (0 << 0x10) // moreindustriesperclimate - obsolete
7837 | (0 << 0x11) // moretoylandfeatures
7838 | (1 << 0x12) // newstations
7839 | (1 << 0x13) // tracktypecostdiff
7840 | (1 << 0x14) // manualconvert
7841 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7842 | (1 << 0x16) // canals
7843 | (1 << 0x17) // newstartyear
7844 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7845 | (1 << 0x19) // newhouses
7846 | (1 << 0x1A) // newbridges
7847 | (1 << 0x1B) // newtownnames
7848 | (1 << 0x1C) // moreanimation
7849 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7850 | (1 << 0x1E) // newshistory
7851 | (0 << 0x1F); // custombridgeheads
7852
7853 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7854 | (1 << 0x01) // windowsnap
7855 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7856 | (1 << 0x03) // pathbasedsignalling
7857 | (0 << 0x04) // aichoosechance
7858 | (1 << 0x05) // resolutionwidth
7859 | (1 << 0x06) // resolutionheight
7860 | (1 << 0x07) // newindustries
7861 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7862 | (0 << 0x09) // townroadbranchprob
7863 | (0 << 0x0A) // tempsnowline
7864 | (1 << 0x0B) // newcargo
7865 | (1 << 0x0C) // enhancemultiplayer
7866 | (1 << 0x0D) // onewayroads
7867 | (1 << 0x0E) // irregularstations
7868 | (1 << 0x0F) // statistics
7869 | (1 << 0x10) // newsounds
7870 | (1 << 0x11) // autoreplace
7871 | (1 << 0x12) // autoslope
7872 | (0 << 0x13) // followvehicle
7873 | (1 << 0x14) // trams
7874 | (0 << 0x15) // enhancetunnels
7875 | (1 << 0x16) // shortrvs
7876 | (1 << 0x17) // articulatedrvs
7877 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7878 | (1 << 0x1E) // variablerunningcosts
7879 | (1 << 0x1F); // any switch is on
7880 }
7881
7883 static void ResetCustomStations()
7884 {
7885 const GRFFile * const *end = _grf_files.End();
7886 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7887 StationSpec **&stations = (*file)->stations;
7888 if (stations == NULL) continue;
7889 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7890 if (stations[i] == NULL) continue;
7891 StationSpec *statspec = stations[i];
7892
7893 delete[] statspec->renderdata;
7894
7895 /* Release platforms and layouts */
7896 if (!statspec->copied_layouts) {
7897 for (uint l = 0; l < statspec->lengths; l++) {
7898 for (uint p = 0; p < statspec->platforms[l]; p++) {
7899 free(statspec->layouts[l][p]);
7900 }
7901 free(statspec->layouts[l]);
7902 }
7903 free(statspec->layouts);
7904 free(statspec->platforms);
7905 }
7906
7907 /* Release this station */
7908 free(statspec);
7909 }
7910
7911 /* Free and reset the station data */
7912 free(stations);
7913 stations = NULL;
7914 }
7915 }
7916
7918 static void ResetCustomHouses()
7919 {
7920 const GRFFile * const *end = _grf_files.End();
7921 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7922 HouseSpec **&housespec = (*file)->housespec;
7923 if (housespec == NULL) continue;
7924 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7925 free(housespec[i]);
7926 }
7927
7928 free(housespec);
7929 housespec = NULL;
7930 }
7931 }
7932
7934 static void ResetCustomAirports()
7935 {
7936 const GRFFile * const *end = _grf_files.End();
7937 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7938 AirportSpec **aslist = (*file)->airportspec;
7939 if (aslist != NULL) {
7940 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7941 AirportSpec *as = aslist[i];
7942
7943 if (as != NULL) {
7944 /* We need to remove the tiles layouts */
7945 for (int j = 0; j < as->num_table; j++) {
7946 /* remove the individual layouts */
7947 free(as->table[j]);
7948 }
7949 free(as->table);
7950 free(as->depot_table);
7951
7952 free(as);
7953 }
7954 }
7955 free(aslist);
7956 (*file)->airportspec = NULL;
7957 }
7958
7959 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7960 if (airporttilespec != NULL) {
7961 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7962 free(airporttilespec[i]);
7963 }
7964 free(airporttilespec);
7965 airporttilespec = NULL;
7966 }
7967 }
7968 }
7969
7971 static void ResetCustomIndustries()
7972 {
7973 const GRFFile * const *end = _grf_files.End();
7974 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7975 IndustrySpec **&industryspec = (*file)->industryspec;
7976 IndustryTileSpec **&indtspec = (*file)->indtspec;
7977
7978 /* We are verifiying both tiles and industries specs loaded from the grf file
7979 * First, let's deal with industryspec */
7980 if (industryspec != NULL) {
7981 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7982 IndustrySpec *ind = industryspec[i];
7983 if (ind == NULL) continue;
7984
7985 /* We need to remove the sounds array */
7986 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7987 free(ind->random_sounds);
7988 }
7989
7990 /* We need to remove the tiles layouts */
7991 CleanIndustryTileTable(ind);
7992
7993 free(ind);
7994 }
7995
7996 free(industryspec);
7997 industryspec = NULL;
7998 }
7999
8000 if (indtspec == NULL) continue;
8001 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8002 free(indtspec[i]);
8003 }
8004
8005 free(indtspec);
8006 indtspec = NULL;
8007 }
8008 }
8009
8011 static void ResetCustomObjects()
8012 {
8013 const GRFFile * const *end = _grf_files.End();
8014 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8015 ObjectSpec **&objectspec = (*file)->objectspec;
8016 if (objectspec == NULL) continue;
8017 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8018 free(objectspec[i]);
8019 }
8020
8021 free(objectspec);
8022 objectspec = NULL;
8023 }
8024 }
8025
8027 static void ResetNewGRF()
8028 {
8029 const GRFFile * const *end = _grf_files.End();
8030 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8031 delete *file;
8032 }
8033
8034 _grf_files.Clear();
8035 _cur.grffile = NULL;
8036 }
8037
8039 static void ResetNewGRFErrors()
8040 {
8041 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8042 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8043 delete c->error;
8044 c->error = NULL;
8045 }
8046 }
8047 }
8048
8053 void ResetNewGRFData()
8054 {
8055 CleanUpStrings();
8056 CleanUpGRFTownNames();
8057
8058 /* Copy/reset original engine info data */
8059 SetupEngines();
8060
8061 /* Copy/reset original bridge info data */
8062 ResetBridges();
8063
8064 /* Reset rail type information */
8065 ResetRailTypes();
8066
8067 /* Allocate temporary refit/cargo class data */
8068 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8069
8070 /* Fill rail type label temporary data for default trains */
8071 Engine *e;
8072 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8073 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8074 }
8075
8076 /* Reset GRM reservations */
8077 memset(&_grm_engines, 0, sizeof(_grm_engines));
8078 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8079
8080 /* Reset generic feature callback lists */
8081 ResetGenericCallbacks();
8082
8083 /* Reset price base data */
8084 ResetPriceBaseMultipliers();
8085
8086 /* Reset the curencies array */
8087 ResetCurrencies();
8088
8089 /* Reset the house array */
8090 ResetCustomHouses();
8091 ResetHouses();
8092
8093 /* Reset the industries structures*/
8094 ResetCustomIndustries();
8095 ResetIndustries();
8096
8097 /* Reset the objects. */
8098 ObjectClass::Reset();
8099 ResetCustomObjects();
8100 ResetObjects();
8101
8102 /* Reset station classes */
8103 StationClass::Reset();
8104 ResetCustomStations();
8105
8106 /* Reset airport-related structures */
8107 AirportClass::Reset();
8108 ResetCustomAirports();
8109 AirportSpec::ResetAirports();
8110 AirportTileSpec::ResetAirportTiles();
8111
8112 /* Reset canal sprite groups and flags */
8113 memset(_water_feature, 0, sizeof(_water_feature));
8114
8115 /* Reset the snowline table. */
8116 ClearSnowLine();
8117
8118 /* Reset NewGRF files */
8119 ResetNewGRF();
8120
8121 /* Reset NewGRF errors. */
8122 ResetNewGRFErrors();
8123
8124 /* Set up the default cargo types */
8125 SetupCargoForClimate(_settings_game.game_creation.landscape);
8126
8127 /* Reset misc GRF features and train list display variables */
8128 _misc_grf_features = 0;
8129
8130 _loaded_newgrf_features.has_2CC = false;
8131 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8132 _loaded_newgrf_features.has_newhouses = false;
8133 _loaded_newgrf_features.has_newindustries = false;
8134 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8135
8136 /* Clear all GRF overrides */
8137 _grf_id_overrides.clear();
8138
8139 InitializeSoundPool();
8140 _spritegroup_pool.CleanPool();
8141 }
8142
8146 void ResetPersistentNewGRFData()
8147 {
8148 /* Reset override managers */
8149 _engine_mngr.ResetToDefaultMapping();
8150 _house_mngr.ResetMapping();
8151 _industry_mngr.ResetMapping();
8152 _industile_mngr.ResetMapping();
8153 _airport_mngr.ResetMapping();
8154 _airporttile_mngr.ResetMapping();
8155 }
8156
8161 static void BuildCargoTranslationMap()
8162 {
8163 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8164
8165 for (CargoID c = 0; c < NUM_CARGO; c++) {
8166 const CargoSpec *cs = CargoSpec::Get(c);
8167 if (!cs->IsValid()) continue;
8168
8169 if (_cur.grffile->cargo_list.Length() == 0) {
8170 /* Default translation table, so just a straight mapping to bitnum */
8171 _cur.grffile->cargo_map[c] = cs->bitnum;
8172 } else {
8173 /* Check the translation table for this cargo's label */
8174 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8175 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8176 }
8177 }
8178 }
8179
8184 static void InitNewGRFFile(const GRFConfig *config)
8185 {
8186 GRFFile *newfile = GetFileByFilename(config->filename);
8187 if (newfile != NULL) {
8188 /* We already loaded it once. */
8189 _cur.grffile = newfile;
8190 return;
8191 }
8192
8193 newfile = new GRFFile(config);
8194 *_grf_files.Append() = _cur.grffile = newfile;
8195 }
8196
8201 GRFFile::GRFFile(const GRFConfig *config)
8202 {
8203 this->filename = stredup(config->filename);
8204 this->grfid = config->ident.grfid;
8205
8206 /* Initialise local settings to defaults */
8207 this->traininfo_vehicle_pitch = 0;
8208 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8209
8210 /* Mark price_base_multipliers as 'not set' */
8211 for (Price i = PR_BEGIN; i < PR_END; i++) {
8212 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8213 }
8214
8215 /* Initialise rail type map with default rail types */
8216 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8217 this->railtype_map[0] = RAILTYPE_RAIL;
8218 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8219 this->railtype_map[2] = RAILTYPE_MONO;
8220 this->railtype_map[3] = RAILTYPE_MAGLEV;
8221
8222 /* Copy the initial parameter list
8223 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8224 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8225
8226 assert(config->num_params <= lengthof(config->param));
8227 this->param_end = config->num_params;
8228 if (this->param_end > 0) {
8229 MemCpyT(this->param, config->param, this->param_end);
8230 }
8231 }
8232
8233 GRFFile::~GRFFile()
8234 {
8235 free(this->filename);
8236 delete[] this->language_map;
8237 }
8238
8239
8244 static const CargoLabel _default_refitmasks_rail[] = {
8245 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8246 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8247 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8248 'PLST', 'FZDR',
8249 0 };
8250
8251 static const CargoLabel _default_refitmasks_road[] = {
8252 0 };
8253
8254 static const CargoLabel _default_refitmasks_ships[] = {
8255 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8256 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8257 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8258 'PLST', 'FZDR',
8259 0 };
8260
8261 static const CargoLabel _default_refitmasks_aircraft[] = {
8262 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8263 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8264 0 };
8265
8266 static const CargoLabel * const _default_refitmasks[] = {
8267 _default_refitmasks_rail,
8268 _default_refitmasks_road,
8269 _default_refitmasks_ships,
8270 _default_refitmasks_aircraft,
8271 };
8272
8273
8277 static void CalculateRefitMasks()
8278 {
8279 Engine *e;
8280
8281 FOR_ALL_ENGINES(e) {
8282 EngineID engine = e->index;
8283 EngineInfo *ei = &e->info;
8284 bool only_defaultcargo;
8285
8286 /* Did the newgrf specify any refitting? If not, use defaults. */
8287 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8288 uint32 mask = 0;
8289 uint32 not_mask = 0;
8290 uint32 xor_mask = ei->refit_mask;
8291
8292 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8293 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8294 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8295
8296 if (_gted[engine].cargo_allowed != 0) {
8297 /* Build up the list of cargo types from the set cargo classes. */
8298 const CargoSpec *cs;
8299 FOR_ALL_CARGOSPECS(cs) {
8300 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8301 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8302 }
8303 }
8304
8305 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8306
8307 /* Apply explicit refit includes/excludes. */
8308 ei->refit_mask |= _gted[engine].ctt_include_mask;
8309 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8310 } else {
8311 uint32 xor_mask = 0;
8312
8313 /* Don't apply default refit mask to wagons nor engines with no capacity */
8314 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8315 const CargoLabel *cl = _default_refitmasks[e->type];
8316 for (uint i = 0;; i++) {
8317 if (cl[i] == 0) break;
8318
8319 CargoID cargo = GetCargoIDByLabel(cl[i]);
8320 if (cargo == CT_INVALID) continue;
8321
8322 SetBit(xor_mask, cargo);
8323 }
8324 }
8325
8326 ei->refit_mask = xor_mask & _cargo_mask;
8327
8328 /* If the mask is zero, the vehicle shall only carry the default cargo */
8329 only_defaultcargo = (ei->refit_mask == 0);
8330 }
8331
8332 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8333 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8334
8335 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8336 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8337 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8338 ei->cargo_type = CT_INVALID;
8339 }
8340
8341 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8342 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8343 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8344 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8345 const uint8 *cargo_map_for_first_refittable = NULL;
8346 {
8347 const GRFFile *file = _gted[engine].defaultcargo_grf;
8348 if (file == NULL) file = e->GetGRF();
8349 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8350 cargo_map_for_first_refittable = file->cargo_map;
8351 }
8352 }
8353
8354 if (cargo_map_for_first_refittable != NULL) {
8355 /* Use first refittable cargo from cargo translation table */
8356 byte best_local_slot = 0xFF;
8357 CargoID cargo_type;
8358 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8359 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8360 if (local_slot < best_local_slot) {
8361 best_local_slot = local_slot;
8362 ei->cargo_type = cargo_type;
8363 }
8364 }
8365 }
8366
8367 if (ei->cargo_type == CT_INVALID) {
8368 /* Use first refittable cargo slot */
8369 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8370 }
8371 }
8372 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8373
8374 /* Clear refit_mask for not refittable ships */
8375 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8376 ei->refit_mask = 0;
8377 }
8378 }
8379 }
8380
8382 static void FinaliseCanals()
8383 {
8384 for (uint i = 0; i < CF_END; i++) {
8385 if (_water_feature[i].grffile != NULL) {
8386 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8387 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8388 }
8389 }
8390 }
8391
8393 static void FinaliseEngineArray()
8394 {
8395 Engine *e;
8396
8397 FOR_ALL_ENGINES(e) {
8398 if (e->GetGRF() == NULL) {
8399 const EngineIDMapping &eid = _engine_mngr[e->index];
8400 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8401 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8402 }
8403 }
8404
8405 /* When the train does not set property 27 (misc flags), but it
8406 * is overridden by a NewGRF graphically we want to disable the
8407 * flipping possibility. */
8408 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8409 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8410 }
8411
8412 /* Skip wagons, there livery is defined via the engine */
8413 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8414 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8415 SetBit(_loaded_newgrf_features.used_liveries, ls);
8416 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8417
8418 if (e->type == VEH_TRAIN) {
8419 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8420 switch (ls) {
8421 case LS_STEAM:
8422 case LS_DIESEL:
8423 case LS_ELECTRIC:
8424 case LS_MONORAIL:
8425 case LS_MAGLEV:
8426 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8427 break;
8428
8429 case LS_DMU:
8430 case LS_EMU:
8431 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8432 break;
8433
8434 default: NOT_REACHED();
8435 }
8436 }
8437 }
8438 }
8439 }
8440
8442 static void FinaliseCargoArray()
8443 {
8444 for (CargoID c = 0; c < NUM_CARGO; c++) {
8445 CargoSpec *cs = CargoSpec::Get(c);
8446 if (!cs->IsValid()) {
8447 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8448 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8449 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8450 }
8451 }
8452 }
8453
8465 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8466 {
8467 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8468 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8469 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8470 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8471 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8472 hs->enabled = false;
8473 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);
8474 return false;
8475 }
8476
8477 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8478 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8479 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8480 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8481 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8482 hs->enabled = false;
8483 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);
8484 return false;
8485 }
8486
8487 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8488 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8489 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8490 hs->enabled = false;
8491 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);
8492 return false;
8493 }
8494
8495 /* Make sure that additional parts of multitile houses are not available. */
8496 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8497 hs->enabled = false;
8498 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);
8499 return false;
8500 }
8501
8502 return true;
8503 }
8504
8511 static void EnsureEarlyHouse(HouseZones bitmask)
8512 {
8513 Year min_year = MAX_YEAR;
8514
8515 for (int i = 0; i < NUM_HOUSES; i++) {
8516 HouseSpec *hs = HouseSpec::Get(i);
8517 if (hs == NULL || !hs->enabled) continue;
8518 if ((hs->building_availability & bitmask) != bitmask) continue;
8519 if (hs->min_year < min_year) min_year = hs->min_year;
8520 }
8521
8522 if (min_year == 0) return;
8523
8524 for (int i = 0; i < NUM_HOUSES; i++) {
8525 HouseSpec *hs = HouseSpec::Get(i);
8526 if (hs == NULL || !hs->enabled) continue;
8527 if ((hs->building_availability & bitmask) != bitmask) continue;
8528 if (hs->min_year == min_year) hs->min_year = 0;
8529 }
8530 }
8531
8538 static void FinaliseHouseArray()
8539 {
8540 /* If there are no houses with start dates before 1930, then all houses
8541 * with start dates of 1930 have them reset to 0. This is in order to be
8542 * compatible with TTDPatch, where if no houses have start dates before
8543 * 1930 and the date is before 1930, the game pretends that this is 1930.
8544 * If there have been any houses defined with start dates before 1930 then
8545 * the dates are left alone.
8546 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8547 * minimum introduction date to 0.
8548 */
8549 const GRFFile * const *end = _grf_files.End();
8550 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8551 HouseSpec **&housespec = (*file)->housespec;
8552 if (housespec == NULL) continue;
8553
8554 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8555 HouseSpec *hs = housespec[i];
8556
8557 if (hs == NULL) continue;
8558
8559 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8560 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8561 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8562
8563 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8564
8565 _house_mngr.SetEntitySpec(hs);
8566 }
8567 }
8568
8569 for (int i = 0; i < NUM_HOUSES; i++) {
8570 HouseSpec *hs = HouseSpec::Get(i);
8571 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8572 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8573 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8574
8575 /* We need to check all houses again to we are sure that multitile houses
8576 * did get consecutive IDs and none of the parts are missing. */
8577 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8578 /* GetHouseNorthPart checks 3 houses that are directly before
8579 * it in the house pool. If any of those houses have multi-tile
8580 * flags set it assumes it's part of a multitile house. Since
8581 * we can have invalid houses in the pool marked as disabled, we
8582 * don't want to have them influencing valid tiles. As such set
8583 * building_flags to zero here to make sure any house following
8584 * this one in the pool is properly handled as 1x1 house. */
8585 hs->building_flags = TILE_NO_FLAG;
8586 }
8587 }
8588
8589 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8590 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8591 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8592 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8593 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8594 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8595
8596 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8597 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8598 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8599 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8600 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8601 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8602 }
8603 }
8604
8610 static void FinaliseIndustriesArray()
8611 {
8612 const GRFFile * const *end = _grf_files.End();
8613 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8614 IndustrySpec **&industryspec = (*file)->industryspec;
8615 IndustryTileSpec **&indtspec = (*file)->indtspec;
8616 if (industryspec != NULL) {
8617 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8618 IndustrySpec *indsp = industryspec[i];
8619
8620 if (indsp != NULL && indsp->enabled) {
8621 StringID strid;
8622 /* process the conversion of text at the end, so to be sure everything will be fine
8623 * and available. Check if it does not return undefind marker, which is a very good sign of a
8624 * substitute industry who has not changed the string been examined, thus using it as such */
8625 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8626 if (strid != STR_UNDEFINED) indsp->name = strid;
8627
8628 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8629 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8630
8631 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8632 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8633
8634 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8635 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8636
8637 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8638 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8639
8640 if (indsp->station_name != STR_NULL) {
8641 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8642 * station's name. Don't want to lose the value, therefore, do not process. */
8643 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8644 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8645 }
8646
8647 _industry_mngr.SetEntitySpec(indsp);
8648 _loaded_newgrf_features.has_newindustries = true;
8649 }
8650 }
8651 }
8652
8653 if (indtspec != NULL) {
8654 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8655 IndustryTileSpec *indtsp = indtspec[i];
8656 if (indtsp != NULL) {
8657 _industile_mngr.SetEntitySpec(indtsp);
8658 }
8659 }
8660 }
8661 }
8662
8663 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8664 IndustrySpec *indsp = &_industry_specs[j];
8665 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8666 for (uint i = 0; i < 3; i++) {
8667 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8668 }
8669 }
8670 if (!indsp->enabled) {
8671 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8672 }
8673 }
8674 }
8675
8681 static void FinaliseObjectsArray()
8682 {
8683 const GRFFile * const *end = _grf_files.End();
8684 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8685 ObjectSpec **&objectspec = (*file)->objectspec;
8686 if (objectspec != NULL) {
8687 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8688 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8689 _object_mngr.SetEntitySpec(objectspec[i]);
8690 }
8691 }
8692 }
8693 }
8694 }
8695
8701 static void FinaliseAirportsArray()
8702 {
8703 const GRFFile * const *end = _grf_files.End();
8704 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8705 AirportSpec **&airportspec = (*file)->airportspec;
8706 if (airportspec != NULL) {
8707 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8708 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8709 _airport_mngr.SetEntitySpec(airportspec[i]);
8710 }
8711 }
8712 }
8713
8714 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8715 if (airporttilespec != NULL) {
8716 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8717 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8718 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8719 }
8720 }
8721 }
8722 }
8723 }
8724
8725 /* Here we perform initial decoding of some special sprites (as are they
8726 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8727 * partial implementation yet).
8728 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8729 * a crafted invalid GRF file. We should tell that to the user somehow, or
8730 * better make this more robust in the future. */
8731 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8732 {
8733 /* XXX: There is a difference between staged loading in TTDPatch and
8734 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8735 * during stage 1, whilst action 3 is carried out during stage 2 (to
8736 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8737 * IDs are valid only within a given set (action 1) block, and may be
8738 * overwritten after action 3 associates them. But overwriting happens
8739 * in an earlier stage than associating, so... We just process actions
8740 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8741 * --pasky
8742 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8743 * is not in memory and scanning the file every time would be too expensive.
8744 * In other stages we skip action 0x10 since it's already dealt with. */
8745 static const SpecialSpriteHandler handlers[][GLS_END] = {
8746 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8747 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8748 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8749 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8750 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8751 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8752 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8753 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8754 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8755 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8756 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8757 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8758 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8759 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8760 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8761 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8762 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8763 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8764 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8765 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8766 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8767 };
8768
8769 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8770
8771 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8772 if (it == _grf_line_to_action6_sprite_override.end()) {
8773 /* No preloaded sprite to work with; read the
8774 * pseudo sprite content. */
8775 FioReadBlock(buf, num);
8776 } else {
8777 /* Use the preloaded sprite data. */
8778 buf = _grf_line_to_action6_sprite_override[location];
8779 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8780
8781 /* Skip the real (original) content of this action. */
8782 FioSeekTo(num, SEEK_CUR);
8783 }
8784
8785 ByteReader br(buf, buf + num);
8786 ByteReader *bufp = &br;
8787
8788 try {
8789 byte action = bufp->ReadByte();
8790
8791 if (action == 0xFF) {
8792 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8793 } else if (action == 0xFE) {
8794 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8795 } else if (action >= lengthof(handlers)) {
8796 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8797 } else if (handlers[action][stage] == NULL) {
8798 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8799 } else {
8800 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8801 handlers[action][stage](bufp);
8802 }
8803 } catch (...) {
8804 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8805 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8806 }
8807 }
8808
8809
8811 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8812
8817 byte GetGRFContainerVersion()
8818 {
8819 size_t pos = FioGetPos();
8820
8821 if (FioReadWord() == 0) {
8822 /* Check for GRF container version 2, which is identified by the bytes
8823 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8824 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8825 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8826 }
8827
8828 return 2;
8829 }
8830
8831 /* Container version 1 has no header, rewind to start. */
8832 FioSeekTo(pos, SEEK_SET);
8833 return 1;
8834 }
8835
8843 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8844 {
8845 const char *filename = config->filename;
8846
8847 /* A .grf file is activated only if it was active when the game was
8848 * started. If a game is loaded, only its active .grfs will be
8849 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8850 * considered active if its action 8 has been processed, i.e. its
8851 * action 8 hasn't been skipped using an action 7.
8852 *
8853 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8854 * carried out. All others are ignored, because they only need to be
8855 * processed once at initialization. */
8856 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8857 _cur.grffile = GetFileByFilename(filename);
8858 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8859 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8860 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8861 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
8862 }
8863
8864 if (file_index > LAST_GRF_SLOT) {
8865 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
8866 config->status = GCS_DISABLED;
8867 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8868 return;
8869 }
8870
8871 FioOpenFile(file_index, filename, subdir);
8872 _cur.file_index = file_index; // XXX
8873 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8874
8875 _cur.grfconfig = config;
8876
8877 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8878
8879 _cur.grf_container_ver = GetGRFContainerVersion();
8880 if (_cur.grf_container_ver == 0) {
8881 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8882 return;
8883 }
8884
8885 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8886 /* We need the sprite offsets in the init stage for NewGRF sounds
8887 * and in the activation stage for real sprites. */
8888 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8889 } else {
8890 /* Skip sprite section offset if present. */
8891 if (_cur.grf_container_ver >= 2) FioReadDword();
8892 }
8893
8894 if (_cur.grf_container_ver >= 2) {
8895 /* Read compression value. */
8896 byte compression = FioReadByte();
8897 if (compression != 0) {
8898 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8899 return;
8900 }
8901 }
8902
8903 /* Skip the first sprite; we don't care about how many sprites this
8904 * does contain; newest TTDPatches and George's longvehicles don't
8905 * neither, apparently. */
8906 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8907 if (num == 4 && FioReadByte() == 0xFF) {
8908 FioReadDword();
8909 } else {
8910 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8911 return;
8912 }
8913
8914 _cur.ClearDataForNextFile();
8915
8916 ReusableBuffer<byte> buf;
8917
8918 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8919 byte type = FioReadByte();
8920 _cur.nfo_line++;
8921
8922 if (type == 0xFF) {
8923 if (_cur.skip_sprites == 0) {
8924 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8925
8926 /* Stop all processing if we are to skip the remaining sprites */
8927 if (_cur.skip_sprites == -1) break;
8928
8929 continue;
8930 } else {
8931 FioSkipBytes(num);
8932 }
8933 } else {
8934 if (_cur.skip_sprites == 0) {
8935 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8936 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8937 break;
8938 }
8939
8940 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8941 /* Reference to data section. Container version >= 2 only. */
8942 FioSkipBytes(num);
8943 } else {
8944 FioSkipBytes(7);
8945 SkipSpriteData(type, num - 8);
8946 }
8947 }
8948
8949 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8950 }
8951 }
8952
8960 static void ActivateOldShore()
8961 {
8962 /* Use default graphics, if no shore sprites were loaded.
8963 * Should not happen, as the base set's extra grf should include some. */
8964 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8965
8966 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8967 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8968 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8969 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8970 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8971 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8972 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8973 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8974 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8975 }
8976
8977 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8978 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8979 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8980 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8981 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8982 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8983 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
8984 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
8985 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
8986
8987 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8988 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8989 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
8990 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
8991 }
8992 }
8993
8997 static void FinalisePriceBaseMultipliers()
8998 {
8999 extern const PriceBaseSpec _price_base_specs[];
9001 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9002
9003 /* Evaluate grf overrides */
9004 int num_grfs = _grf_files.Length();
9005 int *grf_overrides = AllocaM(int, num_grfs);
9006 for (int i = 0; i < num_grfs; i++) {
9007 grf_overrides[i] = -1;
9008
9009 GRFFile *source = _grf_files[i];
9010 uint32 override = _grf_id_overrides[source->grfid];
9011 if (override == 0) continue;
9012
9013 GRFFile *dest = GetFileByGRFID(override);
9014 if (dest == NULL) continue;
9015
9016 grf_overrides[i] = _grf_files.FindIndex(dest);
9017 assert(grf_overrides[i] >= 0);
9018 }
9019
9020 /* Override features and price base multipliers of earlier loaded grfs */
9021 for (int i = 0; i < num_grfs; i++) {
9022 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9023 GRFFile *source = _grf_files[i];
9024 GRFFile *dest = _grf_files[grf_overrides[i]];
9025
9026 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9027 source->grf_features |= features;
9028 dest->grf_features |= features;
9029
9030 for (Price p = PR_BEGIN; p < PR_END; p++) {
9031 /* No price defined -> nothing to do */
9032 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9033 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9034 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9035 }
9036 }
9037
9038 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9039 for (int i = num_grfs - 1; i >= 0; i--) {
9040 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9041 GRFFile *source = _grf_files[i];
9042 GRFFile *dest = _grf_files[grf_overrides[i]];
9043
9044 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9045 source->grf_features |= features;
9046 dest->grf_features |= features;
9047
9048 for (Price p = PR_BEGIN; p < PR_END; p++) {
9049 /* Already a price defined -> nothing to do */
9050 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9051 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9052 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9053 }
9054 }
9055
9056 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9057 for (int i = 0; i < num_grfs; i++) {
9058 if (grf_overrides[i] < 0) continue;
9059 GRFFile *source = _grf_files[i];
9060 GRFFile *dest = _grf_files[grf_overrides[i]];
9061
9062 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9063 source->grf_features |= features;
9064 dest->grf_features |= features;
9065
9066 for (Price p = PR_BEGIN; p < PR_END; p++) {
9067 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9068 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9069 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9070 }
9071 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9072 }
9073 }
9074
9075 /* Apply fallback prices for grf version < 8 */
9076 const GRFFile * const *end = _grf_files.End();
9077 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9078 if ((*file)->grf_version >= 8) continue;
9079 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9080 for (Price p = PR_BEGIN; p < PR_END; p++) {
9081 Price fallback_price = _price_base_specs[p].fallback_price;
9082 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9083 /* No price multiplier has been set.
9084 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9085 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9086 }
9087 }
9088 }
9089
9090 /* Decide local/global scope of price base multipliers */
9091 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9092 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9093 for (Price p = PR_BEGIN; p < PR_END; p++) {
9094 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9095 /* No multiplier was set; set it to a neutral value */
9096 price_base_multipliers[p] = 0;
9097 } else {
9098 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9099 /* The grf does not define any objects of the feature,
9100 * so it must be a difficulty setting. Apply it globally */
9101 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9102 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9103 price_base_multipliers[p] = 0;
9104 } else {
9105 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9106 }
9107 }
9108 }
9109 }
9110 }
9111
9112 extern void InitGRFTownGeneratorNames();
9113
9115 static void AfterLoadGRFs()
9116 {
9117 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9118 *it->target = MapGRFStringID(it->grfid, it->source);
9119 }
9120 _string_to_grf_mapping.Clear();
9121
9122 /* Free the action 6 override sprites. */
9123 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9124 free((*it).second);
9125 }
9126 _grf_line_to_action6_sprite_override.clear();
9127
9128 /* Polish cargoes */
9129 FinaliseCargoArray();
9130
9131 /* Pre-calculate all refit masks after loading GRF files. */
9132 CalculateRefitMasks();
9133
9134 /* Polish engines */
9135 FinaliseEngineArray();
9136
9137 /* Set the actually used Canal properties */
9138 FinaliseCanals();
9139
9140 /* Add all new houses to the house array. */
9141 FinaliseHouseArray();
9142
9143 /* Add all new industries to the industry array. */
9144 FinaliseIndustriesArray();
9145
9146 /* Add all new objects to the object array. */
9147 FinaliseObjectsArray();
9148
9149 InitializeSortedCargoSpecs();
9150
9151 /* Sort the list of industry types. */
9152 SortIndustryTypes();
9153
9154 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9155 BuildIndustriesLegend();
9156
9157 /* Build the routemap legend, based on the available cargos */
9158 BuildLinkStatsLegend();
9159
9160 /* Add all new airports to the airports array. */
9161 FinaliseAirportsArray();
9162 BindAirportSpecs();
9163
9164 /* Update the townname generators list */
9165 InitGRFTownGeneratorNames();
9166
9167 /* Run all queued vehicle list order changes */
9168 CommitVehicleListOrderChanges();
9169
9170 /* Load old shore sprites in new position, if they were replaced by ActionA */
9171 ActivateOldShore();
9172
9173 /* Set up custom rail types */
9174 InitRailTypes();
9175
9176 Engine *e;
9177 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9178 if (_gted[e->index].rv_max_speed != 0) {
9179 /* Set RV maximum speed from the mph/0.8 unit value */
9180 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9181 }
9182 }
9183
9184 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9185 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9186 if (railtype == INVALID_RAILTYPE) {
9187 /* Rail type is not available, so disable this engine */
9188 e->info.climates = 0;
9189 } else {
9190 e->u.rail.railtype = railtype;
9191 }
9192 }
9193
9194 SetYearEngineAgingStops();
9195
9196 FinalisePriceBaseMultipliers();
9197
9198 /* Deallocate temporary loading data */
9199 free(_gted);
9200 _grm_sprites.clear();
9201 }
9202
9208 void LoadNewGRF(uint load_index, uint file_index)
9209 {
9210 /* In case of networking we need to "sync" the start values
9211 * so all NewGRFs are loaded equally. For this we use the
9212 * start date of the game and we set the counters, etc. to
9213 * 0 so they're the same too. */
9214 Date date = _date;
9215 Year year = _cur_year;
9216 DateFract date_fract = _date_fract;
9217 uint16 tick_counter = _tick_counter;
9218 byte display_opt = _display_opt;
9219
9220 if (_networking) {
9221 _cur_year = _settings_game.game_creation.starting_year;
9222 _date = ConvertYMDToDate(_cur_year, 0, 1);
9223 _date_fract = 0;
9224 _tick_counter = 0;
9225 _display_opt = 0;
9226 }
9227
9228 InitializeGRFSpecial();
9229
9230 ResetNewGRFData();
9231
9232 /*
9233 * Reset the status of all files, so we can 'retry' to load them.
9234 * This is needed when one for example rearranges the NewGRFs in-game
9235 * and a previously disabled NewGRF becomes useable. If it would not
9236 * be reset, the NewGRF would remain disabled even though it should
9237 * have been enabled.
9238 */
9239 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9240 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9241 }
9242
9243 _cur.spriteid = load_index;
9244
9245 /* Load newgrf sprites
9246 * in each loading stage, (try to) open each file specified in the config
9247 * and load information from it. */
9248 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9249 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9250 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9251 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9252 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9253 }
9254
9255 if (stage == GLS_RESERVE) {
9256 static const uint32 overrides[][2] = {
9257 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9258 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9259 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9260 };
9261 for (size_t i = 0; i < lengthof(overrides); i++) {
9262 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9263 }
9264 }
9265
9266 uint slot = file_index;
9267
9268 _cur.stage = stage;
9269 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9270 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9271 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9272
9273 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
9274 if (!FioCheckFileExists(c->filename, subdir)) {
9275 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9276 c->status = GCS_NOT_FOUND;
9277 continue;
9278 }
9279
9280 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9281 LoadNewGRFFile(c, slot++, stage, subdir);
9282 if (stage == GLS_RESERVE) {
9283 SetBit(c->flags, GCF_RESERVED);
9284 } else if (stage == GLS_ACTIVATION) {
9285 ClrBit(c->flags, GCF_RESERVED);
9286 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9287 ClearTemporaryNewGRFData(_cur.grffile);
9288 BuildCargoTranslationMap();
9289 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9290 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9291 /* We're not going to activate this, so free whatever data we allocated */
9292 ClearTemporaryNewGRFData(_cur.grffile);
9293 }
9294 }
9295 }
9296
9297 /* Pseudo sprite processing is finished; free temporary stuff */
9298 _cur.ClearDataForNextFile();
9299
9300 /* Call any functions that should be run after GRFs have been loaded. */
9301 AfterLoadGRFs();
9302
9303 /* Now revert back to the original situation */
9304 _cur_year = year;
9305 _date = date;
9306 _date_fract = date_fract;
9307 _tick_counter = tick_counter;
9308 _display_opt = display_opt;
9309 }