51 #include "table/strings.h"
68 const std::vector<GRFFile *> &GetAllGRFFiles()
117 this->skip_sprites = 0;
119 for (uint i = 0; i < GSF_END; i++) {
120 this->spritesets[i].clear();
123 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
136 assert(feature < GSF_END);
137 for (uint i = 0; i < numsets; i++) {
138 SpriteSet &set = this->spritesets[feature][first_set + i];
139 set.
sprite = first_sprite + i * numents;
152 assert(feature < GSF_END);
153 return !this->spritesets[feature].empty();
165 assert(feature < GSF_END);
166 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
178 return this->spritesets[feature].find(set)->second.sprite;
190 return this->spritesets[feature].find(set)->second.num_sprites;
203 template <VehicleType T>
206 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
218 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
220 inline byte *ReadBytes(
size_t size)
222 if (data + size >= end) {
233 inline byte ReadByte()
235 if (data < end)
return *(data)++;
241 uint16 val = ReadByte();
242 return val | (ReadByte() << 8);
245 uint16 ReadExtendedByte()
247 uint16 val = ReadByte();
248 return val == 0xFF ? ReadWord() : val;
253 uint32 val = ReadWord();
254 return val | (ReadWord() << 16);
257 uint32 ReadVarSize(
byte size)
260 case 1:
return ReadByte();
261 case 2:
return ReadWord();
262 case 4:
return ReadDWord();
269 const char *ReadString()
271 char *
string =
reinterpret_cast<char *
>(data);
272 size_t string_length =
ttd_strnlen(
string, Remaining());
274 if (string_length == Remaining()) {
276 string[string_length - 1] =
'\0';
277 grfmsg(7,
"String was not terminated with a zero byte.");
287 inline size_t Remaining()
const
292 inline bool HasData(
size_t count = 1)
const
294 return data + count <= end;
302 inline void Skip(
size_t len)
311 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
324 uint16 cargo_allowed;
325 uint16 cargo_disallowed;
326 RailTypeLabel railtypelabel;
343 }
else if (this->refittability ==
UNSET) {
344 this->refittability =
EMPTY;
364 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
368 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
373 return this->grfid == other.grfid && this->nfoline == other.nfoline;
377 static std::map<GRFLocation, SpriteID> _grm_sprites;
378 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
379 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
391 void CDECL
grfmsg(
int severity,
const char *str, ...)
411 if (file->grfid == grfid)
return file;
424 if (strcmp(file->filename, filename) == 0)
return file;
450 if (config !=
nullptr) {
461 if (message != STR_NULL) {
462 delete config->error;
463 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
467 return config->error;
478 typedef std::vector<StringIDMapping> StringIDMappingVector;
479 static StringIDMappingVector _string_to_grf_mapping;
488 *target = STR_UNDEFINED;
489 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
502 static const StringID units_volume[] = {
503 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
504 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
505 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
506 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
507 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
508 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
509 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
510 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
516 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
517 static_assert(stringend - stringid == end - begin); \
518 if (str >= begin && str <= end) return str + (stringid - begin)
521 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
522 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
523 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
524 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
525 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
526 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
531 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
532 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
533 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
536 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
537 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
538 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
539 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
540 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
543 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
544 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
545 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
547 #undef TEXTID_TO_STRINGID
549 if (str == STR_NULL)
return STR_EMPTY;
551 Debug(grf, 0,
"Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
590 static std::map<uint32, uint32> _grf_id_overrides;
599 _grf_id_overrides[source_grfid] = target_grfid;
600 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
615 uint32 scope_grfid = INVALID_GRFID;
618 scope_grfid = file->grfid;
619 uint32
override = _grf_id_overrides[file->grfid];
621 scope_grfid =
override;
623 if (grf_match ==
nullptr) {
624 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
631 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
640 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
646 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
650 if (!static_access) {
652 eid->
grfid = scope_grfid;
658 if (static_access)
return nullptr;
661 grfmsg(0,
"Can't allocate any more engines");
672 assert(_engine_mngr.size() == e->
index);
673 _engine_mngr.push_back({
686 memset(
_gted + engine_pool_size, 0, len);
692 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
709 uint32 scope_grfid = INVALID_GRFID;
711 scope_grfid = file->grfid;
712 uint32
override = _grf_id_overrides[file->grfid];
713 if (
override != 0) scope_grfid =
override;
716 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
756 grf_sprite->
sprite = buf->ReadWord();
757 grf_sprite->
pal = buf->ReadWord();
762 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
766 uint index =
GB(grf_sprite->
sprite, 0, 14);
768 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
769 grf_sprite->
sprite = SPR_IMG_QUERY;
770 grf_sprite->
pal = PAL_NONE;
773 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
778 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
779 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
785 uint index =
GB(grf_sprite->
pal, 0, 14);
787 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
788 grf_sprite->
pal = PAL_NONE;
791 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
796 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
797 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
826 regs.delta.
parent[0] = buf->ReadByte();
827 regs.delta.
parent[1] = buf->ReadByte();
839 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
848 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
867 bool has_flags =
HasBit(num_building_sprites, 6);
868 ClrBit(num_building_sprites, 6);
871 dts->
Allocate(num_building_sprites);
873 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
874 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
875 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
876 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
883 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
884 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
891 for (uint i = 0; i < num_building_sprites; i++) {
894 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
897 if (flags & ~valid_flags) {
898 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
899 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
903 seq->
delta_x = buf->ReadByte();
904 seq->delta_y = buf->ReadByte();
906 if (!no_z_position) seq->
delta_z = buf->ReadByte();
909 seq->size_x = buf->ReadByte();
910 seq->size_y = buf->ReadByte();
911 seq->size_z = buf->ReadByte();
919 bool is_consistent =
true;
921 for (uint i = 0; i < num_building_sprites + 1; i++) {
922 if (max_sprite_offset[i] > 0) {
926 is_consistent =
false;
930 if (max_palette_offset[i] > 0) {
934 is_consistent =
false;
943 if (!is_consistent || dts->registers !=
nullptr) {
947 for (uint i = 0; i < num_building_sprites + 1; i++) {
962 CargoTypes result = 0;
980 if (base_pointer == 0) {
981 *index = INVALID_PRICE;
985 static const uint32 start = 0x4B34;
986 static const uint32 size = 6;
988 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
989 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
993 *index = (
Price)((base_pointer - start) / size);
1022 ei->decay_speed = buf->ReadByte();
1039 ei->load_amount = buf->ReadByte();
1061 for (
int i = 0; i < numinfo; i++) {
1070 uint8 tracktype = buf->ReadByte();
1072 if (tracktype < _cur.grffile->railtype_list.size()) {
1077 switch (tracktype) {
1078 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1079 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1080 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1082 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1095 uint16 speed = buf->ReadWord();
1096 if (speed == 0xFFFF) speed = 0;
1103 rvi->
power = buf->ReadWord();
1106 if (rvi->
power != 0) {
1124 uint8 spriteid = buf->ReadByte();
1125 uint8 orig_spriteid = spriteid;
1129 if (spriteid < 0xFD) spriteid >>= 1;
1131 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1132 rvi->image_index = spriteid;
1134 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1135 rvi->image_index = 0;
1141 uint8 dual = buf->ReadByte();
1146 rvi->railveh_type = rvi->
power == 0 ?
1158 uint8 ctype = buf->ReadByte();
1160 if (ctype == 0xFF) {
1163 }
else if (_cur.
grffile->grf_version >= 8) {
1168 ei->cargo_type = ctype;
1171 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1177 SB(rvi->
weight, 0, 8, buf->ReadByte());
1185 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1197 uint8 traction = buf->ReadByte();
1200 if (traction <= 0x07) {
1202 }
else if (traction <= 0x27) {
1204 }
else if (traction <= 0x31) {
1206 }
else if (traction <= 0x37) {
1208 }
else if (traction <= 0x41) {
1234 ei->refit_cost = buf->ReadByte();
1238 uint32 mask = buf->ReadDWord();
1276 byte weight = buf->ReadByte();
1279 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1301 _gted[e->
index].cargo_allowed = buf->ReadWord();
1307 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1321 uint8 count = buf->ReadByte();
1359 for (
int i = 0; i < numinfo; i++) {
1370 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1378 rvi->running_cost = buf->ReadByte();
1386 uint8 spriteid = buf->ReadByte();
1387 uint8 orig_spriteid = spriteid;
1390 if (spriteid == 0xFF) spriteid = 0xFD;
1392 if (spriteid < 0xFD) spriteid >>= 1;
1394 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1395 rvi->image_index = spriteid;
1397 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1398 rvi->image_index = 0;
1404 rvi->capacity = buf->ReadByte();
1409 uint8 ctype = buf->ReadByte();
1411 if (ctype == 0xFF) {
1414 }
else if (_cur.
grffile->grf_version >= 8) {
1419 ei->cargo_type = ctype;
1422 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1428 rvi->cost_factor = buf->ReadByte();
1436 rvi->
power = buf->ReadByte();
1440 rvi->
weight = buf->ReadByte();
1448 uint32 mask = buf->ReadDWord();
1468 ei->refit_cost = buf->ReadByte();
1481 _gted[e->
index].cargo_allowed = buf->ReadWord();
1487 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1519 uint8 count = buf->ReadByte();
1553 for (
int i = 0; i < numinfo; i++) {
1562 uint8 spriteid = buf->ReadByte();
1563 uint8 orig_spriteid = spriteid;
1566 if (spriteid == 0xFF) spriteid = 0xFD;
1568 if (spriteid < 0xFD) spriteid >>= 1;
1570 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1571 svi->image_index = spriteid;
1573 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1574 svi->image_index = 0;
1584 svi->cost_factor = buf->ReadByte();
1593 uint8 ctype = buf->ReadByte();
1595 if (ctype == 0xFF) {
1598 }
else if (_cur.
grffile->grf_version >= 8) {
1603 ei->cargo_type = ctype;
1606 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1612 svi->capacity = buf->ReadWord();
1616 svi->running_cost = buf->ReadByte();
1624 uint32 mask = buf->ReadDWord();
1636 ei->refit_cost = buf->ReadByte();
1657 _gted[e->
index].cargo_allowed = buf->ReadWord();
1663 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1691 uint8 count = buf->ReadByte();
1725 for (
int i = 0; i < numinfo; i++) {
1734 uint8 spriteid = buf->ReadByte();
1735 uint8 orig_spriteid = spriteid;
1738 if (spriteid == 0xFF) spriteid = 0xFD;
1740 if (spriteid < 0xFD) spriteid >>= 1;
1742 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1743 avi->image_index = spriteid;
1745 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1746 avi->image_index = 0;
1752 if (buf->ReadByte() == 0) {
1760 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1764 avi->cost_factor = buf->ReadByte();
1768 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1772 avi->acceleration = buf->ReadByte();
1776 avi->running_cost = buf->ReadByte();
1792 uint32 mask = buf->ReadDWord();
1804 ei->refit_cost = buf->ReadByte();
1817 _gted[e->
index].cargo_allowed = buf->ReadWord();
1823 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1841 uint8 count = buf->ReadByte();
1887 for (
int i = 0; i < numinfo; i++) {
1891 if (statspec ==
nullptr && prop != 0x08) {
1892 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1904 uint32 classid = buf->ReadDWord();
1905 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1910 uint16 tiles = buf->ReadExtendedByte();
1914 for (uint t = 0; t < tiles; t++) {
1918 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1921 dts->
Clone(&_station_display_datas_rail[t % 8]);
1929 static std::vector<DrawTileSeqStruct> tmp_layout;
1936 dtss.
delta_x = buf->ReadByte();
1938 dtss.delta_y = buf->ReadByte();
1939 dtss.
delta_z = buf->ReadByte();
1940 dtss.size_x = buf->ReadByte();
1941 dtss.size_y = buf->ReadByte();
1942 dtss.size_z = buf->ReadByte();
1948 dts->
Clone(tmp_layout.data());
1954 byte srcid = buf->ReadByte();
1957 if (srcstatspec ==
nullptr) {
1958 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1965 for (
const auto &it : srcstatspec->
renderdata) {
1985 while (buf->HasData()) {
1986 byte length = buf->ReadByte();
1987 byte number = buf->ReadByte();
1989 if (length == 0 || number == 0)
break;
1991 if (statspec->
layouts.size() < length) statspec->
layouts.resize(length);
1992 if (statspec->
layouts[length - 1].size() < number) statspec->
layouts[length - 1].resize(number);
1994 const byte *layout = buf->ReadBytes(length * number);
1995 statspec->
layouts[length - 1][number - 1].assign(layout, layout + length * number);
1998 for (
auto &tile : statspec->
layouts[length - 1][number - 1]) {
1999 if ((tile & 6) != tile) {
2000 grfmsg(1,
"StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
2008 byte srcid = buf->ReadByte();
2011 if (srcstatspec ==
nullptr) {
2012 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2025 statspec->
pylons = buf->ReadByte();
2029 if (_cur.
grffile->grf_version >= 7) {
2037 statspec->
flags = buf->ReadByte();
2041 statspec->
wires = buf->ReadByte();
2045 statspec->
blocked = buf->ReadByte();
2049 statspec->animation.
frames = buf->ReadByte();
2050 statspec->animation.
status = buf->ReadByte();
2054 statspec->animation.
speed = buf->ReadByte();
2058 statspec->animation.
triggers = buf->ReadWord();
2062 uint16 tiles = buf->ReadExtendedByte();
2066 for (uint t = 0; t < tiles; t++) {
2068 uint num_building_sprites = buf->ReadByte();
2096 if (
id + numinfo > CF_END) {
2097 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2101 for (
int i = 0; i < numinfo; i++) {
2110 cp->
flags = buf->ReadByte();
2135 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2139 for (
int i = 0; i < numinfo; i++) {
2145 byte year = buf->ReadByte();
2160 bridge->
price = buf->ReadByte();
2164 bridge->
speed = buf->ReadWord();
2168 byte tableid = buf->ReadByte();
2169 byte numtables = buf->ReadByte();
2176 for (; numtables-- != 0; tableid++) {
2178 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2179 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2184 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2187 for (
byte sprite = 0; sprite < 32; sprite++) {
2201 bridge->
flags = buf->ReadByte();
2210 if (newone != STR_UNDEFINED) bridge->
material = newone;
2217 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2222 bridge->
price = buf->ReadWord();
2279 for (uint j = 0; j < 4; j++) buf->ReadByte();
2283 byte count = buf->ReadByte();
2284 for (
byte j = 0; j < count; j++) buf->ReadByte();
2289 buf->Skip(buf->ReadByte() * 2);
2312 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2317 if (_cur.
grffile->housespec ==
nullptr) {
2321 for (
int i = 0; i < numinfo; i++) {
2324 if (prop != 0x08 && housespec ==
nullptr) {
2327 if (cir > ret) ret = cir;
2334 byte subs_id = buf->ReadByte();
2336 if (subs_id == 0xFF) {
2339 HouseSpec::Get(hid + i)->
enabled =
false;
2343 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2348 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2352 MemCpyT(housespec, HouseSpec::Get(subs_id));
2356 housespec->
grf_prop.subst_id = subs_id;
2378 uint16 years = buf->ReadWord();
2398 int8 goods = buf->ReadByte();
2434 byte override = buf->ReadByte();
2438 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2442 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2451 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2473 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2481 uint32 cargotypes = buf->ReadDWord();
2484 if (cargotypes == 0xFFFFFFFF)
break;
2486 for (uint j = 0; j < 3; j++) {
2488 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2506 byte count = buf->ReadByte();
2507 for (
byte j = 0; j < count; j++) {
2515 housespec->
min_year = buf->ReadWord();
2519 housespec->
max_year = buf->ReadWord();
2523 uint count = buf->ReadByte();
2526 error->param_value[1] = prop;
2575 template <
typename T>
2579 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2583 translation_table.clear();
2584 for (
int i = 0; i < numinfo; i++) {
2585 uint32 item = buf->ReadDWord();
2586 translation_table.push_back(
BSWAP32(item));
2601 for (
int i = 0; i < 4; i++) output[i] = reader->ReadByte();
2605 return std::string(output);
2638 for (
int i = 0; i < numinfo; i++) {
2641 int factor = buf->ReadByte();
2642 uint price = gvid + i;
2644 if (price < PR_END) {
2647 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2656 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2664 uint32 rate = buf->ReadDWord();
2672 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2679 uint16 options = buf->ReadWord();
2688 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2700 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2712 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2719 Year year_euro = buf->ReadWord();
2724 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2731 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2733 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2739 table[i][j] = buf->ReadByte();
2740 if (_cur.
grffile->grf_version >= 8) {
2743 if (table[i][j] >= 128) {
2765 uint curidx = gvid + i;
2767 if (lang ==
nullptr) {
2768 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2773 while (buf->ReadByte() != 0) {
2783 uint plural_form = buf->ReadByte();
2784 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2785 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2792 byte newgrf_id = buf->ReadByte();
2793 while (newgrf_id != 0) {
2794 const char *name = buf->ReadString();
2809 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2816 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2821 newgrf_id = buf->ReadByte();
2857 for (
int i = 0; i < numinfo; i++) {
2881 uint32 s = buf->ReadDWord();
2882 uint32 t = buf->ReadDWord();
2889 while (buf->ReadByte() != 0) {
2917 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2921 for (
int i = 0; i < numinfo; i++) {
2926 cs->
bitnum = buf->ReadByte();
2964 cs->
sprite = buf->ReadWord();
2968 cs->
weight = buf->ReadByte();
2972 cs->transit_days[0] = buf->ReadByte();
2976 cs->transit_days[1] = buf->ReadByte();
2984 cs->rating_colour = buf->ReadByte();
2988 cs->legend_colour = buf->ReadByte();
2996 cs->
classes = buf->ReadWord();
3000 cs->
label = buf->ReadDWord();
3005 uint8 substitute_type = buf->ReadByte();
3007 switch (substitute_type) {
3014 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3030 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3055 if (_cur.
grffile->sound_offset == 0) {
3056 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3061 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3065 for (
int i = 0; i < numinfo; i++) {
3070 sound->volume = buf->ReadByte();
3074 sound->priority = buf->ReadByte();
3078 SoundID orig_sound = buf->ReadByte();
3083 SoundEntry *old_sound = GetSound(orig_sound);
3086 *old_sound = *sound;
3128 buf->Skip(buf->ReadByte() * 2);
3156 if (_cur.
grffile->indtspec ==
nullptr) {
3160 for (
int i = 0; i < numinfo; i++) {
3163 if (prop != 0x08 && tsp ==
nullptr) {
3165 if (cir > ret) ret = cir;
3172 byte subs_id = buf->ReadByte();
3176 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3181 if (*tilespec ==
nullptr) {
3182 *tilespec = CallocT<IndustryTileSpec>(1);
3185 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3203 byte ovrid = buf->ReadByte();
3207 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3211 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3218 uint16 acctp = buf->ReadWord();
3250 byte num_cargoes = buf->ReadByte();
3253 error->param_value[1] = prop;
3257 if (i < num_cargoes) {
3324 byte num_table = buf->ReadByte();
3325 for (
byte j = 0; j < num_table; j++) {
3326 for (uint k = 0;; k++) {
3327 byte x = buf->ReadByte();
3328 if (x == 0xFE && k == 0) {
3334 byte y = buf->ReadByte();
3335 if (x == 0 && y == 0x80)
break;
3337 byte gfx = buf->ReadByte();
3338 if (gfx == 0xFE) buf->ReadWord();
3345 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3352 buf->Skip(buf->ReadByte());
3356 int num_inputs = buf->ReadByte();
3357 int num_outputs = buf->ReadByte();
3358 buf->Skip(num_inputs * num_outputs * 2);
3376 const size_t size = layout.size();
3377 for (
size_t i = 0; i < size - 1; i++) {
3378 for (
size_t j = i + 1; j < size; j++) {
3379 if (layout[i].ti.x == layout[j].ti.x &&
3380 layout[i].ti.y == layout[j].ti.y) {
3406 if (_cur.
grffile->industryspec ==
nullptr) {
3410 for (
int i = 0; i < numinfo; i++) {
3413 if (prop != 0x08 && indsp ==
nullptr) {
3415 if (cir > ret) ret = cir;
3422 byte subs_id = buf->ReadByte();
3424 if (subs_id == 0xFF) {
3427 _industry_specs[indid + i].
enabled =
false;
3431 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3438 if (*indspec ==
nullptr) {
3442 *indsp = _origin_industry_specs[subs_id];
3445 indsp->
grf_prop.subst_id = subs_id;
3455 byte ovrid = buf->ReadByte();
3459 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3463 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3468 byte new_num_layouts = buf->ReadByte();
3469 uint32 definition_size = buf->ReadDWord();
3470 uint32 bytes_read = 0;
3471 std::vector<IndustryTileLayout> new_layouts;
3474 for (
byte j = 0; j < new_num_layouts; j++) {
3477 for (uint k = 0;; k++) {
3478 if (bytes_read >= definition_size) {
3479 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3481 definition_size = UINT32_MAX;
3487 it.ti.
x = buf->ReadByte();
3490 if (it.ti.
x == 0xFE && k == 0) {
3492 IndustryType type = buf->ReadByte();
3493 byte laynbr = buf->ReadByte();
3496 if (type >=
lengthof(_origin_industry_specs)) {
3497 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3501 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3502 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3506 layout = _origin_industry_specs[type].layouts[laynbr];
3510 it.ti.
y = buf->ReadByte();
3513 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3519 it.gfx = buf->ReadByte();
3522 if (it.gfx == 0xFE) {
3524 int local_tile_id = buf->ReadWord();
3528 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3531 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3536 }
else if (it.gfx == 0xFF) {
3537 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3538 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3547 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3553 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3557 new_layouts.push_back(layout);
3587 for (
byte j = 0; j < 2; j++) {
3593 for (
byte j = 0; j < 3; j++) {
3601 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3614 sounds[j] = buf->ReadByte();
3630 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3656 uint32 multiples = buf->ReadDWord();
3672 byte aflag = buf->ReadByte();
3682 uint16 str = buf->ReadWord();
3692 byte num_cargoes = buf->ReadByte();
3693 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3695 error->param_value[1] = prop;
3698 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3699 if (i < num_cargoes) {
3701 indsp->produced_cargo[i] = cargo;
3710 byte num_cargoes = buf->ReadByte();
3713 error->param_value[1] = prop;
3717 if (i < num_cargoes) {
3728 byte num_cargoes = buf->ReadByte();
3729 if (num_cargoes >
lengthof(indsp->production_rate)) {
3731 error->param_value[1] = prop;
3734 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3735 if (i < num_cargoes) {
3736 indsp->production_rate[i] = buf->ReadByte();
3738 indsp->production_rate[i] = 0;
3745 byte num_inputs = buf->ReadByte();
3746 byte num_outputs = buf->ReadByte();
3749 error->param_value[1] = prop;
3753 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3755 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3779 for (
int i = 0; i < as->
num_table; i++) {
3784 }
while ((++it)->ti.x != -0x80);
3785 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3788 as->
table = table_list;
3810 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3815 if (_cur.
grffile->airportspec ==
nullptr) {
3819 for (
int i = 0; i < numinfo; i++) {
3822 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3823 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3829 byte subs_id = buf->ReadByte();
3831 if (subs_id == 0xFF) {
3838 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3846 if (*spec ==
nullptr) {
3847 *spec = MallocT<AirportSpec>(1);
3856 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3868 uint32 defsize = buf->ReadDWord();
3874 for (
byte j = 0; j < as->
num_table; j++) {
3876 for (
int k = 0;; k++) {
3877 att[k].
ti.
x = buf->ReadByte();
3878 att[k].
ti.
y = buf->ReadByte();
3880 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3883 att[k].
ti.
x = -0x80;
3892 att[k].
gfx = buf->ReadByte();
3894 if (att[k].gfx == 0xFE) {
3896 int local_tile_id = buf->ReadWord();
3899 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3902 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3905 att[k].
gfx = tempid;
3907 }
else if (att[k].gfx == 0xFF) {
3908 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3909 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3920 tile_table[j] = CallocT<AirportTileTable>(size);
3921 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3924 for (
int j = 0; j < old_num_table; j++) {
3930 as->
table = tile_table;
3933 for (
int i = 0; i < as->
num_table; i++) {
3934 free(tile_table[i]);
4040 if (_cur.
grffile->objectspec ==
nullptr) {
4044 for (
int i = 0; i < numinfo; i++) {
4047 if (prop != 0x08 && spec ==
nullptr) {
4050 if (cir > ret) ret = cir;
4059 if (*ospec ==
nullptr) {
4060 *ospec = CallocT<ObjectSpec>(1);
4061 (*ospec)->views = 1;
4062 (*ospec)->size = 0x11;
4066 uint32 classid = buf->ReadDWord();
4067 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4068 (*ospec)->enabled =
true;
4083 spec->
climate = buf->ReadByte();
4087 spec->
size = buf->ReadByte();
4088 if ((spec->
size & 0xF0) == 0 || (spec->
size & 0x0F) == 0) {
4089 grfmsg(1,
"ObjectChangeInfo: Invalid object size requested (%u) for object id %u. Ignoring.", spec->
size,
id + i);
4134 spec->
height = buf->ReadByte();
4138 spec->
views = buf->ReadByte();
4140 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4173 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4177 for (
int i = 0; i < numinfo; i++) {
4190 uint16 str = buf->ReadWord();
4192 if (_cur.
grffile->grf_version < 8) {
4222 int n = buf->ReadByte();
4223 for (
int j = 0; j != n; j++) {
4224 RailTypeLabel label = buf->ReadDWord();
4284 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4303 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4307 for (
int i = 0; i < numinfo; i++) {
4311 RailTypeLabel rtl = buf->ReadDWord();
4320 _cur.
grffile->railtype_map[
id + i] = rt;
4338 int n = buf->ReadByte();
4339 for (
int j = 0; j != n; j++) {
4344 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4351 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4392 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4396 for (
int i = 0; i < numinfo; i++) {
4409 uint16 str = buf->ReadWord();
4436 int n = buf->ReadByte();
4437 for (
int j = 0; j != n; j++) {
4438 RoadTypeLabel label = buf->ReadDWord();
4485 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4516 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4520 for (
int i = 0; i < numinfo; i++) {
4523 RoadTypeLabel rtl = buf->ReadDWord();
4530 }
else if (GetRoadTramType(rt) != rtt) {
4531 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4535 type_map[
id + i] = rt;
4552 int n = buf->ReadByte();
4553 for (
int j = 0; j != n; j++) {
4558 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4564 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4588 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4593 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4606 if (_cur.
grffile->airtspec ==
nullptr) {
4610 for (
int i = 0; i < numinfo; i++) {
4613 if (prop != 0x08 && tsp ==
nullptr) {
4614 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4621 byte subs_id = buf->ReadByte();
4625 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4630 if (*tilespec ==
nullptr) {
4631 *tilespec = CallocT<AirportTileSpec>(1);
4648 byte override = buf->ReadByte();
4652 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4656 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4686 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4689 default: NOT_REACHED();
4699 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4703 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4716 static void FeatureChangeInfo(
ByteReader *buf)
4729 static const VCI_Handler handler[] = {
4747 AirportTilesChangeInfo,
4751 static_assert(GSF_END ==
lengthof(handler));
4753 uint8 feature = buf->ReadByte();
4754 uint8 numprops = buf->ReadByte();
4755 uint numinfo = buf->ReadByte();
4756 uint engine = buf->ReadExtendedByte();
4758 if (feature >= GSF_END) {
4759 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4763 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4764 feature, numprops, engine, numinfo);
4766 if (handler[feature] ==
nullptr) {
4767 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4774 while (numprops-- && buf->HasData()) {
4775 uint8 prop = buf->ReadByte();
4778 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4785 uint8 feature = buf->ReadByte();
4786 uint8 numprops = buf->ReadByte();
4787 uint numinfo = buf->ReadByte();
4788 buf->ReadExtendedByte();
4790 if (feature == GSF_BRIDGES && numprops == 1) {
4791 uint8 prop = buf->ReadByte();
4794 if (prop == 0x0D)
return;
4795 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4796 uint8 prop = buf->ReadByte();
4799 bool is_safe =
true;
4800 for (uint i = 0; i < numinfo; i++) {
4801 uint32 s = buf->ReadDWord();
4809 if (is_safe)
return;
4820 static void ReserveChangeInfo(
ByteReader *buf)
4822 uint8 feature = buf->ReadByte();
4824 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4826 uint8 numprops = buf->ReadByte();
4827 uint8 numinfo = buf->ReadByte();
4828 uint8 index = buf->ReadExtendedByte();
4830 while (numprops-- && buf->HasData()) {
4831 uint8 prop = buf->ReadByte();
4835 default: NOT_REACHED();
4841 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4845 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4849 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4853 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4857 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4878 uint8 feature = buf->ReadByte();
4879 uint16 num_sets = buf->ReadByte();
4880 uint16 first_set = 0;
4882 if (num_sets == 0 && buf->HasData(3)) {
4885 first_set = buf->ReadExtendedByte();
4886 num_sets = buf->ReadExtendedByte();
4888 uint16 num_ents = buf->ReadExtendedByte();
4890 if (feature >= GSF_END) {
4892 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4898 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4899 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4902 for (
int i = 0; i < num_sets * num_ents; i++) {
4912 uint16 num_sets = buf->ReadByte();
4914 if (num_sets == 0 && buf->HasData(3)) {
4917 buf->ReadExtendedByte();
4918 num_sets = buf->ReadExtendedByte();
4920 uint16 num_ents = buf->ReadExtendedByte();
4929 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4931 if (
HasBit(groupid, 15)) {
4936 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4937 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4941 return _cur.spritegroups[groupid];
4954 if (
HasBit(spriteid, 15)) {
4960 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4965 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4968 assert(spriteset_start + num_sprites <= _cur.
spriteid);
4989 uint8 feature = buf->ReadByte();
4990 if (feature >= GSF_END) {
4991 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4995 uint8 setid = buf->ReadByte();
4996 uint8 type = buf->ReadByte();
5020 switch (
GB(type, 2, 2)) {
5021 default: NOT_REACHED();
5022 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5023 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5024 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5034 adjust.variable = buf->ReadByte();
5035 if (adjust.variable == 0x7E) {
5037 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5042 varadjust = buf->ReadByte();
5043 adjust.shift_num =
GB(varadjust, 0, 5);
5044 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5045 adjust.and_mask = buf->ReadVarSize(varsize);
5047 if (adjust.type != DSGA_TYPE_NONE) {
5048 adjust.add_val = buf->ReadVarSize(varsize);
5049 adjust.divmod_val = buf->ReadVarSize(varsize);
5052 adjust.divmod_val = 0;
5056 }
while (
HasBit(varadjust, 5));
5058 std::vector<DeterministicSpriteGroupRange> ranges;
5059 ranges.resize(buf->ReadByte());
5060 for (uint i = 0; i < ranges.size(); i++) {
5061 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5062 ranges[i].low = buf->ReadVarSize(varsize);
5063 ranges[i].high = buf->ReadVarSize(varsize);
5066 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5067 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5069 group->calculated_result = ranges.size() == 0;
5072 std::vector<uint32> bounds;
5073 for (uint i = 0; i < ranges.size(); i++) {
5074 bounds.push_back(ranges[i].low);
5075 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5077 std::sort(bounds.begin(), bounds.end());
5078 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5080 std::vector<const SpriteGroup *> target;
5081 for (uint j = 0; j < bounds.size(); ++j) {
5082 uint32 v = bounds[j];
5084 for (uint i = 0; i < ranges.size(); i++) {
5085 if (ranges[i].low <= v && v <= ranges[i].high) {
5086 t = ranges[i].group;
5090 target.push_back(t);
5092 assert(target.size() == bounds.size());
5094 for (uint j = 0; j < bounds.size(); ) {
5095 if (target[j] != group->default_group) {
5097 r.group = target[j];
5099 while (j < bounds.size() && target[j] == r.group) {
5102 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5124 group->count = buf->ReadByte();
5127 uint8 triggers = buf->ReadByte();
5128 group->triggers =
GB(triggers, 0, 7);
5129 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5132 byte num_groups = buf->ReadByte();
5134 grfmsg(1,
"NewSpriteGroup: Random Action 2 nrand should be power of 2");
5137 for (uint i = 0; i < num_groups; i++) {
5138 group->
groups.push_back(GetGroupFromGroupID(setid, type, buf->ReadWord()));
5149 case GSF_ROADVEHICLES:
5160 byte num_loaded = type;
5161 byte num_loading = buf->ReadByte();
5164 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5168 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5169 setid, num_loaded, num_loading);
5171 if (num_loaded + num_loading == 1) {
5173 uint16 spriteid = buf->ReadWord();
5175 grfmsg(8,
"NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
5179 std::vector<uint16> loaded;
5180 std::vector<uint16> loading;
5182 for (uint i = 0; i < num_loaded; i++) {
5183 loaded.push_back(buf->ReadWord());
5184 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, loaded[i]);
5187 for (uint i = 0; i < num_loading; i++) {
5188 loading.push_back(buf->ReadWord());
5189 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
5192 if (std::adjacent_find(loaded.begin(), loaded.end(), std::not_equal_to<>()) == loaded.end() &&
5193 std::adjacent_find(loading.begin(), loading.end(), std::not_equal_to<>()) == loading.end() &&
5194 loaded[0] == loading[0])
5198 grfmsg(8,
"NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
5207 for (uint16 spriteid : loaded) {
5209 group->
loaded.push_back(t);
5212 for (uint16 spriteid : loading) {
5221 case GSF_AIRPORTTILES:
5223 case GSF_INDUSTRYTILES: {
5224 byte num_building_sprites = std::max((uint8)1, type);
5232 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5236 case GSF_INDUSTRIES: {
5238 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5249 for (uint i = 0; i < 3; i++) {
5253 for (uint i = 0; i < 2; i++) {
5256 group->again = buf->ReadByte();
5257 }
else if (type == 1) {
5259 for (uint i = 0; i < 3; i++) {
5263 for (uint i = 0; i < 2; i++) {
5266 group->again = buf->ReadByte();
5267 }
else if (type == 2) {
5271 error->data =
"too many inputs (max 16)";
5274 for (uint i = 0; i < group->
num_input; i++) {
5275 byte rawcargo = buf->ReadByte();
5284 error->data =
"duplicate input cargo";
5293 error->data =
"too many outputs (max 16)";
5296 for (uint i = 0; i < group->
num_output; i++) {
5297 byte rawcargo = buf->ReadByte();
5304 error->data =
"duplicate output cargo";
5310 group->again = buf->ReadByte();
5318 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5323 _cur.spritegroups[setid] = act_group;
5326 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5328 if (feature == GSF_OBJECTS) {
5333 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5338 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5339 if (ctype == 0xFF)
return CT_PURCHASE;
5344 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5349 if (cs->bitnum == ctype) {
5350 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5355 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5361 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5368 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5374 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));
5378 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);
5383 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5385 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5386 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5393 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5396 static uint last_engines_count;
5397 bool wagover =
false;
5400 if (
HasBit(idcount, 7)) {
5403 idcount =
GB(idcount, 0, 7);
5405 if (last_engines_count == 0) {
5406 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5410 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5411 last_engines_count, idcount);
5413 if (last_engines_count != idcount) {
5414 last_engines =
ReallocT(last_engines, idcount);
5415 last_engines_count = idcount;
5420 for (uint i = 0; i < idcount; i++) {
5426 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5430 engines[i] = e->
index;
5431 if (!wagover) last_engines[i] = engines[i];
5434 uint8 cidcount = buf->ReadByte();
5435 for (uint c = 0; c < cidcount; c++) {
5436 uint8 ctype = buf->ReadByte();
5437 uint16 groupid = buf->ReadWord();
5438 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5440 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5442 ctype = TranslateCargo(feature, ctype);
5445 for (uint i = 0; i < idcount; i++) {
5448 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5451 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5453 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5458 uint16 groupid = buf->ReadWord();
5459 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5461 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5463 for (uint i = 0; i < idcount; i++) {
5467 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5469 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5476 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5479 for (uint i = 0; i < idcount; i++) {
5483 uint8 cidcount = buf->ReadByte();
5484 buf->Skip(cidcount * 3);
5486 uint16 groupid = buf->ReadWord();
5487 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5489 for (uint i = 0; i < idcount; i++) {
5493 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5503 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5505 uint8 *stations =
AllocaM(uint8, idcount);
5506 for (uint i = 0; i < idcount; i++) {
5507 stations[i] = buf->ReadByte();
5510 uint8 cidcount = buf->ReadByte();
5511 for (uint c = 0; c < cidcount; c++) {
5512 uint8 ctype = buf->ReadByte();
5513 uint16 groupid = buf->ReadWord();
5514 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5516 ctype = TranslateCargo(GSF_STATIONS, ctype);
5519 for (uint i = 0; i < idcount; i++) {
5522 if (statspec ==
nullptr) {
5523 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5531 uint16 groupid = buf->ReadWord();
5532 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5534 for (uint i = 0; i < idcount; i++) {
5537 if (statspec ==
nullptr) {
5538 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5543 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5550 StationClass::Assign(statspec);
5555 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5557 uint8 *houses =
AllocaM(uint8, idcount);
5558 for (uint i = 0; i < idcount; i++) {
5559 houses[i] = buf->ReadByte();
5563 uint8 cidcount = buf->ReadByte();
5564 buf->Skip(cidcount * 3);
5566 uint16 groupid = buf->ReadWord();
5567 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5569 if (_cur.
grffile->housespec ==
nullptr) {
5570 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5574 for (uint i = 0; i < idcount; i++) {
5577 if (hs ==
nullptr) {
5578 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5586 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5588 uint8 *industries =
AllocaM(uint8, idcount);
5589 for (uint i = 0; i < idcount; i++) {
5590 industries[i] = buf->ReadByte();
5594 uint8 cidcount = buf->ReadByte();
5595 buf->Skip(cidcount * 3);
5597 uint16 groupid = buf->ReadWord();
5598 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5600 if (_cur.
grffile->industryspec ==
nullptr) {
5601 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5605 for (uint i = 0; i < idcount; i++) {
5608 if (indsp ==
nullptr) {
5609 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5617 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5619 uint8 *indtiles =
AllocaM(uint8, idcount);
5620 for (uint i = 0; i < idcount; i++) {
5621 indtiles[i] = buf->ReadByte();
5625 uint8 cidcount = buf->ReadByte();
5626 buf->Skip(cidcount * 3);
5628 uint16 groupid = buf->ReadWord();
5629 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5631 if (_cur.
grffile->indtspec ==
nullptr) {
5632 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5636 for (uint i = 0; i < idcount; i++) {
5639 if (indtsp ==
nullptr) {
5640 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5648 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5651 for (uint i = 0; i < idcount; i++) {
5652 cargoes[i] = buf->ReadByte();
5656 uint8 cidcount = buf->ReadByte();
5657 buf->Skip(cidcount * 3);
5659 uint16 groupid = buf->ReadWord();
5660 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5662 for (uint i = 0; i < idcount; i++) {
5666 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5672 cs->group = _cur.spritegroups[groupid];
5676 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5678 if (_cur.
grffile->objectspec ==
nullptr) {
5679 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5683 uint8 *objects =
AllocaM(uint8, idcount);
5684 for (uint i = 0; i < idcount; i++) {
5685 objects[i] = buf->ReadByte();
5688 uint8 cidcount = buf->ReadByte();
5689 for (uint c = 0; c < cidcount; c++) {
5690 uint8 ctype = buf->ReadByte();
5691 uint16 groupid = buf->ReadWord();
5692 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5694 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5697 for (uint i = 0; i < idcount; i++) {
5700 if (spec ==
nullptr) {
5701 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5709 uint16 groupid = buf->ReadWord();
5710 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5712 for (uint i = 0; i < idcount; i++) {
5715 if (spec ==
nullptr) {
5716 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5721 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5731 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5733 uint8 *railtypes =
AllocaM(uint8, idcount);
5734 for (uint i = 0; i < idcount; i++) {
5735 uint8
id = buf->ReadByte();
5739 uint8 cidcount = buf->ReadByte();
5740 for (uint c = 0; c < cidcount; c++) {
5741 uint8 ctype = buf->ReadByte();
5742 uint16 groupid = buf->ReadWord();
5743 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5745 if (ctype >= RTSG_END)
continue;
5748 for (uint i = 0; i < idcount; i++) {
5753 rti->
group[ctype] = _cur.spritegroups[groupid];
5762 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5766 uint8 *roadtypes =
AllocaM(uint8, idcount);
5767 for (uint i = 0; i < idcount; i++) {
5768 uint8
id = buf->ReadByte();
5772 uint8 cidcount = buf->ReadByte();
5773 for (uint c = 0; c < cidcount; c++) {
5774 uint8 ctype = buf->ReadByte();
5775 uint16 groupid = buf->ReadWord();
5776 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5778 if (ctype >= ROTSG_END)
continue;
5781 for (uint i = 0; i < idcount; i++) {
5786 rti->
group[ctype] = _cur.spritegroups[groupid];
5795 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5797 uint8 *airports =
AllocaM(uint8, idcount);
5798 for (uint i = 0; i < idcount; i++) {
5799 airports[i] = buf->ReadByte();
5803 uint8 cidcount = buf->ReadByte();
5804 buf->Skip(cidcount * 3);
5806 uint16 groupid = buf->ReadWord();
5807 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5809 if (_cur.
grffile->airportspec ==
nullptr) {
5810 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5814 for (uint i = 0; i < idcount; i++) {
5817 if (as ==
nullptr) {
5818 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5826 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5828 uint8 *airptiles =
AllocaM(uint8, idcount);
5829 for (uint i = 0; i < idcount; i++) {
5830 airptiles[i] = buf->ReadByte();
5834 uint8 cidcount = buf->ReadByte();
5835 buf->Skip(cidcount * 3);
5837 uint16 groupid = buf->ReadWord();
5838 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5840 if (_cur.
grffile->airtspec ==
nullptr) {
5841 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5845 for (uint i = 0; i < idcount; i++) {
5848 if (airtsp ==
nullptr) {
5849 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5859 static void FeatureMapSpriteGroup(
ByteReader *buf)
5875 uint8 feature = buf->ReadByte();
5876 uint8 idcount = buf->ReadByte();
5878 if (feature >= GSF_END) {
5879 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5887 uint16 groupid = buf->ReadWord();
5888 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5890 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5899 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5903 case GSF_ROADVEHICLES:
5906 VehicleMapSpriteGroup(buf, feature, idcount);
5910 CanalMapSpriteGroup(buf, idcount);
5914 StationMapSpriteGroup(buf, idcount);
5918 TownHouseMapSpriteGroup(buf, idcount);
5921 case GSF_INDUSTRIES:
5922 IndustryMapSpriteGroup(buf, idcount);
5925 case GSF_INDUSTRYTILES:
5926 IndustrytileMapSpriteGroup(buf, idcount);
5930 CargoMapSpriteGroup(buf, idcount);
5934 AirportMapSpriteGroup(buf, idcount);
5938 ObjectMapSpriteGroup(buf, idcount);
5942 RailTypeMapSpriteGroup(buf, idcount);
5946 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5950 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5953 case GSF_AIRPORTTILES:
5954 AirportTileMapSpriteGroup(buf, idcount);
5958 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5982 bool new_scheme = _cur.
grffile->grf_version >= 7;
5984 uint8 feature = buf->ReadByte();
5985 if (feature >= GSF_END && feature != 0x48) {
5986 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5990 uint8 lang = buf->ReadByte();
5991 uint8 num = buf->ReadByte();
5992 bool generic =
HasBit(lang, 7);
5995 id = buf->ReadWord();
5996 }
else if (feature <= GSF_AIRCRAFT) {
5997 id = buf->ReadExtendedByte();
5999 id = buf->ReadByte();
6004 uint16 endid =
id + num;
6006 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
6007 id, endid, feature, lang);
6009 for (;
id < endid && buf->HasData();
id++) {
6010 const char *name = buf->ReadString();
6011 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6015 case GSF_ROADVEHICLES:
6020 if (e ==
nullptr)
break;
6034 switch (
GB(
id, 8, 8)) {
6036 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6037 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6045 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6046 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6053 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6054 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6061 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6062 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6069 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6088 if (offset >= max_sprites) {
6089 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6090 uint orig_num = num;
6095 if (offset + num > max_sprites) {
6096 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6097 uint orig_num = num;
6098 num = std::max(max_sprites - offset, 0);
6099 return orig_num - num;
6128 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6130 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6160 uint8 type = buf->ReadByte();
6161 uint16 num = buf->ReadExtendedByte();
6162 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6168 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6185 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6196 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6203 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);
6213 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);
6224 for (; num > 0; num--) {
6295 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6325 *value = _game_mode;
6359 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6368 *value = _openttd_newgrf_version;
6383 default:
return false;
6387 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6405 if (cond_val ==
nullptr) {
6409 uint32 index = *cond_val / 0x20;
6425 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6446 size_t pos = file.
GetPos();
6449 byte *preload_sprite =
nullptr;
6453 preload_sprite = MallocT<byte>(num);
6458 file.
SeekTo(pos, SEEK_SET);
6461 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6462 free(preload_sprite);
6467 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6468 if (it != _grf_line_to_action6_sprite_override.end()) {
6469 free(preload_sprite);
6470 preload_sprite = _grf_line_to_action6_sprite_override[location];
6472 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6485 param_num = buf->ReadByte();
6486 if (param_num == 0xFF)
break;
6490 param_size = buf->ReadByte();
6494 add_value =
HasBit(param_size, 7);
6495 param_size =
GB(param_size, 0, 7);
6498 offset = buf->ReadExtendedByte();
6502 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6503 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6507 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6510 for (i = 0; i < param_size && offset + i < num; i++) {
6511 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6514 if (i % 4 == 0) carry =
false;
6517 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6518 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6520 carry = new_value >= 256;
6522 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6554 uint32 cond_val = 0;
6558 uint8 param = buf->ReadByte();
6559 uint8 paramsize = buf->ReadByte();
6560 uint8 condtype = buf->ReadByte();
6567 switch (paramsize) {
6568 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6569 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6570 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6571 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6575 if (param < 0x80 && _cur.grffile->param_end <= param) {
6576 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6580 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6585 if (condtype >= 0x0B) {
6616 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6618 }
else if (param == 0x88) {
6628 if (condtype != 10 && c ==
nullptr) {
6629 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6656 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6660 uint32 param_val = GetParamVal(param, &cond_val);
6662 case 0x00: result = !!(param_val & (1 << cond_val));
6664 case 0x01: result = !(param_val & (1 << cond_val));
6666 case 0x02: result = (param_val & mask) == cond_val;
6668 case 0x03: result = (param_val & mask) != cond_val;
6670 case 0x04: result = (param_val & mask) < cond_val;
6672 case 0x05: result = (param_val & mask) > cond_val;
6674 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6679 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6683 uint8 numsprites = buf->ReadByte();
6691 if (label->label != numsprites)
continue;
6694 if (choice ==
nullptr) choice = label;
6696 if (label->nfo_line > _cur.
nfo_line) {
6702 if (choice !=
nullptr) {
6703 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6709 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6728 uint8 grf_version = buf->ReadByte();
6729 uint32 grfid = buf->ReadDWord();
6730 const char *name = buf->ReadString();
6734 if (grf_version < 2 || grf_version > 8) {
6736 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);
6744 if (buf->HasData()) {
6745 const char *info = buf->ReadString();
6763 uint8 version = buf->ReadByte();
6764 uint32 grfid = buf->ReadDWord();
6765 const char *name = buf->ReadString();
6768 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6772 if (_cur.
grffile->grfid != grfid) {
6773 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));
6777 _cur.
grffile->grf_version = version;
6795 uint8 num_sets = buf->ReadByte();
6797 for (uint i = 0; i < num_sets; i++) {
6798 uint8 num_sprites = buf->ReadByte();
6799 uint16 first_sprite = buf->ReadWord();
6801 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6802 i, num_sprites, first_sprite
6805 for (uint j = 0; j < num_sprites; j++) {
6806 int load_index = first_sprite + j;
6812 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6822 uint8 num_sets = buf->ReadByte();
6824 for (uint i = 0; i < num_sets; i++) {
6853 STR_NEWGRF_ERROR_VERSION_NUMBER,
6854 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6855 STR_NEWGRF_ERROR_UNSET_SWITCH,
6856 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6857 STR_NEWGRF_ERROR_LOAD_BEFORE,
6858 STR_NEWGRF_ERROR_LOAD_AFTER,
6859 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6863 STR_NEWGRF_ERROR_MSG_INFO,
6864 STR_NEWGRF_ERROR_MSG_WARNING,
6865 STR_NEWGRF_ERROR_MSG_ERROR,
6866 STR_NEWGRF_ERROR_MSG_FATAL
6869 byte severity = buf->ReadByte();
6870 byte lang = buf->ReadByte();
6871 byte message_id = buf->ReadByte();
6874 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6878 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6879 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6884 if (severity >=
lengthof(sevstr)) {
6885 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6887 }
else if (severity == 3) {
6897 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6898 grfmsg(7,
"GRFLoadError: Invalid message id.");
6902 if (buf->Remaining() <= 1) {
6903 grfmsg(7,
"GRFLoadError: No message data supplied.");
6912 if (message_id == 0xFF) {
6914 if (buf->HasData()) {
6915 const char *message = buf->ReadString();
6919 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6920 error->custom_message.clear();
6923 error->message = msgstr[message_id];
6926 if (buf->HasData()) {
6927 const char *data = buf->ReadString();
6931 grfmsg(7,
"GRFLoadError: No message data supplied.");
6932 error->data.clear();
6936 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6937 uint param_number = buf->ReadByte();
6951 if (!buf->HasData())
return;
6953 const char *text = buf->ReadString();
6954 grfmsg(2,
"GRFComment: %s", text);
6960 uint8 target = buf->ReadByte();
6963 if (target < 0x80 || target == 0x9E)
return;
6977 static uint32 GetPatchVariable(uint8 param)
6987 case 0x0F:
return 0;
7003 case 0x11:
return SPR_2CCMAP_BASE;
7020 byte max_edge = std::max(log_X, log_Y);
7022 if (log_X == log_Y) {
7025 if (max_edge == log_Y)
SetBit(map_bits, 1);
7028 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7029 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7038 return SPR_SLOPES_BASE;
7045 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7051 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7064 for (uint i = start; i < num_ids; i++) {
7068 if (op == 2 || op == 3)
break;
7073 if (size == count)
break;
7076 if (size == count) {
7078 if (op == 0 || op == 3) {
7079 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7080 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7086 if (op != 4 && op != 5) {
7088 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7093 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7123 uint8 target = buf->ReadByte();
7124 uint8 oper = buf->ReadByte();
7125 uint32 src1 = buf->ReadByte();
7126 uint32 src2 = buf->ReadByte();
7129 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7138 if (target < 0x80 && target < _cur.grffile->param_end) {
7139 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7143 oper =
GB(oper, 0, 7);
7147 if (
GB(data, 0, 8) == 0xFF) {
7148 if (data == 0x0000FFFF) {
7150 src1 = GetPatchVariable(src1);
7154 uint8 feature =
GB(data, 8, 8);
7155 uint16 count =
GB(data, 16, 16);
7157 if (_cur.
stage == GLS_RESERVE) {
7158 if (feature == 0x08) {
7162 if (_cur.
spriteid + count >= 16384) {
7163 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7169 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7176 }
else if (_cur.
stage == GLS_ACTIVATION) {
7205 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7213 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7224 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7241 }
else if (src1 == 0xFE) {
7253 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7254 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7276 res = (int32)src1 * (int32)src2;
7280 if ((int32)src2 < 0) {
7281 res = src1 >> -(int32)src2;
7283 res = src1 << (src2 & 0x1F);
7288 if ((int32)src2 < 0) {
7289 res = (int32)src1 >> -(int32)src2;
7291 res = (int32)src1 << (src2 & 0x1F);
7315 res = (int32)src1 / (int32)src2;
7331 res = (int32)src1 % (int32)src2;
7335 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7364 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7375 uint32 safe_bits = 0;
7376 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7385 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7389 if (target < 0x80) {
7390 _cur.
grffile->param[target] = res;
7394 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7408 uint8 num = buf->ReadByte();
7410 for (uint i = 0; i < num; i++) {
7411 uint32 grfid = buf->ReadDWord();
7433 uint8 num = buf->ReadByte();
7435 for (uint i = 0; i < num; i++) {
7436 uint32 grfid = buf->ReadDWord();
7440 if (file !=
nullptr && file != _cur.
grfconfig) {
7458 uint32 grfid = _cur.
grffile->grfid;
7462 byte id = buf->ReadByte();
7463 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7468 bool new_scheme = _cur.
grffile->grf_version >= 7;
7470 byte lang = buf->ReadByte();
7472 byte nb_gen = townname->nb_gen;
7476 const char *name = buf->ReadString();
7479 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7481 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7483 lang = buf->ReadByte();
7484 }
while (lang != 0);
7485 townname->id[nb_gen] = id;
7489 byte nb = buf->ReadByte();
7490 grfmsg(6,
"FeatureTownName: %u parts", nb);
7492 townname->nbparts[id] = nb;
7493 townname->partlist[id] = CallocT<NamePartList>(nb);
7495 for (
int i = 0; i < nb; i++) {
7496 byte nbtext = buf->ReadByte();
7497 townname->partlist[id][i].bitstart = buf->ReadByte();
7498 townname->partlist[id][i].bitcount = buf->ReadByte();
7499 townname->partlist[id][i].maxprob = 0;
7500 townname->partlist[id][i].partcount = nbtext;
7501 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7502 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);
7504 for (
int j = 0; j < nbtext; j++) {
7505 byte prob = buf->ReadByte();
7508 byte ref_id = buf->ReadByte();
7510 if (townname->nbparts[ref_id] == 0) {
7511 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7512 DelGRFTownName(grfid);
7517 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7518 townname->partlist[id][i].parts[j].data.
id = ref_id;
7520 const char *text = buf->ReadString();
7522 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7524 townname->partlist[id][i].parts[j].
prob = prob;
7525 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7527 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7539 byte nfo_label = buf->ReadByte();
7541 GRFLabel *label = MallocT<GRFLabel>(1);
7542 label->label = nfo_label;
7545 label->next =
nullptr;
7553 for (l = _cur.
grffile->
label; l->next !=
nullptr; l = l->next) {}
7557 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7571 if (file ==
nullptr || file->sound_offset == 0) {
7572 grfmsg(1,
"ImportGRFSound: Source file not available");
7576 if (sound_id >= file->num_sounds) {
7577 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7581 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7583 *sound = *GetSound(file->sound_offset + sound_id);
7586 sound->volume = 128;
7587 sound->priority = 0;
7598 sound->volume = 0x80;
7599 sound->priority = 0;
7601 if (offs != SIZE_MAX) {
7603 sound->file = _cur.
file;
7604 sound->file_offset = offs;
7616 uint16 num = buf->ReadWord();
7617 if (num == 0)
return;
7620 if (_cur.
grffile->sound_offset == 0) {
7621 _cur.
grffile->sound_offset = GetNumSounds();
7622 _cur.
grffile->num_sounds = num;
7625 sound = GetSound(_cur.
grffile->sound_offset);
7630 for (
int i = 0; i < num; i++) {
7635 bool invalid = i >= _cur.
grffile->num_sounds;
7637 size_t offs = file.
GetPos();
7642 if (grf_container_version >= 2 && type == 0xFD) {
7645 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7647 }
else if (len != 4) {
7648 grfmsg(1,
"GRFSound: Invalid sprite section import");
7658 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7665 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7673 if (_cur.
stage == GLS_INIT) {
7674 if (grf_container_version >= 2) {
7675 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7684 if (_cur.
stage == GLS_ACTIVATION) {
7687 if (file.
ReadByte() != 0)
grfmsg(1,
"GRFSound: Import type mismatch");
7695 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7724 uint8 num_def = buf->ReadByte();
7726 for (uint i = 0; i < num_def; i++) {
7728 uint8 num_char = buf->ReadByte();
7729 uint16 base_char = buf->ReadWord();
7731 if (size >= FS_END) {
7732 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7735 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7737 for (uint c = 0; c < num_char; c++) {
7755 uint8 num_def = buf->ReadByte();
7757 for (uint i = 0; i < num_def; i++) {
7781 uint32 grfid = buf->ReadDWord();
7784 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7793 error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7803 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7804 byte num_strings = buf->ReadByte();
7805 uint16 first_id = buf->ReadWord();
7807 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7808 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7812 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7813 const char *
string = buf->ReadString();
7816 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7820 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7849 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7861 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7864 char data = buf->ReadByte();
7872 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7887 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7890 char data = buf->ReadByte();
7896 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7909 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7922 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7927 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7958 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7965 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7975 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7977 }
else if (len != 8) {
7978 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
7981 uint32 min_value = buf->ReadDWord();
7982 uint32 max_value = buf->ReadDWord();
7983 if (min_value <= max_value) {
7987 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7996 if (len < 1 || len > 3) {
7997 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
8000 byte param_nr = buf->ReadByte();
8002 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8018 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8054 this->handler.data = handler;
8066 this->handler.text = handler;
8078 this->handler.call_handler =
true;
8079 this->handler.u.branch = handler;
8091 this->handler.call_handler =
false;
8092 this->handler.u.subtags =
subtags;
8121 byte type = buf->ReadByte();
8123 uint32
id = buf->ReadDWord();
8125 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8127 type = buf->ReadByte();
8131 byte langid = buf->ReadByte();
8132 const char *name_string = buf->ReadString();
8143 type = buf->ReadByte();
8168 byte type = buf->ReadByte();
8170 uint32
id = buf->ReadDWord();
8172 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8174 type = buf->ReadByte();
8187 type = buf->ReadByte();
8224 byte new_type = buf->ReadByte();
8225 while (new_type != 0) {
8228 new_type = buf->ReadByte();
8239 uint16 size = buf->ReadWord();
8263 while ((tag = &subtags[i++])->type != 0) {
8266 default: NOT_REACHED();
8269 byte langid = buf->ReadByte();
8270 return tag->handler.
text(langid, buf->ReadString());
8274 size_t len = buf->ReadWord();
8275 if (buf->Remaining() < len)
return false;
8276 return tag->handler.
data(len, buf);
8281 return tag->handler.u.branch(buf);
8287 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8299 byte type = buf->ReadByte();
8301 uint32
id = buf->ReadDWord();
8302 if (!
HandleNode(type,
id, buf, subtags))
return false;
8303 type = buf->ReadByte();
8425 if (stations ==
nullptr)
continue;
8427 if (stations[i] ==
nullptr)
continue;
8444 HouseSpec **&housespec = file->housespec;
8445 if (housespec ==
nullptr)
continue;
8451 housespec =
nullptr;
8460 if (aslist !=
nullptr) {
8464 if (as !=
nullptr) {
8466 for (
int j = 0; j < as->
num_table; j++) {
8478 file->airportspec =
nullptr;
8482 if (airporttilespec !=
nullptr) {
8484 free(airporttilespec[i]);
8486 free(airporttilespec);
8487 airporttilespec =
nullptr;
8501 if (industryspec !=
nullptr) {
8508 industryspec =
nullptr;
8511 if (indtspec ==
nullptr)
continue;
8526 if (objectspec ==
nullptr)
continue;
8528 free(objectspec[i]);
8532 objectspec =
nullptr;
8564 CleanUpGRFTownNames();
8608 ObjectClass::Reset();
8613 StationClass::Reset();
8617 AirportClass::Reset();
8646 _grf_id_overrides.clear();
8648 InitializeSoundPool();
8696 if (newfile !=
nullptr) {
8702 newfile =
new GRFFile(config);
8720 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8725 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8732 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8736 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8752 free(this->filename);
8762 CargoTypes original_known_cargoes = 0;
8763 for (
int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
8771 bool only_defaultcargo;
8774 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
8777 static constexpr
byte T = 1 << LT_TEMPERATE;
8778 static constexpr
byte A = 1 << LT_ARCTIC;
8779 static constexpr
byte S = 1 << LT_TROPIC;
8780 static constexpr
byte Y = 1 << LT_TOYLAND;
8781 static const struct DefaultRefitMasks {
8784 CargoTypes cargo_allowed;
8785 CargoTypes cargo_disallowed;
8786 } _default_refit_masks[] = {
8788 {T | A | S , CT_MAIL,
CC_MAIL, 0},
8791 {T | A , CT_COAL,
CC_BULK, 0},
8792 { S , CT_COPPER_ORE,
CC_BULK, 0},
8807 switch (ei->cargo_type) {
8811 _gted[engine].cargo_disallowed = 0;
8816 _gted[engine].cargo_disallowed = 0;
8835 _gted[engine].cargo_disallowed = 0;
8838 for (
const auto &drm : _default_refit_masks) {
8840 if (drm.cargo_type != ei->cargo_type)
continue;
8842 _gted[engine].cargo_allowed = drm.cargo_allowed;
8843 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
8860 CargoTypes mask = 0;
8861 CargoTypes not_mask = 0;
8862 CargoTypes xor_mask = ei->refit_mask;
8868 if (
_gted[engine].cargo_allowed != 0) {
8871 if (
_gted[engine].cargo_allowed & cs->classes)
SetBit(mask, cs->Index());
8872 if (
_gted[engine].cargo_disallowed & cs->classes)
SetBit(not_mask, cs->Index());
8876 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8894 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8896 const uint8 *cargo_map_for_first_refittable =
nullptr;
8899 if (file ==
nullptr) file = e->
GetGRF();
8900 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8901 cargo_map_for_first_refittable = file->
cargo_map;
8905 if (cargo_map_for_first_refittable !=
nullptr) {
8907 byte best_local_slot = 0xFF;
8909 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8910 if (local_slot < best_local_slot) {
8911 best_local_slot = local_slot;
8912 ei->cargo_type = cargo_type;
8934 for (uint i = 0; i < CF_END; i++) {
8946 if (e->
GetGRF() ==
nullptr) {
8949 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
8984 default: NOT_REACHED();
8998 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8999 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
9023 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
9033 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);
9041 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9048 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);
9067 if (hs ==
nullptr || !hs->
enabled)
continue;
9072 if (min_year == 0)
return;
9076 if (hs ==
nullptr || !hs->
enabled)
continue;
9100 HouseSpec **&housespec = file->housespec;
9101 if (housespec ==
nullptr)
continue;
9106 if (hs ==
nullptr)
continue;
9164 if (industryspec !=
nullptr) {
9168 if (indsp !=
nullptr && indsp->
enabled) {
9174 if (strid != STR_UNDEFINED) indsp->
name = strid;
9177 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9192 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9200 if (indtspec !=
nullptr) {
9203 if (indtsp !=
nullptr) {
9204 _industile_mngr.SetEntitySpec(indtsp);
9213 for (uint i = 0; i < 3; i++) {
9218 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9232 if (objectspec !=
nullptr) {
9234 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9251 if (airportspec !=
nullptr) {
9253 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9254 _airport_mngr.SetEntitySpec(airportspec[i]);
9260 if (airporttilespec !=
nullptr) {
9262 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9263 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9276 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9290 static const SpecialSpriteHandler handlers[][GLS_END] = {
9291 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9292 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9293 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9294 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9295 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9296 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9297 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9298 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9299 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9300 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9301 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9302 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9303 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9305 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9308 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9311 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9316 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9317 if (it == _grf_line_to_action6_sprite_override.end()) {
9323 buf = _grf_line_to_action6_sprite_override[location];
9324 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9334 byte action = bufp->ReadByte();
9336 if (action == 0xFF) {
9337 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9338 }
else if (action == 0xFE) {
9339 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9340 }
else if (action >=
lengthof(handlers)) {
9341 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9342 }
else if (handlers[action][stage] ==
nullptr) {
9343 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9345 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9346 handlers[action][stage](bufp);
9349 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9365 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config->
filename);
9368 if (grf_container_version == 0) {
9369 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9373 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9379 if (grf_container_version >= 2) file.
ReadDword();
9382 if (grf_container_version >= 2) {
9384 byte compression = file.
ReadByte();
9385 if (compression != 0) {
9386 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9395 if (num == 4 && file.
ReadByte() == 0xFF) {
9398 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9406 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
9412 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9423 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9424 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9428 if (grf_container_version >= 2 && type == 0xFD) {
9451 const char *filename = config->
filename;
9462 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9464 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9471 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
9525 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9526 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9527 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9528 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9529 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9530 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9541 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9545 int *grf_overrides =
AllocaM(
int, num_grfs);
9546 for (
int i = 0; i < num_grfs; i++) {
9547 grf_overrides[i] = -1;
9550 uint32
override = _grf_id_overrides[source->grfid];
9551 if (
override == 0)
continue;
9554 if (dest ==
nullptr)
continue;
9557 assert(grf_overrides[i] >= 0);
9561 for (
int i = 0; i < num_grfs; i++) {
9562 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9570 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9573 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
9579 for (
int i = num_grfs - 1; i >= 0; i--) {
9580 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9588 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9591 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
9597 for (
int i = 0; i < num_grfs; i++) {
9598 if (grf_overrides[i] < 0)
continue;
9606 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9607 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9609 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
9617 if (file->grf_version >= 8)
continue;
9618 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9619 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9621 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9624 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9631 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9632 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9633 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9635 price_base_multipliers[p] = 0;
9640 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file->
filename, p);
9642 price_base_multipliers[p] = 0;
9644 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file->
filename, p);
9659 _string_to_grf_mapping.clear();
9662 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9665 _grf_line_to_action6_sprite_override.clear();
9728 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9737 if (
_gted[e->
index].roadtramtype < list->size())
9739 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9757 e->u.rail.railtype = railtype;
9767 _grm_sprites.clear();
9815 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9822 if (stage == GLS_RESERVE) {
9823 static const uint32 overrides[][2] = {
9824 { 0x44442202, 0x44440111 },
9825 { 0x6D620402, 0x6D620401 },
9826 { 0x4D656f20, 0x4D656F17 },
9828 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9834 uint num_non_static = 0;
9843 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->
filename);
9852 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9854 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9863 if (stage == GLS_RESERVE) {
9865 }
else if (stage == GLS_ACTIVATION) {
9870 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur.
spriteid);