52 #include "table/strings.h"
69 const std::vector<GRFFile *> &GetAllGRFFiles()
118 this->skip_sprites = 0;
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
124 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.
sprite = first_sprite + i * numents;
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
179 return this->spritesets[feature].find(set)->second.sprite;
191 return this->spritesets[feature].find(set)->second.num_sprites;
204 template <VehicleType T>
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
219 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
221 inline byte *ReadBytes(
size_t size)
223 if (data + size >= end) {
234 inline byte ReadByte()
236 if (data < end)
return *(data)++;
242 uint16 val = ReadByte();
243 return val | (ReadByte() << 8);
246 uint16 ReadExtendedByte()
248 uint16 val = ReadByte();
249 return val == 0xFF ? ReadWord() : val;
254 uint32 val = ReadWord();
255 return val | (ReadWord() << 16);
258 uint32 ReadVarSize(
byte size)
261 case 1:
return ReadByte();
262 case 2:
return ReadWord();
263 case 4:
return ReadDWord();
270 const char *ReadString()
272 char *
string =
reinterpret_cast<char *
>(data);
273 size_t string_length =
ttd_strnlen(
string, Remaining());
275 if (string_length == Remaining()) {
277 string[string_length - 1] =
'\0';
278 grfmsg(7,
"String was not terminated with a zero byte.");
288 inline size_t Remaining()
const
293 inline bool HasData(
size_t count = 1)
const
295 return data + count <= end;
303 inline void Skip(
size_t len)
312 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
325 uint16 cargo_allowed;
326 uint16 cargo_disallowed;
327 RailTypeLabel railtypelabel;
344 }
else if (this->refittability ==
UNSET) {
345 this->refittability =
EMPTY;
365 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
369 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
374 return this->grfid == other.grfid && this->nfoline == other.nfoline;
378 static std::map<GRFLocation, SpriteID> _grm_sprites;
379 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
380 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
392 void CDECL
grfmsg(
int severity,
const char *str, ...)
412 if (file->grfid == grfid)
return file;
425 if (strcmp(file->filename, filename) == 0)
return file;
451 if (config !=
nullptr) {
462 if (message != STR_NULL) {
463 delete config->error;
464 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
468 return config->error;
479 typedef std::vector<StringIDMapping> StringIDMappingVector;
480 static StringIDMappingVector _string_to_grf_mapping;
489 *target = STR_UNDEFINED;
490 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
503 static const StringID units_volume[] = {
504 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
505 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
506 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
507 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
508 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
509 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
510 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
511 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
517 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
518 static_assert(stringend - stringid == end - begin); \
519 if (str >= begin && str <= end) return str + (stringid - begin)
522 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
523 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
524 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
525 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
526 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
527 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
532 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
533 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
534 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
537 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
538 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
539 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
540 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
541 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
544 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
545 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
546 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
548 #undef TEXTID_TO_STRINGID
550 if (str == STR_NULL)
return STR_EMPTY;
552 Debug(grf, 0,
"Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
591 static std::map<uint32, uint32> _grf_id_overrides;
600 _grf_id_overrides[source_grfid] = target_grfid;
601 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
616 uint32 scope_grfid = INVALID_GRFID;
619 scope_grfid = file->grfid;
620 uint32
override = _grf_id_overrides[file->grfid];
622 scope_grfid =
override;
624 if (grf_match ==
nullptr) {
625 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
632 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
641 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
647 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
651 if (!static_access) {
653 eid->
grfid = scope_grfid;
659 if (static_access)
return nullptr;
662 grfmsg(0,
"Can't allocate any more engines");
673 assert(_engine_mngr.size() == e->
index);
674 _engine_mngr.push_back({
687 memset(
_gted + engine_pool_size, 0, len);
693 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
710 uint32 scope_grfid = INVALID_GRFID;
712 scope_grfid = file->grfid;
713 uint32
override = _grf_id_overrides[file->grfid];
714 if (
override != 0) scope_grfid =
override;
717 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
757 grf_sprite->
sprite = buf->ReadWord();
758 grf_sprite->
pal = buf->ReadWord();
763 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
767 uint index =
GB(grf_sprite->
sprite, 0, 14);
769 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
770 grf_sprite->
sprite = SPR_IMG_QUERY;
771 grf_sprite->
pal = PAL_NONE;
774 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
779 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
780 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
786 uint index =
GB(grf_sprite->
pal, 0, 14);
788 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
789 grf_sprite->
pal = PAL_NONE;
792 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
797 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
798 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
827 regs.delta.
parent[0] = buf->ReadByte();
828 regs.delta.
parent[1] = buf->ReadByte();
840 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
849 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
868 bool has_flags =
HasBit(num_building_sprites, 6);
869 ClrBit(num_building_sprites, 6);
872 dts->
Allocate(num_building_sprites);
874 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
875 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
876 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
877 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
884 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
885 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
892 for (uint i = 0; i < num_building_sprites; i++) {
895 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
898 if (flags & ~valid_flags) {
899 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
900 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
904 seq->
delta_x = buf->ReadByte();
905 seq->delta_y = buf->ReadByte();
907 if (!no_z_position) seq->
delta_z = buf->ReadByte();
910 seq->size_x = buf->ReadByte();
911 seq->size_y = buf->ReadByte();
912 seq->size_z = buf->ReadByte();
920 bool is_consistent =
true;
922 for (uint i = 0; i < num_building_sprites + 1; i++) {
923 if (max_sprite_offset[i] > 0) {
927 is_consistent =
false;
931 if (max_palette_offset[i] > 0) {
935 is_consistent =
false;
944 if (!is_consistent || dts->registers !=
nullptr) {
948 for (uint i = 0; i < num_building_sprites + 1; i++) {
963 CargoTypes result = 0;
981 if (base_pointer == 0) {
982 *index = INVALID_PRICE;
986 static const uint32 start = 0x4B34;
987 static const uint32 size = 6;
989 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
990 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
994 *index = (
Price)((base_pointer - start) / size);
1023 ei->decay_speed = buf->ReadByte();
1040 ei->load_amount = buf->ReadByte();
1062 for (
int i = 0; i < numinfo; i++) {
1071 uint8 tracktype = buf->ReadByte();
1073 if (tracktype < _cur.grffile->railtype_list.size()) {
1078 switch (tracktype) {
1079 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1080 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1081 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1083 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1096 uint16 speed = buf->ReadWord();
1097 if (speed == 0xFFFF) speed = 0;
1104 rvi->
power = buf->ReadWord();
1107 if (rvi->
power != 0) {
1125 uint8 spriteid = buf->ReadByte();
1126 uint8 orig_spriteid = spriteid;
1130 if (spriteid < 0xFD) spriteid >>= 1;
1132 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1133 rvi->image_index = spriteid;
1135 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1136 rvi->image_index = 0;
1142 uint8 dual = buf->ReadByte();
1147 rvi->railveh_type = rvi->
power == 0 ?
1159 uint8 ctype = buf->ReadByte();
1161 if (ctype == 0xFF) {
1164 }
else if (_cur.
grffile->grf_version >= 8) {
1169 ei->cargo_type = ctype;
1172 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1178 SB(rvi->
weight, 0, 8, buf->ReadByte());
1186 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1198 uint8 traction = buf->ReadByte();
1201 if (traction <= 0x07) {
1203 }
else if (traction <= 0x27) {
1205 }
else if (traction <= 0x31) {
1207 }
else if (traction <= 0x37) {
1209 }
else if (traction <= 0x41) {
1235 ei->refit_cost = buf->ReadByte();
1239 uint32 mask = buf->ReadDWord();
1277 byte weight = buf->ReadByte();
1280 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1302 _gted[e->
index].cargo_allowed = buf->ReadWord();
1308 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1322 uint8 count = buf->ReadByte();
1360 for (
int i = 0; i < numinfo; i++) {
1371 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1379 rvi->running_cost = buf->ReadByte();
1387 uint8 spriteid = buf->ReadByte();
1388 uint8 orig_spriteid = spriteid;
1391 if (spriteid == 0xFF) spriteid = 0xFD;
1393 if (spriteid < 0xFD) spriteid >>= 1;
1395 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1396 rvi->image_index = spriteid;
1398 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1399 rvi->image_index = 0;
1405 rvi->capacity = buf->ReadByte();
1410 uint8 ctype = buf->ReadByte();
1412 if (ctype == 0xFF) {
1415 }
else if (_cur.
grffile->grf_version >= 8) {
1420 ei->cargo_type = ctype;
1423 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1429 rvi->cost_factor = buf->ReadByte();
1437 rvi->
power = buf->ReadByte();
1441 rvi->
weight = buf->ReadByte();
1449 uint32 mask = buf->ReadDWord();
1469 ei->refit_cost = buf->ReadByte();
1482 _gted[e->
index].cargo_allowed = buf->ReadWord();
1488 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1520 uint8 count = buf->ReadByte();
1554 for (
int i = 0; i < numinfo; i++) {
1563 uint8 spriteid = buf->ReadByte();
1564 uint8 orig_spriteid = spriteid;
1567 if (spriteid == 0xFF) spriteid = 0xFD;
1569 if (spriteid < 0xFD) spriteid >>= 1;
1571 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1572 svi->image_index = spriteid;
1574 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1575 svi->image_index = 0;
1585 svi->cost_factor = buf->ReadByte();
1594 uint8 ctype = buf->ReadByte();
1596 if (ctype == 0xFF) {
1599 }
else if (_cur.
grffile->grf_version >= 8) {
1604 ei->cargo_type = ctype;
1607 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1613 svi->capacity = buf->ReadWord();
1617 svi->running_cost = buf->ReadByte();
1625 uint32 mask = buf->ReadDWord();
1637 ei->refit_cost = buf->ReadByte();
1658 _gted[e->
index].cargo_allowed = buf->ReadWord();
1664 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1692 uint8 count = buf->ReadByte();
1726 for (
int i = 0; i < numinfo; i++) {
1735 uint8 spriteid = buf->ReadByte();
1736 uint8 orig_spriteid = spriteid;
1739 if (spriteid == 0xFF) spriteid = 0xFD;
1741 if (spriteid < 0xFD) spriteid >>= 1;
1743 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1744 avi->image_index = spriteid;
1746 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1747 avi->image_index = 0;
1753 if (buf->ReadByte() == 0) {
1761 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1765 avi->cost_factor = buf->ReadByte();
1769 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1773 avi->acceleration = buf->ReadByte();
1777 avi->running_cost = buf->ReadByte();
1793 uint32 mask = buf->ReadDWord();
1805 ei->refit_cost = buf->ReadByte();
1818 _gted[e->
index].cargo_allowed = buf->ReadWord();
1824 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1842 uint8 count = buf->ReadByte();
1888 for (
int i = 0; i < numinfo; i++) {
1892 if (statspec ==
nullptr && prop != 0x08) {
1893 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1905 uint32 classid = buf->ReadDWord();
1906 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1911 uint16 tiles = buf->ReadExtendedByte();
1915 for (uint t = 0; t < tiles; t++) {
1919 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1922 dts->
Clone(&_station_display_datas_rail[t % 8]);
1930 static std::vector<DrawTileSeqStruct> tmp_layout;
1937 dtss.
delta_x = buf->ReadByte();
1939 dtss.delta_y = buf->ReadByte();
1940 dtss.
delta_z = buf->ReadByte();
1941 dtss.size_x = buf->ReadByte();
1942 dtss.size_y = buf->ReadByte();
1943 dtss.size_z = buf->ReadByte();
1949 dts->
Clone(tmp_layout.data());
1954 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
1961 byte srcid = buf->ReadByte();
1964 if (srcstatspec ==
nullptr) {
1965 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1972 for (
const auto &it : srcstatspec->
renderdata) {
1992 while (buf->HasData()) {
1993 byte length = buf->ReadByte();
1994 byte number = buf->ReadByte();
1996 if (length == 0 || number == 0)
break;
1998 if (statspec->
layouts.size() < length) statspec->
layouts.resize(length);
1999 if (statspec->
layouts[length - 1].size() < number) statspec->
layouts[length - 1].resize(number);
2001 const byte *layout = buf->ReadBytes(length * number);
2002 statspec->
layouts[length - 1][number - 1].assign(layout, layout + length * number);
2005 for (
auto &tile : statspec->
layouts[length - 1][number - 1]) {
2006 if ((tile & 6) != tile) {
2007 grfmsg(1,
"StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
2015 byte srcid = buf->ReadByte();
2018 if (srcstatspec ==
nullptr) {
2019 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2032 statspec->
pylons = buf->ReadByte();
2036 if (_cur.
grffile->grf_version >= 7) {
2044 statspec->
flags = buf->ReadByte();
2048 statspec->
wires = buf->ReadByte();
2052 statspec->
blocked = buf->ReadByte();
2056 statspec->animation.
frames = buf->ReadByte();
2057 statspec->animation.
status = buf->ReadByte();
2061 statspec->animation.
speed = buf->ReadByte();
2065 statspec->animation.
triggers = buf->ReadWord();
2069 uint16 tiles = buf->ReadExtendedByte();
2073 for (uint t = 0; t < tiles; t++) {
2075 uint num_building_sprites = buf->ReadByte();
2082 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
2109 if (
id + numinfo > CF_END) {
2110 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2114 for (
int i = 0; i < numinfo; i++) {
2123 cp->
flags = buf->ReadByte();
2148 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2152 for (
int i = 0; i < numinfo; i++) {
2158 byte year = buf->ReadByte();
2173 bridge->
price = buf->ReadByte();
2177 bridge->
speed = buf->ReadWord();
2181 byte tableid = buf->ReadByte();
2182 byte numtables = buf->ReadByte();
2189 for (; numtables-- != 0; tableid++) {
2191 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2192 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2197 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2200 for (
byte sprite = 0; sprite < 32; sprite++) {
2214 bridge->
flags = buf->ReadByte();
2223 if (newone != STR_UNDEFINED) bridge->
material = newone;
2230 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2235 bridge->
price = buf->ReadWord();
2292 for (uint j = 0; j < 4; j++) buf->ReadByte();
2296 byte count = buf->ReadByte();
2297 for (
byte j = 0; j < count; j++) buf->ReadByte();
2302 buf->Skip(buf->ReadByte() * 2);
2325 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2330 if (_cur.
grffile->housespec ==
nullptr) {
2334 for (
int i = 0; i < numinfo; i++) {
2337 if (prop != 0x08 && housespec ==
nullptr) {
2340 if (cir > ret) ret = cir;
2347 byte subs_id = buf->ReadByte();
2349 if (subs_id == 0xFF) {
2352 HouseSpec::Get(hid + i)->
enabled =
false;
2356 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2361 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2365 MemCpyT(housespec, HouseSpec::Get(subs_id));
2369 housespec->
grf_prop.subst_id = subs_id;
2391 uint16 years = buf->ReadWord();
2411 int8 goods = buf->ReadByte();
2447 byte override = buf->ReadByte();
2451 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2455 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2464 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2486 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2494 uint32 cargotypes = buf->ReadDWord();
2497 if (cargotypes == 0xFFFFFFFF)
break;
2499 for (uint j = 0; j < 3; j++) {
2501 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2519 byte count = buf->ReadByte();
2520 for (
byte j = 0; j < count; j++) {
2528 housespec->
min_year = buf->ReadWord();
2532 housespec->
max_year = buf->ReadWord();
2536 uint count = buf->ReadByte();
2539 error->param_value[1] = prop;
2588 template <
typename T>
2592 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2596 translation_table.clear();
2597 for (
int i = 0; i < numinfo; i++) {
2598 uint32 item = buf->ReadDWord();
2599 translation_table.push_back(
BSWAP32(item));
2614 for (
int i = 0; i < 4; i++) output[i] = reader->ReadByte();
2618 return std::string(output);
2651 for (
int i = 0; i < numinfo; i++) {
2654 int factor = buf->ReadByte();
2655 uint price = gvid + i;
2657 if (price < PR_END) {
2660 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2669 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2677 uint32 rate = buf->ReadDWord();
2685 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2692 uint16 options = buf->ReadWord();
2701 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2713 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2725 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2732 Year year_euro = buf->ReadWord();
2737 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2744 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2746 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2752 table[i][j] = buf->ReadByte();
2753 if (_cur.
grffile->grf_version >= 8) {
2756 if (table[i][j] >= 128) {
2778 uint curidx = gvid + i;
2780 if (lang ==
nullptr) {
2781 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2786 while (buf->ReadByte() != 0) {
2796 uint plural_form = buf->ReadByte();
2797 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2798 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2805 byte newgrf_id = buf->ReadByte();
2806 while (newgrf_id != 0) {
2807 const char *name = buf->ReadString();
2822 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2829 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2834 newgrf_id = buf->ReadByte();
2870 for (
int i = 0; i < numinfo; i++) {
2894 uint32 s = buf->ReadDWord();
2895 uint32 t = buf->ReadDWord();
2902 while (buf->ReadByte() != 0) {
2930 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2934 for (
int i = 0; i < numinfo; i++) {
2939 cs->
bitnum = buf->ReadByte();
2977 cs->
sprite = buf->ReadWord();
2981 cs->
weight = buf->ReadByte();
2985 cs->transit_days[0] = buf->ReadByte();
2989 cs->transit_days[1] = buf->ReadByte();
2997 cs->rating_colour = buf->ReadByte();
3001 cs->legend_colour = buf->ReadByte();
3009 cs->
classes = buf->ReadWord();
3013 cs->
label = buf->ReadDWord();
3018 uint8 substitute_type = buf->ReadByte();
3020 switch (substitute_type) {
3027 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3043 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3068 if (_cur.
grffile->sound_offset == 0) {
3069 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3074 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3078 for (
int i = 0; i < numinfo; i++) {
3083 sound->volume = buf->ReadByte();
3087 sound->priority = buf->ReadByte();
3091 SoundID orig_sound = buf->ReadByte();
3096 SoundEntry *old_sound = GetSound(orig_sound);
3099 *old_sound = *sound;
3141 buf->Skip(buf->ReadByte() * 2);
3169 if (_cur.
grffile->indtspec ==
nullptr) {
3173 for (
int i = 0; i < numinfo; i++) {
3176 if (prop != 0x08 && tsp ==
nullptr) {
3178 if (cir > ret) ret = cir;
3185 byte subs_id = buf->ReadByte();
3189 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3194 if (*tilespec ==
nullptr) {
3195 *tilespec = CallocT<IndustryTileSpec>(1);
3198 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3216 byte ovrid = buf->ReadByte();
3220 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3224 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3231 uint16 acctp = buf->ReadWord();
3263 byte num_cargoes = buf->ReadByte();
3266 error->param_value[1] = prop;
3270 if (i < num_cargoes) {
3337 byte num_table = buf->ReadByte();
3338 for (
byte j = 0; j < num_table; j++) {
3339 for (uint k = 0;; k++) {
3340 byte x = buf->ReadByte();
3341 if (x == 0xFE && k == 0) {
3347 byte y = buf->ReadByte();
3348 if (x == 0 && y == 0x80)
break;
3350 byte gfx = buf->ReadByte();
3351 if (gfx == 0xFE) buf->ReadWord();
3358 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3365 buf->Skip(buf->ReadByte());
3369 int num_inputs = buf->ReadByte();
3370 int num_outputs = buf->ReadByte();
3371 buf->Skip(num_inputs * num_outputs * 2);
3389 const size_t size = layout.size();
3390 if (size == 0)
return false;
3392 for (
size_t i = 0; i < size - 1; i++) {
3393 for (
size_t j = i + 1; j < size; j++) {
3394 if (layout[i].ti.x == layout[j].ti.x &&
3395 layout[i].ti.y == layout[j].ti.y) {
3401 bool have_regular_tile =
false;
3402 for (
size_t i = 0; i < size; i++) {
3404 have_regular_tile =
true;
3409 return have_regular_tile;
3430 if (_cur.
grffile->industryspec ==
nullptr) {
3434 for (
int i = 0; i < numinfo; i++) {
3437 if (prop != 0x08 && indsp ==
nullptr) {
3439 if (cir > ret) ret = cir;
3446 byte subs_id = buf->ReadByte();
3448 if (subs_id == 0xFF) {
3451 _industry_specs[indid + i].
enabled =
false;
3455 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3462 if (*indspec ==
nullptr) {
3466 *indsp = _origin_industry_specs[subs_id];
3469 indsp->
grf_prop.subst_id = subs_id;
3479 byte ovrid = buf->ReadByte();
3483 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3487 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3492 byte new_num_layouts = buf->ReadByte();
3493 uint32 definition_size = buf->ReadDWord();
3494 uint32 bytes_read = 0;
3495 std::vector<IndustryTileLayout> new_layouts;
3498 for (
byte j = 0; j < new_num_layouts; j++) {
3501 for (uint k = 0;; k++) {
3502 if (bytes_read >= definition_size) {
3503 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3505 definition_size = UINT32_MAX;
3511 it.ti.
x = buf->ReadByte();
3514 if (it.ti.
x == 0xFE && k == 0) {
3516 IndustryType type = buf->ReadByte();
3517 byte laynbr = buf->ReadByte();
3520 if (type >=
lengthof(_origin_industry_specs)) {
3521 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3525 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3526 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3530 layout = _origin_industry_specs[type].layouts[laynbr];
3534 it.ti.
y = buf->ReadByte();
3537 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3543 it.gfx = buf->ReadByte();
3546 if (it.gfx == 0xFE) {
3548 int local_tile_id = buf->ReadWord();
3552 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3555 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3561 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3562 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3571 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3577 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3581 new_layouts.push_back(layout);
3611 for (
byte j = 0; j < 2; j++) {
3617 for (
byte j = 0; j < 3; j++) {
3625 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3638 sounds[j] = buf->ReadByte();
3654 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3680 uint32 multiples = buf->ReadDWord();
3696 byte aflag = buf->ReadByte();
3706 uint16 str = buf->ReadWord();
3716 byte num_cargoes = buf->ReadByte();
3717 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3719 error->param_value[1] = prop;
3722 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3723 if (i < num_cargoes) {
3725 indsp->produced_cargo[i] = cargo;
3734 byte num_cargoes = buf->ReadByte();
3737 error->param_value[1] = prop;
3741 if (i < num_cargoes) {
3752 byte num_cargoes = buf->ReadByte();
3753 if (num_cargoes >
lengthof(indsp->production_rate)) {
3755 error->param_value[1] = prop;
3758 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3759 if (i < num_cargoes) {
3760 indsp->production_rate[i] = buf->ReadByte();
3762 indsp->production_rate[i] = 0;
3769 byte num_inputs = buf->ReadByte();
3770 byte num_outputs = buf->ReadByte();
3773 error->param_value[1] = prop;
3777 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3779 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3803 for (
int i = 0; i < as->
num_table; i++) {
3808 }
while ((++it)->ti.x != -0x80);
3809 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3812 as->
table = table_list;
3834 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3839 if (_cur.
grffile->airportspec ==
nullptr) {
3843 for (
int i = 0; i < numinfo; i++) {
3846 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3847 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3853 byte subs_id = buf->ReadByte();
3855 if (subs_id == 0xFF) {
3862 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3870 if (*spec ==
nullptr) {
3871 *spec = MallocT<AirportSpec>(1);
3880 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3892 uint32 defsize = buf->ReadDWord();
3898 for (
byte j = 0; j < as->
num_table; j++) {
3900 for (
int k = 0;; k++) {
3901 att[k].
ti.
x = buf->ReadByte();
3902 att[k].
ti.
y = buf->ReadByte();
3904 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3907 att[k].
ti.
x = -0x80;
3916 att[k].
gfx = buf->ReadByte();
3918 if (att[k].gfx == 0xFE) {
3920 int local_tile_id = buf->ReadWord();
3923 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3926 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3929 att[k].
gfx = tempid;
3931 }
else if (att[k].gfx == 0xFF) {
3932 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3933 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3944 tile_table[j] = CallocT<AirportTileTable>(size);
3945 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3948 for (
int j = 0; j < old_num_table; j++) {
3954 as->
table = tile_table;
3957 for (
int i = 0; i < as->
num_table; i++) {
3958 free(tile_table[i]);
4064 if (_cur.
grffile->objectspec ==
nullptr) {
4068 for (
int i = 0; i < numinfo; i++) {
4071 if (prop != 0x08 && spec ==
nullptr) {
4074 if (cir > ret) ret = cir;
4083 if (*ospec ==
nullptr) {
4084 *ospec = CallocT<ObjectSpec>(1);
4085 (*ospec)->views = 1;
4090 uint32 classid = buf->ReadDWord();
4091 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4092 (*ospec)->enabled =
true;
4107 spec->
climate = buf->ReadByte();
4111 spec->
size = buf->ReadByte();
4112 if (
GB(spec->
size, 0, 4) == 0 ||
GB(spec->
size, 4, 4) == 0) {
4113 grfmsg(0,
"ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->
size,
id + i);
4158 spec->
height = buf->ReadByte();
4162 spec->
views = buf->ReadByte();
4164 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4197 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4201 for (
int i = 0; i < numinfo; i++) {
4214 uint16 str = buf->ReadWord();
4216 if (_cur.
grffile->grf_version < 8) {
4246 int n = buf->ReadByte();
4247 for (
int j = 0; j != n; j++) {
4248 RailTypeLabel label = buf->ReadDWord();
4308 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4327 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4331 for (
int i = 0; i < numinfo; i++) {
4335 RailTypeLabel rtl = buf->ReadDWord();
4344 _cur.
grffile->railtype_map[
id + i] = rt;
4362 int n = buf->ReadByte();
4363 for (
int j = 0; j != n; j++) {
4368 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4375 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4416 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4420 for (
int i = 0; i < numinfo; i++) {
4433 uint16 str = buf->ReadWord();
4460 int n = buf->ReadByte();
4461 for (
int j = 0; j != n; j++) {
4462 RoadTypeLabel label = buf->ReadDWord();
4509 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4540 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4544 for (
int i = 0; i < numinfo; i++) {
4547 RoadTypeLabel rtl = buf->ReadDWord();
4554 }
else if (GetRoadTramType(rt) != rtt) {
4555 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4559 type_map[
id + i] = rt;
4576 int n = buf->ReadByte();
4577 for (
int j = 0; j != n; j++) {
4582 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4588 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4612 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4617 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4630 if (_cur.
grffile->airtspec ==
nullptr) {
4634 for (
int i = 0; i < numinfo; i++) {
4637 if (prop != 0x08 && tsp ==
nullptr) {
4638 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4645 byte subs_id = buf->ReadByte();
4649 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4654 if (*tilespec ==
nullptr) {
4655 *tilespec = CallocT<AirportTileSpec>(1);
4672 byte override = buf->ReadByte();
4676 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4680 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4710 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4713 default: NOT_REACHED();
4723 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4727 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4740 static void FeatureChangeInfo(
ByteReader *buf)
4753 static const VCI_Handler handler[] = {
4771 AirportTilesChangeInfo,
4775 static_assert(GSF_END ==
lengthof(handler));
4777 uint8 feature = buf->ReadByte();
4778 uint8 numprops = buf->ReadByte();
4779 uint numinfo = buf->ReadByte();
4780 uint engine = buf->ReadExtendedByte();
4782 if (feature >= GSF_END) {
4783 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4787 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4788 feature, numprops, engine, numinfo);
4790 if (handler[feature] ==
nullptr) {
4791 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4798 while (numprops-- && buf->HasData()) {
4799 uint8 prop = buf->ReadByte();
4802 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4809 uint8 feature = buf->ReadByte();
4810 uint8 numprops = buf->ReadByte();
4811 uint numinfo = buf->ReadByte();
4812 buf->ReadExtendedByte();
4814 if (feature == GSF_BRIDGES && numprops == 1) {
4815 uint8 prop = buf->ReadByte();
4818 if (prop == 0x0D)
return;
4819 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4820 uint8 prop = buf->ReadByte();
4823 bool is_safe =
true;
4824 for (uint i = 0; i < numinfo; i++) {
4825 uint32 s = buf->ReadDWord();
4833 if (is_safe)
return;
4844 static void ReserveChangeInfo(
ByteReader *buf)
4846 uint8 feature = buf->ReadByte();
4848 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4850 uint8 numprops = buf->ReadByte();
4851 uint8 numinfo = buf->ReadByte();
4852 uint8 index = buf->ReadExtendedByte();
4854 while (numprops-- && buf->HasData()) {
4855 uint8 prop = buf->ReadByte();
4859 default: NOT_REACHED();
4865 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4869 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4873 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4877 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4881 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4902 uint8 feature = buf->ReadByte();
4903 uint16 num_sets = buf->ReadByte();
4904 uint16 first_set = 0;
4906 if (num_sets == 0 && buf->HasData(3)) {
4909 first_set = buf->ReadExtendedByte();
4910 num_sets = buf->ReadExtendedByte();
4912 uint16 num_ents = buf->ReadExtendedByte();
4914 if (feature >= GSF_END) {
4916 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4922 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4923 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4926 for (
int i = 0; i < num_sets * num_ents; i++) {
4936 uint16 num_sets = buf->ReadByte();
4938 if (num_sets == 0 && buf->HasData(3)) {
4941 buf->ReadExtendedByte();
4942 num_sets = buf->ReadExtendedByte();
4944 uint16 num_ents = buf->ReadExtendedByte();
4953 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4955 if (
HasBit(groupid, 15)) {
4960 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4961 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4965 return _cur.spritegroups[groupid];
4978 if (
HasBit(spriteid, 15)) {
4984 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4989 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4992 assert(spriteset_start + num_sprites <= _cur.
spriteid);
5013 uint8 feature = buf->ReadByte();
5014 if (feature >= GSF_END) {
5015 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5019 uint8 setid = buf->ReadByte();
5020 uint8 type = buf->ReadByte();
5044 switch (
GB(type, 2, 2)) {
5045 default: NOT_REACHED();
5046 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5047 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5048 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5058 adjust.variable = buf->ReadByte();
5059 if (adjust.variable == 0x7E) {
5061 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5066 varadjust = buf->ReadByte();
5067 adjust.shift_num =
GB(varadjust, 0, 5);
5068 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5069 adjust.and_mask = buf->ReadVarSize(varsize);
5071 if (adjust.type != DSGA_TYPE_NONE) {
5072 adjust.add_val = buf->ReadVarSize(varsize);
5073 adjust.divmod_val = buf->ReadVarSize(varsize);
5076 adjust.divmod_val = 0;
5080 }
while (
HasBit(varadjust, 5));
5082 std::vector<DeterministicSpriteGroupRange> ranges;
5083 ranges.resize(buf->ReadByte());
5084 for (uint i = 0; i < ranges.size(); i++) {
5085 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5086 ranges[i].low = buf->ReadVarSize(varsize);
5087 ranges[i].high = buf->ReadVarSize(varsize);
5090 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5091 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5093 group->calculated_result = ranges.size() == 0;
5096 std::vector<uint32> bounds;
5097 for (uint i = 0; i < ranges.size(); i++) {
5098 bounds.push_back(ranges[i].low);
5099 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5101 std::sort(bounds.begin(), bounds.end());
5102 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5104 std::vector<const SpriteGroup *> target;
5105 for (uint j = 0; j < bounds.size(); ++j) {
5106 uint32 v = bounds[j];
5108 for (uint i = 0; i < ranges.size(); i++) {
5109 if (ranges[i].low <= v && v <= ranges[i].high) {
5110 t = ranges[i].group;
5114 target.push_back(t);
5116 assert(target.size() == bounds.size());
5118 for (uint j = 0; j < bounds.size(); ) {
5119 if (target[j] != group->default_group) {
5121 r.group = target[j];
5123 while (j < bounds.size() && target[j] == r.group) {
5126 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5148 group->count = buf->ReadByte();
5151 uint8 triggers = buf->ReadByte();
5152 group->triggers =
GB(triggers, 0, 7);
5153 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5156 byte num_groups = buf->ReadByte();
5158 grfmsg(1,
"NewSpriteGroup: Random Action 2 nrand should be power of 2");
5161 for (uint i = 0; i < num_groups; i++) {
5162 group->
groups.push_back(GetGroupFromGroupID(setid, type, buf->ReadWord()));
5173 case GSF_ROADVEHICLES:
5184 byte num_loaded = type;
5185 byte num_loading = buf->ReadByte();
5188 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5192 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5193 setid, num_loaded, num_loading);
5195 if (num_loaded + num_loading == 0) {
5196 grfmsg(1,
"NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
5200 if (num_loaded + num_loading == 1) {
5202 uint16 spriteid = buf->ReadWord();
5204 grfmsg(8,
"NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
5208 std::vector<uint16> loaded;
5209 std::vector<uint16> loading;
5211 for (uint i = 0; i < num_loaded; i++) {
5212 loaded.push_back(buf->ReadWord());
5213 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, loaded[i]);
5216 for (uint i = 0; i < num_loading; i++) {
5217 loading.push_back(buf->ReadWord());
5218 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
5221 if (std::adjacent_find(loaded.begin(), loaded.end(), std::not_equal_to<>()) == loaded.end() &&
5222 std::adjacent_find(loading.begin(), loading.end(), std::not_equal_to<>()) == loading.end() &&
5223 loaded[0] == loading[0])
5227 grfmsg(8,
"NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
5236 for (uint16 spriteid : loaded) {
5238 group->
loaded.push_back(t);
5241 for (uint16 spriteid : loading) {
5250 case GSF_AIRPORTTILES:
5252 case GSF_INDUSTRYTILES: {
5253 byte num_building_sprites = std::max((uint8)1, type);
5261 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5265 case GSF_INDUSTRIES: {
5267 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5278 for (uint i = 0; i < 3; i++) {
5282 for (uint i = 0; i < 2; i++) {
5285 group->again = buf->ReadByte();
5286 }
else if (type == 1) {
5288 for (uint i = 0; i < 3; i++) {
5292 for (uint i = 0; i < 2; i++) {
5295 group->again = buf->ReadByte();
5296 }
else if (type == 2) {
5300 error->data =
"too many inputs (max 16)";
5303 for (uint i = 0; i < group->
num_input; i++) {
5304 byte rawcargo = buf->ReadByte();
5313 error->data =
"duplicate input cargo";
5322 error->data =
"too many outputs (max 16)";
5325 for (uint i = 0; i < group->
num_output; i++) {
5326 byte rawcargo = buf->ReadByte();
5333 error->data =
"duplicate output cargo";
5339 group->again = buf->ReadByte();
5347 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5352 _cur.spritegroups[setid] = act_group;
5355 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5357 if (feature == GSF_OBJECTS) {
5362 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5367 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5368 if (ctype == 0xFF)
return CT_PURCHASE;
5373 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5378 if (cs->bitnum == ctype) {
5379 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5384 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5390 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5397 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5403 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));
5407 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);
5412 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5414 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5415 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5422 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5425 static uint last_engines_count;
5426 bool wagover =
false;
5429 if (
HasBit(idcount, 7)) {
5432 idcount =
GB(idcount, 0, 7);
5434 if (last_engines_count == 0) {
5435 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5439 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5440 last_engines_count, idcount);
5442 if (last_engines_count != idcount) {
5443 last_engines =
ReallocT(last_engines, idcount);
5444 last_engines_count = idcount;
5449 for (uint i = 0; i < idcount; i++) {
5455 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5459 engines[i] = e->
index;
5460 if (!wagover) last_engines[i] = engines[i];
5463 uint8 cidcount = buf->ReadByte();
5464 for (uint c = 0; c < cidcount; c++) {
5465 uint8 ctype = buf->ReadByte();
5466 uint16 groupid = buf->ReadWord();
5467 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5469 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5471 ctype = TranslateCargo(feature, ctype);
5474 for (uint i = 0; i < idcount; i++) {
5477 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5480 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5482 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5487 uint16 groupid = buf->ReadWord();
5488 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5490 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5492 for (uint i = 0; i < idcount; i++) {
5496 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5498 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5505 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5508 for (uint i = 0; i < idcount; i++) {
5512 uint8 cidcount = buf->ReadByte();
5513 buf->Skip(cidcount * 3);
5515 uint16 groupid = buf->ReadWord();
5516 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5518 for (uint i = 0; i < idcount; i++) {
5522 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5532 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5534 uint8 *stations =
AllocaM(uint8, idcount);
5535 for (uint i = 0; i < idcount; i++) {
5536 stations[i] = buf->ReadByte();
5539 uint8 cidcount = buf->ReadByte();
5540 for (uint c = 0; c < cidcount; c++) {
5541 uint8 ctype = buf->ReadByte();
5542 uint16 groupid = buf->ReadWord();
5543 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5545 ctype = TranslateCargo(GSF_STATIONS, ctype);
5548 for (uint i = 0; i < idcount; i++) {
5551 if (statspec ==
nullptr) {
5552 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5560 uint16 groupid = buf->ReadWord();
5561 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5563 for (uint i = 0; i < idcount; i++) {
5566 if (statspec ==
nullptr) {
5567 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5572 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5579 StationClass::Assign(statspec);
5584 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5586 uint8 *houses =
AllocaM(uint8, idcount);
5587 for (uint i = 0; i < idcount; i++) {
5588 houses[i] = buf->ReadByte();
5592 uint8 cidcount = buf->ReadByte();
5593 buf->Skip(cidcount * 3);
5595 uint16 groupid = buf->ReadWord();
5596 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5598 if (_cur.
grffile->housespec ==
nullptr) {
5599 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5603 for (uint i = 0; i < idcount; i++) {
5606 if (hs ==
nullptr) {
5607 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5615 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5617 uint8 *industries =
AllocaM(uint8, idcount);
5618 for (uint i = 0; i < idcount; i++) {
5619 industries[i] = buf->ReadByte();
5623 uint8 cidcount = buf->ReadByte();
5624 buf->Skip(cidcount * 3);
5626 uint16 groupid = buf->ReadWord();
5627 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5629 if (_cur.
grffile->industryspec ==
nullptr) {
5630 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5634 for (uint i = 0; i < idcount; i++) {
5637 if (indsp ==
nullptr) {
5638 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5646 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5648 uint8 *indtiles =
AllocaM(uint8, idcount);
5649 for (uint i = 0; i < idcount; i++) {
5650 indtiles[i] = buf->ReadByte();
5654 uint8 cidcount = buf->ReadByte();
5655 buf->Skip(cidcount * 3);
5657 uint16 groupid = buf->ReadWord();
5658 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5660 if (_cur.
grffile->indtspec ==
nullptr) {
5661 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5665 for (uint i = 0; i < idcount; i++) {
5668 if (indtsp ==
nullptr) {
5669 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5677 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5680 for (uint i = 0; i < idcount; i++) {
5681 cargoes[i] = buf->ReadByte();
5685 uint8 cidcount = buf->ReadByte();
5686 buf->Skip(cidcount * 3);
5688 uint16 groupid = buf->ReadWord();
5689 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5691 for (uint i = 0; i < idcount; i++) {
5695 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5701 cs->group = _cur.spritegroups[groupid];
5705 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5707 if (_cur.
grffile->objectspec ==
nullptr) {
5708 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5712 uint8 *objects =
AllocaM(uint8, idcount);
5713 for (uint i = 0; i < idcount; i++) {
5714 objects[i] = buf->ReadByte();
5717 uint8 cidcount = buf->ReadByte();
5718 for (uint c = 0; c < cidcount; c++) {
5719 uint8 ctype = buf->ReadByte();
5720 uint16 groupid = buf->ReadWord();
5721 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5723 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5726 for (uint i = 0; i < idcount; i++) {
5729 if (spec ==
nullptr) {
5730 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5738 uint16 groupid = buf->ReadWord();
5739 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5741 for (uint i = 0; i < idcount; i++) {
5744 if (spec ==
nullptr) {
5745 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5750 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5760 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5762 uint8 *railtypes =
AllocaM(uint8, idcount);
5763 for (uint i = 0; i < idcount; i++) {
5764 uint8
id = buf->ReadByte();
5768 uint8 cidcount = buf->ReadByte();
5769 for (uint c = 0; c < cidcount; c++) {
5770 uint8 ctype = buf->ReadByte();
5771 uint16 groupid = buf->ReadWord();
5772 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5774 if (ctype >= RTSG_END)
continue;
5777 for (uint i = 0; i < idcount; i++) {
5782 rti->
group[ctype] = _cur.spritegroups[groupid];
5791 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5795 uint8 *roadtypes =
AllocaM(uint8, idcount);
5796 for (uint i = 0; i < idcount; i++) {
5797 uint8
id = buf->ReadByte();
5801 uint8 cidcount = buf->ReadByte();
5802 for (uint c = 0; c < cidcount; c++) {
5803 uint8 ctype = buf->ReadByte();
5804 uint16 groupid = buf->ReadWord();
5805 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5807 if (ctype >= ROTSG_END)
continue;
5810 for (uint i = 0; i < idcount; i++) {
5815 rti->
group[ctype] = _cur.spritegroups[groupid];
5824 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5826 uint8 *airports =
AllocaM(uint8, idcount);
5827 for (uint i = 0; i < idcount; i++) {
5828 airports[i] = buf->ReadByte();
5832 uint8 cidcount = buf->ReadByte();
5833 buf->Skip(cidcount * 3);
5835 uint16 groupid = buf->ReadWord();
5836 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5838 if (_cur.
grffile->airportspec ==
nullptr) {
5839 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5843 for (uint i = 0; i < idcount; i++) {
5846 if (as ==
nullptr) {
5847 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5855 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5857 uint8 *airptiles =
AllocaM(uint8, idcount);
5858 for (uint i = 0; i < idcount; i++) {
5859 airptiles[i] = buf->ReadByte();
5863 uint8 cidcount = buf->ReadByte();
5864 buf->Skip(cidcount * 3);
5866 uint16 groupid = buf->ReadWord();
5867 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5869 if (_cur.
grffile->airtspec ==
nullptr) {
5870 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5874 for (uint i = 0; i < idcount; i++) {
5877 if (airtsp ==
nullptr) {
5878 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5888 static void FeatureMapSpriteGroup(
ByteReader *buf)
5904 uint8 feature = buf->ReadByte();
5905 uint8 idcount = buf->ReadByte();
5907 if (feature >= GSF_END) {
5908 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5916 uint16 groupid = buf->ReadWord();
5917 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5919 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5928 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5932 case GSF_ROADVEHICLES:
5935 VehicleMapSpriteGroup(buf, feature, idcount);
5939 CanalMapSpriteGroup(buf, idcount);
5943 StationMapSpriteGroup(buf, idcount);
5947 TownHouseMapSpriteGroup(buf, idcount);
5950 case GSF_INDUSTRIES:
5951 IndustryMapSpriteGroup(buf, idcount);
5954 case GSF_INDUSTRYTILES:
5955 IndustrytileMapSpriteGroup(buf, idcount);
5959 CargoMapSpriteGroup(buf, idcount);
5963 AirportMapSpriteGroup(buf, idcount);
5967 ObjectMapSpriteGroup(buf, idcount);
5971 RailTypeMapSpriteGroup(buf, idcount);
5975 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5979 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5982 case GSF_AIRPORTTILES:
5983 AirportTileMapSpriteGroup(buf, idcount);
5987 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
6011 bool new_scheme = _cur.
grffile->grf_version >= 7;
6013 uint8 feature = buf->ReadByte();
6014 if (feature >= GSF_END && feature != 0x48) {
6015 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
6019 uint8 lang = buf->ReadByte();
6020 uint8 num = buf->ReadByte();
6021 bool generic =
HasBit(lang, 7);
6024 id = buf->ReadWord();
6025 }
else if (feature <= GSF_AIRCRAFT) {
6026 id = buf->ReadExtendedByte();
6028 id = buf->ReadByte();
6033 uint16 endid =
id + num;
6035 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
6036 id, endid, feature, lang);
6038 for (;
id < endid && buf->HasData();
id++) {
6039 const char *name = buf->ReadString();
6040 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6044 case GSF_ROADVEHICLES:
6049 if (e ==
nullptr)
break;
6063 switch (
GB(
id, 8, 8)) {
6065 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6066 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6074 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6075 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6082 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6083 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6090 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6091 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6098 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6117 if (offset >= max_sprites) {
6118 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6119 uint orig_num = num;
6124 if (offset + num > max_sprites) {
6125 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6126 uint orig_num = num;
6127 num = std::max(max_sprites - offset, 0);
6128 return orig_num - num;
6157 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6159 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6189 uint8 type = buf->ReadByte();
6190 uint16 num = buf->ReadExtendedByte();
6191 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6197 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6214 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6225 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6232 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);
6242 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);
6253 for (; num > 0; num--) {
6324 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6354 *value = _game_mode;
6388 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6397 *value = _openttd_newgrf_version;
6412 default:
return false;
6416 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6434 if (cond_val ==
nullptr) {
6438 uint32 index = *cond_val / 0x20;
6454 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6475 size_t pos = file.
GetPos();
6478 byte *preload_sprite =
nullptr;
6482 preload_sprite = MallocT<byte>(num);
6487 file.
SeekTo(pos, SEEK_SET);
6490 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6491 free(preload_sprite);
6496 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6497 if (it != _grf_line_to_action6_sprite_override.end()) {
6498 free(preload_sprite);
6499 preload_sprite = _grf_line_to_action6_sprite_override[location];
6501 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6514 param_num = buf->ReadByte();
6515 if (param_num == 0xFF)
break;
6519 param_size = buf->ReadByte();
6523 add_value =
HasBit(param_size, 7);
6524 param_size =
GB(param_size, 0, 7);
6527 offset = buf->ReadExtendedByte();
6531 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6532 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6536 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6539 for (i = 0; i < param_size && offset + i < num; i++) {
6540 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6543 if (i % 4 == 0) carry =
false;
6546 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6547 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6549 carry = new_value >= 256;
6551 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6583 uint32 cond_val = 0;
6587 uint8 param = buf->ReadByte();
6588 uint8 paramsize = buf->ReadByte();
6589 uint8 condtype = buf->ReadByte();
6596 switch (paramsize) {
6597 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6598 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6599 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6600 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6604 if (param < 0x80 && _cur.grffile->param_end <= param) {
6605 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6609 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6614 if (condtype >= 0x0B) {
6645 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6647 }
else if (param == 0x88) {
6657 if (condtype != 10 && c ==
nullptr) {
6658 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6685 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6689 uint32 param_val = GetParamVal(param, &cond_val);
6691 case 0x00: result = !!(param_val & (1 << cond_val));
6693 case 0x01: result = !(param_val & (1 << cond_val));
6695 case 0x02: result = (param_val & mask) == cond_val;
6697 case 0x03: result = (param_val & mask) != cond_val;
6699 case 0x04: result = (param_val & mask) < cond_val;
6701 case 0x05: result = (param_val & mask) > cond_val;
6703 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6708 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6712 uint8 numsprites = buf->ReadByte();
6720 if (label->label != numsprites)
continue;
6723 if (choice ==
nullptr) choice = label;
6725 if (label->nfo_line > _cur.
nfo_line) {
6731 if (choice !=
nullptr) {
6732 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6738 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6757 uint8 grf_version = buf->ReadByte();
6758 uint32 grfid = buf->ReadDWord();
6759 const char *name = buf->ReadString();
6763 if (grf_version < 2 || grf_version > 8) {
6765 Debug(grf, 0,
"{}: NewGRF \"{}\" (GRFID {:08X}) uses GRF version {}, which is incompatible with this version of OpenTTD.", _cur.
grfconfig->
filename, name,
BSWAP32(grfid), grf_version);
6773 if (buf->HasData()) {
6774 const char *info = buf->ReadString();
6792 uint8 version = buf->ReadByte();
6793 uint32 grfid = buf->ReadDWord();
6794 const char *name = buf->ReadString();
6797 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6801 if (_cur.
grffile->grfid != grfid) {
6802 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));
6806 _cur.
grffile->grf_version = version;
6824 uint8 num_sets = buf->ReadByte();
6826 for (uint i = 0; i < num_sets; i++) {
6827 uint8 num_sprites = buf->ReadByte();
6828 uint16 first_sprite = buf->ReadWord();
6830 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6831 i, num_sprites, first_sprite
6834 for (uint j = 0; j < num_sprites; j++) {
6835 int load_index = first_sprite + j;
6841 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6851 uint8 num_sets = buf->ReadByte();
6853 for (uint i = 0; i < num_sets; i++) {
6882 STR_NEWGRF_ERROR_VERSION_NUMBER,
6883 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6884 STR_NEWGRF_ERROR_UNSET_SWITCH,
6885 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6886 STR_NEWGRF_ERROR_LOAD_BEFORE,
6887 STR_NEWGRF_ERROR_LOAD_AFTER,
6888 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6892 STR_NEWGRF_ERROR_MSG_INFO,
6893 STR_NEWGRF_ERROR_MSG_WARNING,
6894 STR_NEWGRF_ERROR_MSG_ERROR,
6895 STR_NEWGRF_ERROR_MSG_FATAL
6898 byte severity = buf->ReadByte();
6899 byte lang = buf->ReadByte();
6900 byte message_id = buf->ReadByte();
6903 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6907 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6908 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6913 if (severity >=
lengthof(sevstr)) {
6914 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6916 }
else if (severity == 3) {
6926 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6927 grfmsg(7,
"GRFLoadError: Invalid message id.");
6931 if (buf->Remaining() <= 1) {
6932 grfmsg(7,
"GRFLoadError: No message data supplied.");
6941 if (message_id == 0xFF) {
6943 if (buf->HasData()) {
6944 const char *message = buf->ReadString();
6948 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6949 error->custom_message.clear();
6952 error->message = msgstr[message_id];
6955 if (buf->HasData()) {
6956 const char *data = buf->ReadString();
6960 grfmsg(7,
"GRFLoadError: No message data supplied.");
6961 error->data.clear();
6965 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6966 uint param_number = buf->ReadByte();
6980 if (!buf->HasData())
return;
6982 const char *text = buf->ReadString();
6983 grfmsg(2,
"GRFComment: %s", text);
6989 uint8 target = buf->ReadByte();
6992 if (target < 0x80 || target == 0x9E)
return;
7006 static uint32 GetPatchVariable(uint8 param)
7016 case 0x0F:
return 0;
7032 case 0x11:
return SPR_2CCMAP_BASE;
7049 byte max_edge = std::max(log_X, log_Y);
7051 if (log_X == log_Y) {
7054 if (max_edge == log_Y)
SetBit(map_bits, 1);
7057 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7058 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7067 return SPR_SLOPES_BASE;
7078 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7084 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7097 for (uint i = start; i < num_ids; i++) {
7101 if (op == 2 || op == 3)
break;
7106 if (size == count)
break;
7109 if (size == count) {
7111 if (op == 0 || op == 3) {
7112 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7113 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7119 if (op != 4 && op != 5) {
7121 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7126 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7156 uint8 target = buf->ReadByte();
7157 uint8 oper = buf->ReadByte();
7158 uint32 src1 = buf->ReadByte();
7159 uint32 src2 = buf->ReadByte();
7162 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7171 if (target < 0x80 && target < _cur.grffile->param_end) {
7172 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7176 oper =
GB(oper, 0, 7);
7180 if (
GB(data, 0, 8) == 0xFF) {
7181 if (data == 0x0000FFFF) {
7183 src1 = GetPatchVariable(src1);
7187 uint8 feature =
GB(data, 8, 8);
7188 uint16 count =
GB(data, 16, 16);
7190 if (_cur.
stage == GLS_RESERVE) {
7191 if (feature == 0x08) {
7195 if (_cur.
spriteid + count >= 16384) {
7196 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7202 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7209 }
else if (_cur.
stage == GLS_ACTIVATION) {
7238 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7246 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7257 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7274 }
else if (src1 == 0xFE) {
7286 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7287 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7309 res = (int32)src1 * (int32)src2;
7313 if ((int32)src2 < 0) {
7314 res = src1 >> -(int32)src2;
7316 res = src1 << (src2 & 0x1F);
7321 if ((int32)src2 < 0) {
7322 res = (int32)src1 >> -(int32)src2;
7324 res = (int32)src1 << (src2 & 0x1F);
7348 res = (int32)src1 / (int32)src2;
7364 res = (int32)src1 % (int32)src2;
7368 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7397 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7408 uint32 safe_bits = 0;
7409 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7418 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7422 if (target < 0x80) {
7423 _cur.
grffile->param[target] = res;
7427 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7441 uint8 num = buf->ReadByte();
7443 for (uint i = 0; i < num; i++) {
7444 uint32 grfid = buf->ReadDWord();
7466 uint8 num = buf->ReadByte();
7468 for (uint i = 0; i < num; i++) {
7469 uint32 grfid = buf->ReadDWord();
7473 if (file !=
nullptr && file != _cur.
grfconfig) {
7491 uint32 grfid = _cur.
grffile->grfid;
7495 byte id = buf->ReadByte();
7496 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7501 bool new_scheme = _cur.
grffile->grf_version >= 7;
7503 byte lang = buf->ReadByte();
7505 byte nb_gen = townname->nb_gen;
7509 const char *name = buf->ReadString();
7512 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7514 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7516 lang = buf->ReadByte();
7517 }
while (lang != 0);
7518 townname->id[nb_gen] = id;
7522 byte nb = buf->ReadByte();
7523 grfmsg(6,
"FeatureTownName: %u parts", nb);
7525 townname->nbparts[id] = nb;
7526 townname->partlist[id] = CallocT<NamePartList>(nb);
7528 for (
int i = 0; i < nb; i++) {
7529 byte nbtext = buf->ReadByte();
7530 townname->partlist[id][i].bitstart = buf->ReadByte();
7531 townname->partlist[id][i].bitcount = buf->ReadByte();
7532 townname->partlist[id][i].maxprob = 0;
7533 townname->partlist[id][i].partcount = nbtext;
7534 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7535 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);
7537 for (
int j = 0; j < nbtext; j++) {
7538 byte prob = buf->ReadByte();
7541 byte ref_id = buf->ReadByte();
7543 if (townname->nbparts[ref_id] == 0) {
7544 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7545 DelGRFTownName(grfid);
7550 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7551 townname->partlist[id][i].parts[j].data.
id = ref_id;
7553 const char *text = buf->ReadString();
7555 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7557 townname->partlist[id][i].parts[j].
prob = prob;
7558 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7560 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7572 byte nfo_label = buf->ReadByte();
7574 GRFLabel *label = MallocT<GRFLabel>(1);
7575 label->label = nfo_label;
7578 label->next =
nullptr;
7586 for (l = _cur.
grffile->
label; l->next !=
nullptr; l = l->next) {}
7590 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7604 if (file ==
nullptr || file->sound_offset == 0) {
7605 grfmsg(1,
"ImportGRFSound: Source file not available");
7609 if (sound_id >= file->num_sounds) {
7610 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7614 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7616 *sound = *GetSound(file->sound_offset + sound_id);
7619 sound->volume = 128;
7620 sound->priority = 0;
7631 sound->volume = 0x80;
7632 sound->priority = 0;
7634 if (offs != SIZE_MAX) {
7636 sound->file = _cur.
file;
7637 sound->file_offset = offs;
7649 uint16 num = buf->ReadWord();
7650 if (num == 0)
return;
7653 if (_cur.
grffile->sound_offset == 0) {
7654 _cur.
grffile->sound_offset = GetNumSounds();
7655 _cur.
grffile->num_sounds = num;
7658 sound = GetSound(_cur.
grffile->sound_offset);
7663 for (
int i = 0; i < num; i++) {
7668 bool invalid = i >= _cur.
grffile->num_sounds;
7670 size_t offs = file.
GetPos();
7675 if (grf_container_version >= 2 && type == 0xFD) {
7678 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7680 }
else if (len != 4) {
7681 grfmsg(1,
"GRFSound: Invalid sprite section import");
7691 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7698 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7706 if (_cur.
stage == GLS_INIT) {
7707 if (grf_container_version >= 2) {
7708 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7717 if (_cur.
stage == GLS_ACTIVATION) {
7720 if (file.
ReadByte() != 0)
grfmsg(1,
"GRFSound: Import type mismatch");
7728 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7757 uint8 num_def = buf->ReadByte();
7759 for (uint i = 0; i < num_def; i++) {
7761 uint8 num_char = buf->ReadByte();
7762 uint16 base_char = buf->ReadWord();
7764 if (size >= FS_END) {
7765 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7768 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7770 for (uint c = 0; c < num_char; c++) {
7788 uint8 num_def = buf->ReadByte();
7790 for (uint i = 0; i < num_def; i++) {
7814 uint32 grfid = buf->ReadDWord();
7817 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7826 error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7836 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7837 byte num_strings = buf->ReadByte();
7838 uint16 first_id = buf->ReadWord();
7840 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7841 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7845 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7846 const char *
string = buf->ReadString();
7849 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7853 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7882 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7894 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7897 char data = buf->ReadByte();
7905 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7920 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7923 char data = buf->ReadByte();
7929 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7942 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7955 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7960 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7991 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7998 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
8008 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
8010 }
else if (len != 8) {
8011 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
8014 uint32 min_value = buf->ReadDWord();
8015 uint32 max_value = buf->ReadDWord();
8016 if (min_value <= max_value) {
8020 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
8029 if (len < 1 || len > 3) {
8030 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
8033 byte param_nr = buf->ReadByte();
8035 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8051 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8087 this->handler.data = handler;
8099 this->handler.text = handler;
8111 this->handler.call_handler =
true;
8112 this->handler.u.branch = handler;
8124 this->handler.call_handler =
false;
8125 this->handler.u.subtags =
subtags;
8154 byte type = buf->ReadByte();
8156 uint32
id = buf->ReadDWord();
8158 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8160 type = buf->ReadByte();
8164 byte langid = buf->ReadByte();
8165 const char *name_string = buf->ReadString();
8176 type = buf->ReadByte();
8201 byte type = buf->ReadByte();
8203 uint32
id = buf->ReadDWord();
8205 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8207 type = buf->ReadByte();
8220 type = buf->ReadByte();
8257 byte new_type = buf->ReadByte();
8258 while (new_type != 0) {
8261 new_type = buf->ReadByte();
8272 uint16 size = buf->ReadWord();
8296 while ((tag = &subtags[i++])->type != 0) {
8299 default: NOT_REACHED();
8302 byte langid = buf->ReadByte();
8303 return tag->handler.
text(langid, buf->ReadString());
8307 size_t len = buf->ReadWord();
8308 if (buf->Remaining() < len)
return false;
8309 return tag->handler.
data(len, buf);
8314 return tag->handler.u.branch(buf);
8320 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8332 byte type = buf->ReadByte();
8334 uint32
id = buf->ReadDWord();
8335 if (!
HandleNode(type,
id, buf, subtags))
return false;
8336 type = buf->ReadByte();
8458 if (stations ==
nullptr)
continue;
8460 if (stations[i] ==
nullptr)
continue;
8477 HouseSpec **&housespec = file->housespec;
8478 if (housespec ==
nullptr)
continue;
8484 housespec =
nullptr;
8493 if (aslist !=
nullptr) {
8497 if (as !=
nullptr) {
8499 for (
int j = 0; j < as->
num_table; j++) {
8511 file->airportspec =
nullptr;
8515 if (airporttilespec !=
nullptr) {
8517 free(airporttilespec[i]);
8519 free(airporttilespec);
8520 airporttilespec =
nullptr;
8534 if (industryspec !=
nullptr) {
8541 industryspec =
nullptr;
8544 if (indtspec ==
nullptr)
continue;
8559 if (objectspec ==
nullptr)
continue;
8561 free(objectspec[i]);
8565 objectspec =
nullptr;
8597 CleanUpGRFTownNames();
8641 ObjectClass::Reset();
8646 StationClass::Reset();
8650 AirportClass::Reset();
8679 _grf_id_overrides.clear();
8681 InitializeSoundPool();
8729 if (newfile !=
nullptr) {
8735 newfile =
new GRFFile(config);
8753 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8758 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8765 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8769 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8785 free(this->filename);
8795 CargoTypes original_known_cargoes = 0;
8796 for (
int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
8804 bool only_defaultcargo;
8807 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
8810 static constexpr
byte T = 1 << LT_TEMPERATE;
8811 static constexpr
byte A = 1 << LT_ARCTIC;
8812 static constexpr
byte S = 1 << LT_TROPIC;
8813 static constexpr
byte Y = 1 << LT_TOYLAND;
8814 static const struct DefaultRefitMasks {
8817 CargoTypes cargo_allowed;
8818 CargoTypes cargo_disallowed;
8819 } _default_refit_masks[] = {
8821 {T | A | S , CT_MAIL,
CC_MAIL, 0},
8824 {T | A , CT_COAL,
CC_BULK, 0},
8825 { S , CT_COPPER_ORE,
CC_BULK, 0},
8840 switch (ei->cargo_type) {
8844 _gted[engine].cargo_disallowed = 0;
8849 _gted[engine].cargo_disallowed = 0;
8868 _gted[engine].cargo_disallowed = 0;
8871 for (
const auto &drm : _default_refit_masks) {
8873 if (drm.cargo_type != ei->cargo_type)
continue;
8875 _gted[engine].cargo_allowed = drm.cargo_allowed;
8876 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
8893 CargoTypes mask = 0;
8894 CargoTypes not_mask = 0;
8895 CargoTypes xor_mask = ei->refit_mask;
8901 if (
_gted[engine].cargo_allowed != 0) {
8904 if (
_gted[engine].cargo_allowed & cs->classes)
SetBit(mask, cs->Index());
8905 if (
_gted[engine].cargo_disallowed & cs->classes)
SetBit(not_mask, cs->Index());
8909 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8927 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8929 const uint8 *cargo_map_for_first_refittable =
nullptr;
8932 if (file ==
nullptr) file = e->
GetGRF();
8933 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8934 cargo_map_for_first_refittable = file->
cargo_map;
8938 if (cargo_map_for_first_refittable !=
nullptr) {
8940 byte best_local_slot = 0xFF;
8942 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8943 if (local_slot < best_local_slot) {
8944 best_local_slot = local_slot;
8945 ei->cargo_type = cargo_type;
8967 for (uint i = 0; i < CF_END; i++) {
8979 if (e->
GetGRF() ==
nullptr) {
8982 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
9017 default: NOT_REACHED();
9031 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
9032 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
9056 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
9066 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs->
grf_prop.
local_id);
9074 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9081 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs->
grf_prop.
local_id);
9100 if (hs ==
nullptr || !hs->
enabled)
continue;
9105 if (min_year == 0)
return;
9109 if (hs ==
nullptr || !hs->
enabled)
continue;
9133 HouseSpec **&housespec = file->housespec;
9134 if (housespec ==
nullptr)
continue;
9139 if (hs ==
nullptr)
continue;
9197 if (industryspec !=
nullptr) {
9201 if (indsp !=
nullptr && indsp->
enabled) {
9207 if (strid != STR_UNDEFINED) indsp->
name = strid;
9210 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9225 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9233 if (indtspec !=
nullptr) {
9236 if (indtsp !=
nullptr) {
9237 _industile_mngr.SetEntitySpec(indtsp);
9246 for (uint i = 0; i < 3; i++) {
9251 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9265 if (objectspec !=
nullptr) {
9267 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9284 if (airportspec !=
nullptr) {
9286 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9287 _airport_mngr.SetEntitySpec(airportspec[i]);
9293 if (airporttilespec !=
nullptr) {
9295 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9296 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9309 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9323 static const SpecialSpriteHandler handlers[][GLS_END] = {
9324 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9325 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9326 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9327 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9328 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9329 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9330 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9331 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9332 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9333 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9334 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9335 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9336 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9338 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9341 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9344 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9349 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9350 if (it == _grf_line_to_action6_sprite_override.end()) {
9356 buf = _grf_line_to_action6_sprite_override[location];
9357 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9367 byte action = bufp->ReadByte();
9369 if (action == 0xFF) {
9370 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9371 }
else if (action == 0xFE) {
9372 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9373 }
else if (action >=
lengthof(handlers)) {
9374 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9375 }
else if (handlers[action][stage] ==
nullptr) {
9376 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9378 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9379 handlers[action][stage](bufp);
9382 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9398 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config->
filename);
9401 if (grf_container_version == 0) {
9402 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9406 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9412 if (grf_container_version >= 2) file.
ReadDword();
9415 if (grf_container_version >= 2) {
9417 byte compression = file.
ReadByte();
9418 if (compression != 0) {
9419 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9428 if (num == 4 && file.
ReadByte() == 0xFF) {
9431 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9439 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
9445 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9456 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9457 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9461 if (grf_container_version >= 2 && type == 0xFD) {
9484 const char *filename = config->
filename;
9495 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9497 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9504 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
9558 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9559 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9560 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9561 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9562 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9563 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9574 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9578 int *grf_overrides =
AllocaM(
int, num_grfs);
9579 for (
int i = 0; i < num_grfs; i++) {
9580 grf_overrides[i] = -1;
9583 uint32
override = _grf_id_overrides[source->grfid];
9584 if (
override == 0)
continue;
9587 if (dest ==
nullptr)
continue;
9590 assert(grf_overrides[i] >= 0);
9594 for (
int i = 0; i < num_grfs; i++) {
9595 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9603 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9606 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
9612 for (
int i = num_grfs - 1; i >= 0; i--) {
9613 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9621 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9624 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
9630 for (
int i = 0; i < num_grfs; i++) {
9631 if (grf_overrides[i] < 0)
continue;
9639 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9640 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9642 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
9650 if (file->grf_version >= 8)
continue;
9651 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9652 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9654 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9657 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9664 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9665 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9666 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9668 price_base_multipliers[p] = 0;
9673 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file->
filename, p);
9675 price_base_multipliers[p] = 0;
9677 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file->
filename, p);
9692 _string_to_grf_mapping.clear();
9695 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9698 _grf_line_to_action6_sprite_override.clear();
9761 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9770 if (
_gted[e->
index].roadtramtype < list->size())
9772 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9790 e->u.rail.railtype = railtype;
9800 _grm_sprites.clear();
9848 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9855 if (stage == GLS_RESERVE) {
9856 static const uint32 overrides[][2] = {
9857 { 0x44442202, 0x44440111 },
9858 { 0x6D620402, 0x6D620401 },
9859 { 0x4D656f20, 0x4D656F17 },
9861 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9867 uint num_non_static = 0;
9876 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->
filename);
9885 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9887 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9896 if (stage == GLS_RESERVE) {
9898 }
else if (stage == GLS_ACTIVATION) {
9903 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur.
spriteid);