51 #include "table/strings.h"
68 const std::vector<GRFFile *> &GetAllGRFFiles()
118 this->skip_sprites = 0;
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
124 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.
sprite = first_sprite + i * numents;
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
179 return this->spritesets[feature].find(set)->second.sprite;
191 return this->spritesets[feature].find(set)->second.num_sprites;
204 template <VehicleType T>
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
219 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
221 inline byte ReadByte()
223 if (data < end)
return *(data)++;
229 uint16 val = ReadByte();
230 return val | (ReadByte() << 8);
233 uint16 ReadExtendedByte()
235 uint16 val = ReadByte();
236 return val == 0xFF ? ReadWord() : val;
241 uint32 val = ReadWord();
242 return val | (ReadWord() << 16);
245 uint32 ReadVarSize(
byte size)
248 case 1:
return ReadByte();
249 case 2:
return ReadWord();
250 case 4:
return ReadDWord();
257 const char *ReadString()
259 char *
string =
reinterpret_cast<char *
>(data);
260 size_t string_length =
ttd_strnlen(
string, Remaining());
262 if (string_length == Remaining()) {
264 string[string_length - 1] =
'\0';
265 grfmsg(7,
"String was not terminated with a zero byte.");
275 inline size_t Remaining()
const
280 inline bool HasData(
size_t count = 1)
const
282 return data + count <= end;
290 inline void Skip(
size_t len)
299 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
312 uint16 cargo_allowed;
313 uint16 cargo_disallowed;
314 RailTypeLabel railtypelabel;
331 }
else if (this->refittability ==
UNSET) {
332 this->refittability =
EMPTY;
352 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
356 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
361 return this->grfid == other.grfid && this->nfoline == other.nfoline;
365 static std::map<GRFLocation, SpriteID> _grm_sprites;
366 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
367 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
379 void CDECL
grfmsg(
int severity,
const char *str, ...)
399 if (file->grfid == grfid)
return file;
412 if (strcmp(file->filename, filename) == 0)
return file;
438 if (config !=
nullptr) {
449 if (message != STR_NULL) {
450 delete config->error;
451 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
455 return config->error;
466 typedef std::vector<StringIDMapping> StringIDMappingVector;
467 static StringIDMappingVector _string_to_grf_mapping;
476 *target = STR_UNDEFINED;
477 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
490 static const StringID units_volume[] = {
491 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 static_assert(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
531 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535 #undef TEXTID_TO_STRINGID
537 if (str == STR_NULL)
return STR_EMPTY;
539 DEBUG(grf, 0,
"Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
578 static std::map<uint32, uint32> _grf_id_overrides;
587 _grf_id_overrides[source_grfid] = target_grfid;
588 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
603 uint32 scope_grfid = INVALID_GRFID;
606 scope_grfid = file->grfid;
607 uint32
override = _grf_id_overrides[file->grfid];
609 scope_grfid =
override;
611 if (grf_match ==
nullptr) {
612 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
619 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
628 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
634 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
638 if (!static_access) {
640 eid->
grfid = scope_grfid;
646 if (static_access)
return nullptr;
649 grfmsg(0,
"Can't allocate any more engines");
660 assert(_engine_mngr.size() == e->
index);
661 _engine_mngr.push_back({
674 memset(
_gted + engine_pool_size, 0, len);
680 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
697 uint32 scope_grfid = INVALID_GRFID;
699 scope_grfid = file->grfid;
700 uint32
override = _grf_id_overrides[file->grfid];
701 if (
override != 0) scope_grfid =
override;
704 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
744 grf_sprite->
sprite = buf->ReadWord();
745 grf_sprite->
pal = buf->ReadWord();
750 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
754 uint index =
GB(grf_sprite->
sprite, 0, 14);
756 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757 grf_sprite->
sprite = SPR_IMG_QUERY;
758 grf_sprite->
pal = PAL_NONE;
761 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
766 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
773 uint index =
GB(grf_sprite->
pal, 0, 14);
775 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776 grf_sprite->
pal = PAL_NONE;
779 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
784 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
814 regs.delta.
parent[0] = buf->ReadByte();
815 regs.delta.
parent[1] = buf->ReadByte();
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
855 bool has_flags =
HasBit(num_building_sprites, 6);
856 ClrBit(num_building_sprites, 6);
859 dts->
Allocate(num_building_sprites);
861 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
862 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
863 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
871 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
879 for (uint i = 0; i < num_building_sprites; i++) {
882 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
885 if (flags & ~valid_flags) {
886 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
891 seq->
delta_x = buf->ReadByte();
892 seq->delta_y = buf->ReadByte();
894 if (!no_z_position) seq->
delta_z = buf->ReadByte();
897 seq->size_x = buf->ReadByte();
898 seq->size_y = buf->ReadByte();
899 seq->size_z = buf->ReadByte();
907 bool is_consistent =
true;
909 for (uint i = 0; i < num_building_sprites + 1; i++) {
910 if (max_sprite_offset[i] > 0) {
914 is_consistent =
false;
918 if (max_palette_offset[i] > 0) {
922 is_consistent =
false;
931 if (!is_consistent || dts->registers !=
nullptr) {
935 for (uint i = 0; i < num_building_sprites + 1; i++) {
950 CargoTypes result = 0;
969 if (base_pointer == 0) {
970 *index = INVALID_PRICE;
974 static const uint32 start = 0x4B34;
975 static const uint32 size = 6;
977 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
982 *index = (
Price)((base_pointer - start) / size);
1011 ei->decay_speed = buf->ReadByte();
1028 ei->load_amount = buf->ReadByte();
1050 for (
int i = 0; i < numinfo; i++) {
1059 uint8 tracktype = buf->ReadByte();
1061 if (tracktype < _cur.grffile->railtype_list.size()) {
1066 switch (tracktype) {
1067 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1068 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1069 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1071 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1084 uint16 speed = buf->ReadWord();
1085 if (speed == 0xFFFF) speed = 0;
1092 rvi->
power = buf->ReadWord();
1095 if (rvi->
power != 0) {
1113 uint8 spriteid = buf->ReadByte();
1114 uint8 orig_spriteid = spriteid;
1118 if (spriteid < 0xFD) spriteid >>= 1;
1120 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121 rvi->image_index = spriteid;
1123 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124 rvi->image_index = 0;
1130 uint8 dual = buf->ReadByte();
1135 rvi->railveh_type = rvi->
power == 0 ?
1147 uint8 ctype = buf->ReadByte();
1149 if (ctype == 0xFF) {
1152 }
else if (_cur.
grffile->grf_version >= 8) {
1157 ei->cargo_type = ctype;
1160 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1166 SB(rvi->
weight, 0, 8, buf->ReadByte());
1174 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1186 uint8 traction = buf->ReadByte();
1189 if (traction <= 0x07) {
1191 }
else if (traction <= 0x27) {
1193 }
else if (traction <= 0x31) {
1195 }
else if (traction <= 0x37) {
1197 }
else if (traction <= 0x41) {
1223 ei->refit_cost = buf->ReadByte();
1227 uint32 mask = buf->ReadDWord();
1265 byte weight = buf->ReadByte();
1268 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1290 _gted[e->
index].cargo_allowed = buf->ReadWord();
1296 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1310 uint8 count = buf->ReadByte();
1344 for (
int i = 0; i < numinfo; i++) {
1355 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1363 rvi->running_cost = buf->ReadByte();
1371 uint8 spriteid = buf->ReadByte();
1372 uint8 orig_spriteid = spriteid;
1375 if (spriteid == 0xFF) spriteid = 0xFD;
1377 if (spriteid < 0xFD) spriteid >>= 1;
1379 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1380 rvi->image_index = spriteid;
1382 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1383 rvi->image_index = 0;
1389 rvi->capacity = buf->ReadByte();
1394 uint8 ctype = buf->ReadByte();
1396 if (ctype == 0xFF) {
1399 }
else if (_cur.
grffile->grf_version >= 8) {
1404 ei->cargo_type = ctype;
1407 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1413 rvi->cost_factor = buf->ReadByte();
1421 rvi->
power = buf->ReadByte();
1425 rvi->
weight = buf->ReadByte();
1433 uint32 mask = buf->ReadDWord();
1453 ei->refit_cost = buf->ReadByte();
1466 _gted[e->
index].cargo_allowed = buf->ReadWord();
1472 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1504 uint8 count = buf->ReadByte();
1538 for (
int i = 0; i < numinfo; i++) {
1547 uint8 spriteid = buf->ReadByte();
1548 uint8 orig_spriteid = spriteid;
1551 if (spriteid == 0xFF) spriteid = 0xFD;
1553 if (spriteid < 0xFD) spriteid >>= 1;
1555 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1556 svi->image_index = spriteid;
1558 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1559 svi->image_index = 0;
1569 svi->cost_factor = buf->ReadByte();
1578 uint8 ctype = buf->ReadByte();
1580 if (ctype == 0xFF) {
1583 }
else if (_cur.
grffile->grf_version >= 8) {
1588 ei->cargo_type = ctype;
1591 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1597 svi->capacity = buf->ReadWord();
1601 svi->running_cost = buf->ReadByte();
1609 uint32 mask = buf->ReadDWord();
1621 ei->refit_cost = buf->ReadByte();
1642 _gted[e->
index].cargo_allowed = buf->ReadWord();
1648 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1676 uint8 count = buf->ReadByte();
1710 for (
int i = 0; i < numinfo; i++) {
1719 uint8 spriteid = buf->ReadByte();
1720 uint8 orig_spriteid = spriteid;
1723 if (spriteid == 0xFF) spriteid = 0xFD;
1725 if (spriteid < 0xFD) spriteid >>= 1;
1727 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1728 avi->image_index = spriteid;
1730 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1731 avi->image_index = 0;
1737 if (buf->ReadByte() == 0) {
1745 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1749 avi->cost_factor = buf->ReadByte();
1753 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1757 avi->acceleration = buf->ReadByte();
1761 avi->running_cost = buf->ReadByte();
1777 uint32 mask = buf->ReadDWord();
1789 ei->refit_cost = buf->ReadByte();
1802 _gted[e->
index].cargo_allowed = buf->ReadWord();
1808 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1826 uint8 count = buf->ReadByte();
1872 for (
int i = 0; i < numinfo; i++) {
1876 if (statspec ==
nullptr && prop != 0x08) {
1877 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1886 if (*spec ==
nullptr) *spec = CallocT<StationSpec>(1);
1889 uint32 classid = buf->ReadDWord();
1890 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1895 statspec->
tiles = buf->ReadExtendedByte();
1899 for (uint t = 0; t < statspec->
tiles; t++) {
1903 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1906 dts->
Clone(&_station_display_datas_rail[t % 8]);
1914 static std::vector<DrawTileSeqStruct> tmp_layout;
1921 dtss.
delta_x = buf->ReadByte();
1923 dtss.delta_y = buf->ReadByte();
1924 dtss.
delta_z = buf->ReadByte();
1925 dtss.size_x = buf->ReadByte();
1926 dtss.size_y = buf->ReadByte();
1927 dtss.size_z = buf->ReadByte();
1933 dts->
Clone(tmp_layout.data());
1938 byte srcid = buf->ReadByte();
1941 if (srcstatspec ==
nullptr) {
1942 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1950 for (uint t = 0; t < statspec->
tiles; t++) {
1969 statspec->copied_layouts =
false;
1971 while (buf->HasData()) {
1972 byte length = buf->ReadByte();
1973 byte number = buf->ReadByte();
1974 StationLayout layout;
1977 if (length == 0 || number == 0)
break;
1979 if (length > statspec->lengths) {
1980 byte diff_length = length - statspec->lengths;
1981 statspec->platforms =
ReallocT(statspec->platforms, length);
1982 memset(statspec->platforms + statspec->lengths, 0, diff_length);
1984 statspec->layouts =
ReallocT(statspec->layouts, length);
1985 memset(statspec->layouts + statspec->lengths, 0, diff_length *
sizeof(*statspec->layouts));
1987 statspec->lengths = length;
1991 if (number > statspec->platforms[l]) {
1992 statspec->layouts[l] =
ReallocT(statspec->layouts[l], number);
1994 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1995 (number - statspec->platforms[l]) *
sizeof(**statspec->layouts));
1997 statspec->platforms[l] = number;
2001 layout = MallocT<byte>(length * number);
2003 for (l = 0; l < length; l++) {
2004 for (p = 0; p < number; p++) {
2005 layout[l * number + p] = buf->ReadByte();
2015 free(statspec->layouts[l][p]);
2016 statspec->layouts[l][p] = layout;
2021 byte srcid = buf->ReadByte();
2024 if (srcstatspec ==
nullptr) {
2025 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2029 statspec->lengths = srcstatspec->lengths;
2030 statspec->platforms = srcstatspec->platforms;
2031 statspec->layouts = srcstatspec->layouts;
2032 statspec->copied_layouts =
true;
2041 statspec->
pylons = buf->ReadByte();
2045 if (_cur.
grffile->grf_version >= 7) {
2053 statspec->
flags = buf->ReadByte();
2057 statspec->
wires = buf->ReadByte();
2061 statspec->
blocked = buf->ReadByte();
2065 statspec->animation.
frames = buf->ReadByte();
2066 statspec->animation.
status = buf->ReadByte();
2070 statspec->animation.
speed = buf->ReadByte();
2074 statspec->animation.
triggers = buf->ReadWord();
2078 statspec->
tiles = buf->ReadExtendedByte();
2082 for (uint t = 0; t < statspec->
tiles; t++) {
2084 uint num_building_sprites = buf->ReadByte();
2111 if (
id + numinfo > CF_END) {
2112 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2116 for (
int i = 0; i < numinfo; i++) {
2125 cp->
flags = buf->ReadByte();
2150 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2154 for (
int i = 0; i < numinfo; i++) {
2160 byte year = buf->ReadByte();
2175 bridge->
price = buf->ReadByte();
2179 bridge->
speed = buf->ReadWord();
2183 byte tableid = buf->ReadByte();
2184 byte numtables = buf->ReadByte();
2191 for (; numtables-- != 0; tableid++) {
2193 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2194 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2199 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2202 for (
byte sprite = 0; sprite < 32; sprite++) {
2216 bridge->
flags = buf->ReadByte();
2225 if (newone != STR_UNDEFINED) bridge->
material = newone;
2232 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2237 bridge->
price = buf->ReadWord();
2294 for (uint j = 0; j < 4; j++) buf->ReadByte();
2298 byte count = buf->ReadByte();
2299 for (
byte j = 0; j < count; j++) buf->ReadByte();
2304 buf->Skip(buf->ReadByte() * 2);
2327 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2332 if (_cur.
grffile->housespec ==
nullptr) {
2336 for (
int i = 0; i < numinfo; i++) {
2339 if (prop != 0x08 && housespec ==
nullptr) {
2342 if (cir > ret) ret = cir;
2349 byte subs_id = buf->ReadByte();
2351 if (subs_id == 0xFF) {
2354 HouseSpec::Get(hid + i)->
enabled =
false;
2358 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2363 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2367 MemCpyT(housespec, HouseSpec::Get(subs_id));
2371 housespec->
grf_prop.subst_id = subs_id;
2393 uint16 years = buf->ReadWord();
2413 int8 goods = buf->ReadByte();
2449 byte override = buf->ReadByte();
2453 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2457 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2466 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2488 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2496 uint32 cargotypes = buf->ReadDWord();
2499 if (cargotypes == 0xFFFFFFFF)
break;
2501 for (uint j = 0; j < 3; j++) {
2503 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2521 byte count = buf->ReadByte();
2522 for (
byte j = 0; j < count; j++) {
2530 housespec->
min_year = buf->ReadWord();
2534 housespec->
max_year = buf->ReadWord();
2538 uint count = buf->ReadByte();
2541 error->param_value[1] = prop;
2590 template <
typename T>
2594 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2598 translation_table.clear();
2599 for (
int i = 0; i < numinfo; i++) {
2600 uint32 item = buf->ReadDWord();
2601 translation_table.push_back(
BSWAP32(item));
2637 for (
int i = 0; i < numinfo; i++) {
2640 int factor = buf->ReadByte();
2641 uint price = gvid + i;
2643 if (price < PR_END) {
2646 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2655 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2663 uint32 rate = buf->ReadDWord();
2671 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2678 uint16 options = buf->ReadWord();
2687 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2694 uint32 tempfix = buf->ReadDWord();
2700 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2707 uint32 tempfix = buf->ReadDWord();
2713 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2720 Year year_euro = buf->ReadWord();
2725 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2732 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2734 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2740 table[i][j] = buf->ReadByte();
2741 if (_cur.
grffile->grf_version >= 8) {
2744 if (table[i][j] >= 128) {
2766 uint curidx = gvid + i;
2768 if (lang ==
nullptr) {
2769 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2774 while (buf->ReadByte() != 0) {
2784 uint plural_form = buf->ReadByte();
2785 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2786 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2793 byte newgrf_id = buf->ReadByte();
2794 while (newgrf_id != 0) {
2795 const char *name = buf->ReadString();
2810 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2817 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2822 newgrf_id = buf->ReadByte();
2858 for (
int i = 0; i < numinfo; i++) {
2882 uint32 s = buf->ReadDWord();
2883 uint32 t = buf->ReadDWord();
2890 while (buf->ReadByte() != 0) {
2918 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2922 for (
int i = 0; i < numinfo; i++) {
2927 cs->
bitnum = buf->ReadByte();
2965 cs->
sprite = buf->ReadWord();
2969 cs->
weight = buf->ReadByte();
2973 cs->transit_days[0] = buf->ReadByte();
2977 cs->transit_days[1] = buf->ReadByte();
2981 cs->initial_payment = buf->ReadDWord();
2985 cs->rating_colour = buf->ReadByte();
2989 cs->legend_colour = buf->ReadByte();
2997 cs->
classes = buf->ReadWord();
3001 cs->
label = buf->ReadDWord();
3006 uint8 substitute_type = buf->ReadByte();
3008 switch (substitute_type) {
3015 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3031 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3056 if (_cur.
grffile->sound_offset == 0) {
3057 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3062 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3066 for (
int i = 0; i < numinfo; i++) {
3071 sound->volume = buf->ReadByte();
3075 sound->priority = buf->ReadByte();
3079 SoundID orig_sound = buf->ReadByte();
3084 SoundEntry *old_sound = GetSound(orig_sound);
3087 *old_sound = *sound;
3129 buf->Skip(buf->ReadByte() * 2);
3157 if (_cur.
grffile->indtspec ==
nullptr) {
3161 for (
int i = 0; i < numinfo; i++) {
3164 if (prop != 0x08 && tsp ==
nullptr) {
3166 if (cir > ret) ret = cir;
3173 byte subs_id = buf->ReadByte();
3177 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3182 if (*tilespec ==
nullptr) {
3183 *tilespec = CallocT<IndustryTileSpec>(1);
3186 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3204 byte ovrid = buf->ReadByte();
3208 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3212 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3219 uint16 acctp = buf->ReadWord();
3251 byte num_cargoes = buf->ReadByte();
3254 error->param_value[1] = prop;
3258 if (i < num_cargoes) {
3325 byte num_table = buf->ReadByte();
3326 for (
byte j = 0; j < num_table; j++) {
3327 for (uint k = 0;; k++) {
3328 byte x = buf->ReadByte();
3329 if (x == 0xFE && k == 0) {
3335 byte y = buf->ReadByte();
3336 if (x == 0 && y == 0x80)
break;
3338 byte gfx = buf->ReadByte();
3339 if (gfx == 0xFE) buf->ReadWord();
3346 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3353 buf->Skip(buf->ReadByte());
3357 int num_inputs = buf->ReadByte();
3358 int num_outputs = buf->ReadByte();
3359 buf->Skip(num_inputs * num_outputs * 2);
3377 const size_t size = layout.size();
3378 for (
size_t i = 0; i < size - 1; i++) {
3379 for (
size_t j = i + 1; j < size; j++) {
3380 if (layout[i].ti.x == layout[j].ti.x &&
3381 layout[i].ti.y == layout[j].ti.y) {
3407 if (_cur.
grffile->industryspec ==
nullptr) {
3411 for (
int i = 0; i < numinfo; i++) {
3414 if (prop != 0x08 && indsp ==
nullptr) {
3416 if (cir > ret) ret = cir;
3423 byte subs_id = buf->ReadByte();
3425 if (subs_id == 0xFF) {
3428 _industry_specs[indid + i].
enabled =
false;
3432 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3439 if (*indspec ==
nullptr) {
3443 *indsp = _origin_industry_specs[subs_id];
3446 indsp->
grf_prop.subst_id = subs_id;
3456 byte ovrid = buf->ReadByte();
3460 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3464 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3469 byte new_num_layouts = buf->ReadByte();
3470 uint32 definition_size = buf->ReadDWord();
3471 uint32 bytes_read = 0;
3472 std::vector<IndustryTileLayout> new_layouts;
3475 for (
byte j = 0; j < new_num_layouts; j++) {
3478 for (uint k = 0;; k++) {
3479 if (bytes_read >= definition_size) {
3480 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3482 definition_size = UINT32_MAX;
3488 it.ti.
x = buf->ReadByte();
3491 if (it.ti.
x == 0xFE && k == 0) {
3493 IndustryType type = buf->ReadByte();
3494 byte laynbr = buf->ReadByte();
3497 if (type >=
lengthof(_origin_industry_specs)) {
3498 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3502 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3503 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3507 layout = _origin_industry_specs[type].layouts[laynbr];
3511 it.ti.
y = buf->ReadByte();
3514 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3520 it.gfx = buf->ReadByte();
3523 if (it.gfx == 0xFE) {
3525 int local_tile_id = buf->ReadWord();
3529 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3532 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3537 }
else if (it.gfx == 0xFF) {
3538 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3539 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3548 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3554 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3558 new_layouts.push_back(layout);
3588 for (
byte j = 0; j < 2; j++) {
3594 for (
byte j = 0; j < 3; j++) {
3602 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3615 sounds[j] = buf->ReadByte();
3631 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3657 uint32 multiples = buf->ReadDWord();
3673 byte aflag = buf->ReadByte();
3683 uint16 str = buf->ReadWord();
3693 byte num_cargoes = buf->ReadByte();
3694 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3696 error->param_value[1] = prop;
3699 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3700 if (i < num_cargoes) {
3702 indsp->produced_cargo[i] = cargo;
3711 byte num_cargoes = buf->ReadByte();
3714 error->param_value[1] = prop;
3718 if (i < num_cargoes) {
3729 byte num_cargoes = buf->ReadByte();
3730 if (num_cargoes >
lengthof(indsp->production_rate)) {
3732 error->param_value[1] = prop;
3735 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3736 if (i < num_cargoes) {
3737 indsp->production_rate[i] = buf->ReadByte();
3739 indsp->production_rate[i] = 0;
3746 byte num_inputs = buf->ReadByte();
3747 byte num_outputs = buf->ReadByte();
3750 error->param_value[1] = prop;
3754 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3756 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3780 for (
int i = 0; i < as->
num_table; i++) {
3785 }
while ((++it)->ti.x != -0x80);
3786 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3789 as->
table = table_list;
3811 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3816 if (_cur.
grffile->airportspec ==
nullptr) {
3820 for (
int i = 0; i < numinfo; i++) {
3823 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3824 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3830 byte subs_id = buf->ReadByte();
3832 if (subs_id == 0xFF) {
3839 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3847 if (*spec ==
nullptr) {
3848 *spec = MallocT<AirportSpec>(1);
3857 _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 as->
table = tile_table;
3927 for (
int i = 0; i < as->
num_table; i++) {
3928 free(tile_table[i]);
4034 if (_cur.
grffile->objectspec ==
nullptr) {
4038 for (
int i = 0; i < numinfo; i++) {
4041 if (prop != 0x08 && spec ==
nullptr) {
4044 if (cir > ret) ret = cir;
4053 if (*ospec ==
nullptr) {
4054 *ospec = CallocT<ObjectSpec>(1);
4055 (*ospec)->views = 1;
4056 (*ospec)->size = 0x11;
4060 uint32 classid = buf->ReadDWord();
4061 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4062 (*ospec)->enabled =
true;
4077 spec->
climate = buf->ReadByte();
4081 spec->
size = buf->ReadByte();
4082 if ((spec->
size & 0xF0) == 0 || (spec->
size & 0x0F) == 0) {
4083 grfmsg(1,
"ObjectChangeInfo: Invalid object size requested (%u) for object id %u. Ignoring.", spec->
size,
id + i);
4128 spec->
height = buf->ReadByte();
4132 spec->
views = buf->ReadByte();
4134 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4167 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4171 for (
int i = 0; i < numinfo; i++) {
4184 uint16 str = buf->ReadWord();
4186 if (_cur.
grffile->grf_version < 8) {
4216 int n = buf->ReadByte();
4217 for (
int j = 0; j != n; j++) {
4218 RailTypeLabel label = buf->ReadDWord();
4278 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4297 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4301 for (
int i = 0; i < numinfo; i++) {
4305 RailTypeLabel rtl = buf->ReadDWord();
4314 _cur.
grffile->railtype_map[
id + i] = rt;
4332 int n = buf->ReadByte();
4333 for (
int j = 0; j != n; j++) {
4338 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4345 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4386 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4390 for (
int i = 0; i < numinfo; i++) {
4403 uint16 str = buf->ReadWord();
4430 int n = buf->ReadByte();
4431 for (
int j = 0; j != n; j++) {
4432 RoadTypeLabel label = buf->ReadDWord();
4479 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4510 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4514 for (
int i = 0; i < numinfo; i++) {
4517 RoadTypeLabel rtl = buf->ReadDWord();
4524 }
else if (GetRoadTramType(rt) != rtt) {
4525 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4529 type_map[
id + i] = rt;
4546 int n = buf->ReadByte();
4547 for (
int j = 0; j != n; j++) {
4552 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4558 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4582 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4587 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4600 if (_cur.
grffile->airtspec ==
nullptr) {
4604 for (
int i = 0; i < numinfo; i++) {
4607 if (prop != 0x08 && tsp ==
nullptr) {
4608 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4615 byte subs_id = buf->ReadByte();
4619 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4624 if (*tilespec ==
nullptr) {
4625 *tilespec = CallocT<AirportTileSpec>(1);
4642 byte override = buf->ReadByte();
4646 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4650 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4680 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4683 default: NOT_REACHED();
4693 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4697 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4710 static void FeatureChangeInfo(
ByteReader *buf)
4723 static const VCI_Handler handler[] = {
4741 AirportTilesChangeInfo,
4746 uint8 feature = buf->ReadByte();
4747 uint8 numprops = buf->ReadByte();
4748 uint numinfo = buf->ReadByte();
4749 uint engine = buf->ReadExtendedByte();
4751 if (feature >= GSF_END) {
4752 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4756 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4757 feature, numprops, engine, numinfo);
4759 if (feature >=
lengthof(handler) || handler[feature] ==
nullptr) {
4760 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4767 while (numprops-- && buf->HasData()) {
4768 uint8 prop = buf->ReadByte();
4771 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4778 uint8 feature = buf->ReadByte();
4779 uint8 numprops = buf->ReadByte();
4780 uint numinfo = buf->ReadByte();
4781 buf->ReadExtendedByte();
4783 if (feature == GSF_BRIDGES && numprops == 1) {
4784 uint8 prop = buf->ReadByte();
4787 if (prop == 0x0D)
return;
4788 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4789 uint8 prop = buf->ReadByte();
4792 bool is_safe =
true;
4793 for (uint i = 0; i < numinfo; i++) {
4794 uint32 s = buf->ReadDWord();
4802 if (is_safe)
return;
4813 static void ReserveChangeInfo(
ByteReader *buf)
4815 uint8 feature = buf->ReadByte();
4817 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4819 uint8 numprops = buf->ReadByte();
4820 uint8 numinfo = buf->ReadByte();
4821 uint8 index = buf->ReadExtendedByte();
4823 while (numprops-- && buf->HasData()) {
4824 uint8 prop = buf->ReadByte();
4828 default: NOT_REACHED();
4834 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4838 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4842 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4846 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4850 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4871 uint8 feature = buf->ReadByte();
4872 uint16 num_sets = buf->ReadByte();
4873 uint16 first_set = 0;
4875 if (num_sets == 0 && buf->HasData(3)) {
4878 first_set = buf->ReadExtendedByte();
4879 num_sets = buf->ReadExtendedByte();
4881 uint16 num_ents = buf->ReadExtendedByte();
4883 if (feature >= GSF_END) {
4885 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4891 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4892 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4895 for (
int i = 0; i < num_sets * num_ents; i++) {
4905 uint16 num_sets = buf->ReadByte();
4907 if (num_sets == 0 && buf->HasData(3)) {
4910 buf->ReadExtendedByte();
4911 num_sets = buf->ReadExtendedByte();
4913 uint16 num_ents = buf->ReadExtendedByte();
4922 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4924 if (
HasBit(groupid, 15)) {
4929 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4930 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4934 return _cur.spritegroups[groupid];
4947 if (
HasBit(spriteid, 15)) {
4953 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4958 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4961 assert(spriteset_start + num_sprites <= _cur.
spriteid);
4982 uint8 feature = buf->ReadByte();
4983 if (feature >= GSF_END) {
4984 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4988 uint8 setid = buf->ReadByte();
4989 uint8 type = buf->ReadByte();
5013 switch (
GB(type, 2, 2)) {
5014 default: NOT_REACHED();
5015 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5016 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5017 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5020 static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5030 adjust.variable = buf->ReadByte();
5031 if (adjust.variable == 0x7E) {
5033 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5038 varadjust = buf->ReadByte();
5039 adjust.shift_num =
GB(varadjust, 0, 5);
5040 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5041 adjust.and_mask = buf->ReadVarSize(varsize);
5043 if (adjust.type != DSGA_TYPE_NONE) {
5044 adjust.add_val = buf->ReadVarSize(varsize);
5045 adjust.divmod_val = buf->ReadVarSize(varsize);
5048 adjust.divmod_val = 0;
5052 }
while (
HasBit(varadjust, 5));
5054 group->num_adjusts = (uint)adjusts.size();
5055 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5056 MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
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 std::vector<DeterministicSpriteGroupRange> optimised;
5095 for (uint j = 0; j < bounds.size(); ) {
5096 if (target[j] != group->default_group) {
5098 r.group = target[j];
5100 while (j < bounds.size() && target[j] == r.group) {
5103 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5104 optimised.push_back(r);
5110 group->num_ranges = (uint)optimised.size();
5111 if (group->num_ranges > 0) {
5112 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5113 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5131 group->count = buf->ReadByte();
5134 uint8 triggers = buf->ReadByte();
5135 group->triggers =
GB(triggers, 0, 7);
5136 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5141 for (uint i = 0; i < group->
num_groups; i++) {
5142 group->
groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5153 case GSF_ROADVEHICLES:
5164 byte num_loaded = type;
5165 byte num_loading = buf->ReadByte();
5168 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5179 if (num_loaded > 0) group->
loaded = CallocT<const SpriteGroup*>(num_loaded);
5180 if (num_loading > 0) group->
loading = CallocT<const SpriteGroup*>(num_loading);
5182 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5183 setid, num_loaded, num_loading);
5185 for (uint i = 0; i < num_loaded; i++) {
5186 uint16 spriteid = buf->ReadWord();
5188 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5191 for (uint i = 0; i < num_loading; i++) {
5192 uint16 spriteid = buf->ReadWord();
5194 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5201 case GSF_AIRPORTTILES:
5203 case GSF_INDUSTRYTILES: {
5204 byte num_building_sprites = std::max((uint8)1, type);
5212 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5216 case GSF_INDUSTRIES: {
5218 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5229 for (uint i = 0; i < 3; i++) {
5233 for (uint i = 0; i < 2; i++) {
5236 group->again = buf->ReadByte();
5237 }
else if (type == 1) {
5239 for (uint i = 0; i < 3; i++) {
5243 for (uint i = 0; i < 2; i++) {
5246 group->again = buf->ReadByte();
5247 }
else if (type == 2) {
5251 error->data =
"too many inputs (max 16)";
5254 for (uint i = 0; i < group->
num_input; i++) {
5255 byte rawcargo = buf->ReadByte();
5264 error->data =
"duplicate input cargo";
5273 error->data =
"too many outputs (max 16)";
5276 for (uint i = 0; i < group->
num_output; i++) {
5277 byte rawcargo = buf->ReadByte();
5284 error->data =
"duplicate output cargo";
5290 group->again = buf->ReadByte();
5298 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5303 _cur.spritegroups[setid] = act_group;
5306 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5308 if (feature == GSF_OBJECTS) {
5313 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5318 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5319 if (ctype == 0xFF)
return CT_PURCHASE;
5324 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5329 FOR_ALL_CARGOSPECS(cs) {
5330 if (cs->
bitnum == ctype) {
5331 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->
Index());
5336 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5342 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5349 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5355 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));
5359 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);
5364 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5366 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5367 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5374 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5377 static uint last_engines_count;
5378 bool wagover =
false;
5381 if (
HasBit(idcount, 7)) {
5384 idcount =
GB(idcount, 0, 7);
5386 if (last_engines_count == 0) {
5387 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5391 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5392 last_engines_count, idcount);
5394 if (last_engines_count != idcount) {
5395 last_engines =
ReallocT(last_engines, idcount);
5396 last_engines_count = idcount;
5401 for (uint i = 0; i < idcount; i++) {
5407 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5411 engines[i] = e->
index;
5412 if (!wagover) last_engines[i] = engines[i];
5415 uint8 cidcount = buf->ReadByte();
5416 for (uint c = 0; c < cidcount; c++) {
5417 uint8 ctype = buf->ReadByte();
5418 uint16 groupid = buf->ReadWord();
5419 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5421 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5423 ctype = TranslateCargo(feature, ctype);
5426 for (uint i = 0; i < idcount; i++) {
5429 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5432 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5434 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5439 uint16 groupid = buf->ReadWord();
5440 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5442 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5444 for (uint i = 0; i < idcount; i++) {
5448 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5450 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5457 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5460 for (uint i = 0; i < idcount; i++) {
5464 uint8 cidcount = buf->ReadByte();
5465 buf->Skip(cidcount * 3);
5467 uint16 groupid = buf->ReadWord();
5468 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5470 for (uint i = 0; i < idcount; i++) {
5474 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5484 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5486 uint8 *stations =
AllocaM(uint8, idcount);
5487 for (uint i = 0; i < idcount; i++) {
5488 stations[i] = buf->ReadByte();
5491 uint8 cidcount = buf->ReadByte();
5492 for (uint c = 0; c < cidcount; c++) {
5493 uint8 ctype = buf->ReadByte();
5494 uint16 groupid = buf->ReadWord();
5495 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5497 ctype = TranslateCargo(GSF_STATIONS, ctype);
5500 for (uint i = 0; i < idcount; i++) {
5503 if (statspec ==
nullptr) {
5504 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5512 uint16 groupid = buf->ReadWord();
5513 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5515 for (uint i = 0; i < idcount; i++) {
5518 if (statspec ==
nullptr) {
5519 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5524 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5531 StationClass::Assign(statspec);
5536 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5538 uint8 *houses =
AllocaM(uint8, idcount);
5539 for (uint i = 0; i < idcount; i++) {
5540 houses[i] = buf->ReadByte();
5544 uint8 cidcount = buf->ReadByte();
5545 buf->Skip(cidcount * 3);
5547 uint16 groupid = buf->ReadWord();
5548 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5550 if (_cur.
grffile->housespec ==
nullptr) {
5551 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5555 for (uint i = 0; i < idcount; i++) {
5558 if (hs ==
nullptr) {
5559 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5567 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5569 uint8 *industries =
AllocaM(uint8, idcount);
5570 for (uint i = 0; i < idcount; i++) {
5571 industries[i] = buf->ReadByte();
5575 uint8 cidcount = buf->ReadByte();
5576 buf->Skip(cidcount * 3);
5578 uint16 groupid = buf->ReadWord();
5579 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5581 if (_cur.
grffile->industryspec ==
nullptr) {
5582 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5586 for (uint i = 0; i < idcount; i++) {
5589 if (indsp ==
nullptr) {
5590 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5598 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5600 uint8 *indtiles =
AllocaM(uint8, idcount);
5601 for (uint i = 0; i < idcount; i++) {
5602 indtiles[i] = buf->ReadByte();
5606 uint8 cidcount = buf->ReadByte();
5607 buf->Skip(cidcount * 3);
5609 uint16 groupid = buf->ReadWord();
5610 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5612 if (_cur.
grffile->indtspec ==
nullptr) {
5613 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5617 for (uint i = 0; i < idcount; i++) {
5620 if (indtsp ==
nullptr) {
5621 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5629 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5632 for (uint i = 0; i < idcount; i++) {
5633 cargoes[i] = buf->ReadByte();
5637 uint8 cidcount = buf->ReadByte();
5638 buf->Skip(cidcount * 3);
5640 uint16 groupid = buf->ReadWord();
5641 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5643 for (uint i = 0; i < idcount; i++) {
5647 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5653 cs->group = _cur.spritegroups[groupid];
5657 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5659 if (_cur.
grffile->objectspec ==
nullptr) {
5660 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5664 uint8 *objects =
AllocaM(uint8, idcount);
5665 for (uint i = 0; i < idcount; i++) {
5666 objects[i] = buf->ReadByte();
5669 uint8 cidcount = buf->ReadByte();
5670 for (uint c = 0; c < cidcount; c++) {
5671 uint8 ctype = buf->ReadByte();
5672 uint16 groupid = buf->ReadWord();
5673 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5675 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5678 for (uint i = 0; i < idcount; i++) {
5681 if (spec ==
nullptr) {
5682 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5690 uint16 groupid = buf->ReadWord();
5691 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5693 for (uint i = 0; i < idcount; i++) {
5696 if (spec ==
nullptr) {
5697 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5702 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5712 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5714 uint8 *railtypes =
AllocaM(uint8, idcount);
5715 for (uint i = 0; i < idcount; i++) {
5716 uint8
id = buf->ReadByte();
5720 uint8 cidcount = buf->ReadByte();
5721 for (uint c = 0; c < cidcount; c++) {
5722 uint8 ctype = buf->ReadByte();
5723 uint16 groupid = buf->ReadWord();
5724 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5726 if (ctype >= RTSG_END)
continue;
5729 for (uint i = 0; i < idcount; i++) {
5734 rti->
group[ctype] = _cur.spritegroups[groupid];
5743 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5747 uint8 *roadtypes =
AllocaM(uint8, idcount);
5748 for (uint i = 0; i < idcount; i++) {
5749 uint8
id = buf->ReadByte();
5753 uint8 cidcount = buf->ReadByte();
5754 for (uint c = 0; c < cidcount; c++) {
5755 uint8 ctype = buf->ReadByte();
5756 uint16 groupid = buf->ReadWord();
5757 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5759 if (ctype >= ROTSG_END)
continue;
5762 for (uint i = 0; i < idcount; i++) {
5767 rti->
group[ctype] = _cur.spritegroups[groupid];
5776 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5778 uint8 *airports =
AllocaM(uint8, idcount);
5779 for (uint i = 0; i < idcount; i++) {
5780 airports[i] = buf->ReadByte();
5784 uint8 cidcount = buf->ReadByte();
5785 buf->Skip(cidcount * 3);
5787 uint16 groupid = buf->ReadWord();
5788 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5790 if (_cur.
grffile->airportspec ==
nullptr) {
5791 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5795 for (uint i = 0; i < idcount; i++) {
5798 if (as ==
nullptr) {
5799 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5807 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5809 uint8 *airptiles =
AllocaM(uint8, idcount);
5810 for (uint i = 0; i < idcount; i++) {
5811 airptiles[i] = buf->ReadByte();
5815 uint8 cidcount = buf->ReadByte();
5816 buf->Skip(cidcount * 3);
5818 uint16 groupid = buf->ReadWord();
5819 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5821 if (_cur.
grffile->airtspec ==
nullptr) {
5822 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5826 for (uint i = 0; i < idcount; i++) {
5829 if (airtsp ==
nullptr) {
5830 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5840 static void FeatureMapSpriteGroup(
ByteReader *buf)
5856 uint8 feature = buf->ReadByte();
5857 uint8 idcount = buf->ReadByte();
5859 if (feature >= GSF_END) {
5860 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5868 uint16 groupid = buf->ReadWord();
5869 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5871 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5880 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5884 case GSF_ROADVEHICLES:
5887 VehicleMapSpriteGroup(buf, feature, idcount);
5891 CanalMapSpriteGroup(buf, idcount);
5895 StationMapSpriteGroup(buf, idcount);
5899 TownHouseMapSpriteGroup(buf, idcount);
5902 case GSF_INDUSTRIES:
5903 IndustryMapSpriteGroup(buf, idcount);
5906 case GSF_INDUSTRYTILES:
5907 IndustrytileMapSpriteGroup(buf, idcount);
5911 CargoMapSpriteGroup(buf, idcount);
5915 AirportMapSpriteGroup(buf, idcount);
5919 ObjectMapSpriteGroup(buf, idcount);
5923 RailTypeMapSpriteGroup(buf, idcount);
5927 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5931 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5934 case GSF_AIRPORTTILES:
5935 AirportTileMapSpriteGroup(buf, idcount);
5939 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5963 bool new_scheme = _cur.
grffile->grf_version >= 7;
5965 uint8 feature = buf->ReadByte();
5966 if (feature >= GSF_END && feature != 0x48) {
5967 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5971 uint8 lang = buf->ReadByte();
5972 uint8 num = buf->ReadByte();
5973 bool generic =
HasBit(lang, 7);
5976 id = buf->ReadWord();
5977 }
else if (feature <= GSF_AIRCRAFT) {
5978 id = buf->ReadExtendedByte();
5980 id = buf->ReadByte();
5985 uint16 endid =
id + num;
5987 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5988 id, endid, feature, lang);
5990 for (;
id < endid && buf->HasData();
id++) {
5991 const char *name = buf->ReadString();
5992 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
5996 case GSF_ROADVEHICLES:
6001 if (e ==
nullptr)
break;
6015 switch (
GB(
id, 8, 8)) {
6017 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6018 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6026 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6027 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6034 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6035 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6042 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6043 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6050 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6069 if (offset >= max_sprites) {
6070 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6071 uint orig_num = num;
6076 if (offset + num > max_sprites) {
6077 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6078 uint orig_num = num;
6079 num = std::max(max_sprites - offset, 0);
6080 return orig_num - num;
6109 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6111 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6141 uint8 type = buf->ReadByte();
6142 uint16 num = buf->ReadExtendedByte();
6143 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6149 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6166 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6177 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6184 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);
6194 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);
6205 for (; num > 0; num--) {
6276 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6306 *value = _game_mode;
6340 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6349 *value = _openttd_newgrf_version;
6364 default:
return false;
6368 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6386 if (cond_val ==
nullptr) {
6390 uint32 index = *cond_val / 0x20;
6406 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6429 byte *preload_sprite =
nullptr;
6433 preload_sprite = MallocT<byte>(num);
6441 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6442 free(preload_sprite);
6447 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6448 if (it != _grf_line_to_action6_sprite_override.end()) {
6449 free(preload_sprite);
6450 preload_sprite = _grf_line_to_action6_sprite_override[location];
6452 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6465 param_num = buf->ReadByte();
6466 if (param_num == 0xFF)
break;
6470 param_size = buf->ReadByte();
6474 add_value =
HasBit(param_size, 7);
6475 param_size =
GB(param_size, 0, 7);
6478 offset = buf->ReadExtendedByte();
6482 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6483 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6487 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6490 for (i = 0; i < param_size && offset + i < num; i++) {
6491 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6494 if (i % 4 == 0) carry =
false;
6497 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6498 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6500 carry = new_value >= 256;
6502 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6534 uint32 cond_val = 0;
6538 uint8 param = buf->ReadByte();
6539 uint8 paramsize = buf->ReadByte();
6540 uint8 condtype = buf->ReadByte();
6547 switch (paramsize) {
6548 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6549 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6550 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6551 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6555 if (param < 0x80 && _cur.grffile->param_end <= param) {
6556 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6560 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6565 if (condtype >= 0x0B) {
6596 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6598 }
else if (param == 0x88) {
6608 if (condtype != 10 && c ==
nullptr) {
6609 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6636 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6640 uint32 param_val = GetParamVal(param, &cond_val);
6642 case 0x00: result = !!(param_val & (1 << cond_val));
6644 case 0x01: result = !(param_val & (1 << cond_val));
6646 case 0x02: result = (param_val & mask) == cond_val;
6648 case 0x03: result = (param_val & mask) != cond_val;
6650 case 0x04: result = (param_val & mask) < cond_val;
6652 case 0x05: result = (param_val & mask) > cond_val;
6654 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6659 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6663 uint8 numsprites = buf->ReadByte();
6671 if (label->label != numsprites)
continue;
6674 if (choice ==
nullptr) choice = label;
6676 if (label->nfo_line > _cur.
nfo_line) {
6682 if (choice !=
nullptr) {
6683 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6689 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6708 uint8 grf_version = buf->ReadByte();
6709 uint32 grfid = buf->ReadDWord();
6710 const char *name = buf->ReadString();
6714 if (grf_version < 2 || grf_version > 8) {
6716 DEBUG(grf, 0,
"%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.
grfconfig->
filename, name,
BSWAP32(grfid), grf_version);
6724 if (buf->HasData()) {
6725 const char *info = buf->ReadString();
6743 uint8 version = buf->ReadByte();
6744 uint32 grfid = buf->ReadDWord();
6745 const char *name = buf->ReadString();
6748 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6752 if (_cur.
grffile->grfid != grfid) {
6753 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));
6757 _cur.
grffile->grf_version = version;
6775 uint8 num_sets = buf->ReadByte();
6777 for (uint i = 0; i < num_sets; i++) {
6778 uint8 num_sprites = buf->ReadByte();
6779 uint16 first_sprite = buf->ReadWord();
6781 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6782 i, num_sprites, first_sprite
6785 for (uint j = 0; j < num_sprites; j++) {
6786 int load_index = first_sprite + j;
6792 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6802 uint8 num_sets = buf->ReadByte();
6804 for (uint i = 0; i < num_sets; i++) {
6833 STR_NEWGRF_ERROR_VERSION_NUMBER,
6834 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6835 STR_NEWGRF_ERROR_UNSET_SWITCH,
6836 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6837 STR_NEWGRF_ERROR_LOAD_BEFORE,
6838 STR_NEWGRF_ERROR_LOAD_AFTER,
6839 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6843 STR_NEWGRF_ERROR_MSG_INFO,
6844 STR_NEWGRF_ERROR_MSG_WARNING,
6845 STR_NEWGRF_ERROR_MSG_ERROR,
6846 STR_NEWGRF_ERROR_MSG_FATAL
6849 byte severity = buf->ReadByte();
6850 byte lang = buf->ReadByte();
6851 byte message_id = buf->ReadByte();
6854 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6858 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6859 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6864 if (severity >=
lengthof(sevstr)) {
6865 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6867 }
else if (severity == 3) {
6877 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6878 grfmsg(7,
"GRFLoadError: Invalid message id.");
6882 if (buf->Remaining() <= 1) {
6883 grfmsg(7,
"GRFLoadError: No message data supplied.");
6892 if (message_id == 0xFF) {
6894 if (buf->HasData()) {
6895 const char *message = buf->ReadString();
6899 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6900 error->custom_message.clear();
6903 error->message = msgstr[message_id];
6906 if (buf->HasData()) {
6907 const char *data = buf->ReadString();
6911 grfmsg(7,
"GRFLoadError: No message data supplied.");
6912 error->data.clear();
6916 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6917 uint param_number = buf->ReadByte();
6931 if (!buf->HasData())
return;
6933 const char *text = buf->ReadString();
6934 grfmsg(2,
"GRFComment: %s", text);
6940 uint8 target = buf->ReadByte();
6943 if (target < 0x80 || target == 0x9E)
return;
6957 static uint32 GetPatchVariable(uint8 param)
6967 case 0x0F:
return 0;
6983 case 0x11:
return SPR_2CCMAP_BASE;
7000 byte max_edge = std::max(log_X, log_Y);
7002 if (log_X == log_Y) {
7005 if (max_edge == log_Y)
SetBit(map_bits, 1);
7008 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7009 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7018 return SPR_SLOPES_BASE;
7025 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7031 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7044 for (uint i = start; i < num_ids; i++) {
7048 if (op == 2 || op == 3)
break;
7053 if (size == count)
break;
7056 if (size == count) {
7058 if (op == 0 || op == 3) {
7059 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7060 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7066 if (op != 4 && op != 5) {
7068 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7073 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7103 uint8 target = buf->ReadByte();
7104 uint8 oper = buf->ReadByte();
7105 uint32 src1 = buf->ReadByte();
7106 uint32 src2 = buf->ReadByte();
7109 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7118 if (target < 0x80 && target < _cur.grffile->param_end) {
7119 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7123 oper =
GB(oper, 0, 7);
7127 if (
GB(data, 0, 8) == 0xFF) {
7128 if (data == 0x0000FFFF) {
7130 src1 = GetPatchVariable(src1);
7134 uint8 feature =
GB(data, 8, 8);
7135 uint16 count =
GB(data, 16, 16);
7137 if (_cur.
stage == GLS_RESERVE) {
7138 if (feature == 0x08) {
7142 if (_cur.
spriteid + count >= 16384) {
7143 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7149 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7156 }
else if (_cur.
stage == GLS_ACTIVATION) {
7185 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7193 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7204 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7221 }
else if (src1 == 0xFE) {
7233 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7234 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7256 res = (int32)src1 * (int32)src2;
7260 if ((int32)src2 < 0) {
7261 res = src1 >> -(int32)src2;
7263 res = src1 << (src2 & 0x1F);
7268 if ((int32)src2 < 0) {
7269 res = (int32)src1 >> -(int32)src2;
7271 res = (int32)src1 << (src2 & 0x1F);
7295 res = (int32)src1 / (int32)src2;
7311 res = (int32)src1 % (int32)src2;
7315 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7344 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7355 uint32 safe_bits = 0;
7356 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7365 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7369 if (target < 0x80) {
7370 _cur.
grffile->param[target] = res;
7374 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7388 uint8 num = buf->ReadByte();
7390 for (uint i = 0; i < num; i++) {
7391 uint32 grfid = buf->ReadDWord();
7413 uint8 num = buf->ReadByte();
7415 for (uint i = 0; i < num; i++) {
7416 uint32 grfid = buf->ReadDWord();
7420 if (file !=
nullptr && file != _cur.
grfconfig) {
7438 uint32 grfid = _cur.
grffile->grfid;
7442 byte id = buf->ReadByte();
7443 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7448 bool new_scheme = _cur.
grffile->grf_version >= 7;
7450 byte lang = buf->ReadByte();
7452 byte nb_gen = townname->nb_gen;
7456 const char *name = buf->ReadString();
7459 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7461 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7463 lang = buf->ReadByte();
7464 }
while (lang != 0);
7465 townname->id[nb_gen] = id;
7469 byte nb = buf->ReadByte();
7470 grfmsg(6,
"FeatureTownName: %u parts", nb);
7472 townname->nbparts[id] = nb;
7473 townname->partlist[id] = CallocT<NamePartList>(nb);
7475 for (
int i = 0; i < nb; i++) {
7476 byte nbtext = buf->ReadByte();
7477 townname->partlist[id][i].bitstart = buf->ReadByte();
7478 townname->partlist[id][i].bitcount = buf->ReadByte();
7479 townname->partlist[id][i].maxprob = 0;
7480 townname->partlist[id][i].partcount = nbtext;
7481 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7482 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);
7484 for (
int j = 0; j < nbtext; j++) {
7485 byte prob = buf->ReadByte();
7488 byte ref_id = buf->ReadByte();
7490 if (townname->nbparts[ref_id] == 0) {
7491 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7492 DelGRFTownName(grfid);
7497 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7498 townname->partlist[id][i].parts[j].data.
id = ref_id;
7500 const char *text = buf->ReadString();
7502 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7504 townname->partlist[id][i].parts[j].
prob = prob;
7505 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7507 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7519 byte nfo_label = buf->ReadByte();
7521 GRFLabel *label = MallocT<GRFLabel>(1);
7522 label->label = nfo_label;
7525 label->next =
nullptr;
7533 for (l = _cur.
grffile->
label; l->next !=
nullptr; l = l->next) {}
7537 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7551 if (file ==
nullptr || file->sound_offset == 0) {
7552 grfmsg(1,
"ImportGRFSound: Source file not available");
7556 if (sound_id >= file->num_sounds) {
7557 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7561 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7563 *sound = *GetSound(file->sound_offset + sound_id);
7566 sound->volume = 128;
7567 sound->priority = 0;
7578 sound->volume = 0x80;
7579 sound->priority = 0;
7581 if (offs != SIZE_MAX) {
7584 sound->file_offset = offs;
7596 uint16 num = buf->ReadWord();
7597 if (num == 0)
return;
7600 if (_cur.
grffile->sound_offset == 0) {
7601 _cur.
grffile->sound_offset = GetNumSounds();
7602 _cur.
grffile->num_sounds = num;
7605 sound = GetSound(_cur.
grffile->sound_offset);
7608 for (
int i = 0; i < num; i++) {
7613 bool invalid = i >= _cur.
grffile->num_sounds;
7623 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7625 }
else if (len != 4) {
7626 grfmsg(1,
"GRFSound: Invalid sprite section import");
7636 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7643 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7651 if (_cur.
stage == GLS_INIT) {
7653 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7662 if (_cur.
stage == GLS_ACTIVATION) {
7673 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7702 uint8 num_def = buf->ReadByte();
7704 for (uint i = 0; i < num_def; i++) {
7706 uint8 num_char = buf->ReadByte();
7707 uint16 base_char = buf->ReadWord();
7709 if (size >= FS_END) {
7710 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7713 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7715 for (uint c = 0; c < num_char; c++) {
7733 uint8 num_def = buf->ReadByte();
7735 for (uint i = 0; i < num_def; i++) {
7759 uint32 grfid = buf->ReadDWord();
7762 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7772 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE,
lastof(tmp));
7783 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7784 byte num_strings = buf->ReadByte();
7785 uint16 first_id = buf->ReadWord();
7787 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7788 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7792 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7793 const char *
string = buf->ReadString();
7796 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7800 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7829 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7841 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7844 char data = buf->ReadByte();
7852 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7867 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7870 char data = buf->ReadByte();
7876 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7889 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7902 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7907 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7938 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7945 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7955 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7957 }
else if (len != 8) {
7958 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
7961 uint32 min_value = buf->ReadDWord();
7962 uint32 max_value = buf->ReadDWord();
7963 if (min_value <= max_value) {
7967 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7976 if (len < 1 || len > 3) {
7977 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
7980 byte param_nr = buf->ReadByte();
7982 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7998 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8034 this->handler.data = handler;
8046 this->handler.text = handler;
8058 this->handler.call_handler =
true;
8059 this->handler.u.branch = handler;
8071 this->handler.call_handler =
false;
8072 this->handler.u.subtags =
subtags;
8101 byte type = buf->ReadByte();
8103 uint32
id = buf->ReadDWord();
8105 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8107 type = buf->ReadByte();
8111 byte langid = buf->ReadByte();
8112 const char *name_string = buf->ReadString();
8123 type = buf->ReadByte();
8148 byte type = buf->ReadByte();
8150 uint32
id = buf->ReadDWord();
8152 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8154 type = buf->ReadByte();
8167 type = buf->ReadByte();
8204 byte new_type = buf->ReadByte();
8205 while (new_type != 0) {
8208 new_type = buf->ReadByte();
8219 uint16 size = buf->ReadWord();
8243 while ((tag = &subtags[i++])->type != 0) {
8246 default: NOT_REACHED();
8249 byte langid = buf->ReadByte();
8250 return tag->handler.
text(langid, buf->ReadString());
8254 size_t len = buf->ReadWord();
8255 if (buf->Remaining() < len)
return false;
8256 return tag->handler.
data(len, buf);
8261 return tag->handler.u.branch(buf);
8267 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8279 byte type = buf->ReadByte();
8281 uint32
id = buf->ReadDWord();
8282 if (!
HandleNode(type,
id, buf, subtags))
return false;
8283 type = buf->ReadByte();
8405 if (stations ==
nullptr)
continue;
8407 if (stations[i] ==
nullptr)
continue;
8413 if (!statspec->copied_layouts) {
8414 for (uint l = 0; l < statspec->lengths; l++) {
8415 for (uint p = 0; p < statspec->platforms[l]; p++) {
8416 free(statspec->layouts[l][p]);
8418 free(statspec->layouts[l]);
8420 free(statspec->layouts);
8421 free(statspec->platforms);
8438 HouseSpec **&housespec = file->housespec;
8439 if (housespec ==
nullptr)
continue;
8445 housespec =
nullptr;
8454 if (aslist !=
nullptr) {
8458 if (as !=
nullptr) {
8460 for (
int j = 0; j < as->
num_table; j++) {
8472 file->airportspec =
nullptr;
8476 if (airporttilespec !=
nullptr) {
8478 free(airporttilespec[i]);
8480 free(airporttilespec);
8481 airporttilespec =
nullptr;
8495 if (industryspec !=
nullptr) {
8502 industryspec =
nullptr;
8505 if (indtspec ==
nullptr)
continue;
8520 if (objectspec ==
nullptr)
continue;
8522 free(objectspec[i]);
8526 objectspec =
nullptr;
8558 CleanUpGRFTownNames();
8602 ObjectClass::Reset();
8607 StationClass::Reset();
8611 AirportClass::Reset();
8640 _grf_id_overrides.clear();
8642 InitializeSoundPool();
8690 if (newfile !=
nullptr) {
8696 newfile =
new GRFFile(config);
8714 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8719 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8726 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8730 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8746 free(this->filename);
8756 'PASS',
'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
8757 'IORE',
'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
8758 'WATR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8762 static const CargoLabel _default_refitmasks_road[] = {
8765 static const CargoLabel _default_refitmasks_ships[] = {
8766 'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
'IORE',
8767 'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
'WATR',
8768 'RUBR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8772 static const CargoLabel _default_refitmasks_aircraft[] = {
8773 'PASS',
'MAIL',
'GOOD',
'VALU',
'GOLD',
'DIAM',
'FOOD',
'FRUT',
'SUGR',
8774 'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
'PLST',
'FZDR',
8777 static const CargoLabel *
const _default_refitmasks[] = {
8779 _default_refitmasks_road,
8780 _default_refitmasks_ships,
8781 _default_refitmasks_aircraft,
8793 bool only_defaultcargo;
8797 CargoTypes mask = 0;
8798 CargoTypes not_mask = 0;
8799 CargoTypes xor_mask = ei->refit_mask;
8805 if (
_gted[engine].cargo_allowed != 0) {
8808 FOR_ALL_CARGOSPECS(cs) {
8814 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8820 CargoTypes xor_mask = 0;
8825 for (uint i = 0;; i++) {
8826 if (cl[i] == 0)
break;
8838 only_defaultcargo = (ei->refit_mask == 0);
8852 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8854 const uint8 *cargo_map_for_first_refittable =
nullptr;
8857 if (file ==
nullptr) file = e->
GetGRF();
8858 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8859 cargo_map_for_first_refittable = file->
cargo_map;
8863 if (cargo_map_for_first_refittable !=
nullptr) {
8865 byte best_local_slot = 0xFF;
8867 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8868 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8869 if (local_slot < best_local_slot) {
8870 best_local_slot = local_slot;
8871 ei->cargo_type = cargo_type;
8893 for (uint i = 0; i < CF_END; i++) {
8905 if (e->
GetGRF() ==
nullptr) {
8908 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
8943 default: NOT_REACHED();
8957 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8958 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8982 if (filename !=
nullptr)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
8992 if (filename !=
nullptr)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->
grf_prop.
local_id);
9000 DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9007 if (filename !=
nullptr)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->
grf_prop.
local_id);
9026 if (hs ==
nullptr || !hs->
enabled)
continue;
9031 if (min_year == 0)
return;
9035 if (hs ==
nullptr || !hs->
enabled)
continue;
9059 HouseSpec **&housespec = file->housespec;
9060 if (housespec ==
nullptr)
continue;
9065 if (hs ==
nullptr)
continue;
9123 if (industryspec !=
nullptr) {
9127 if (indsp !=
nullptr && indsp->
enabled) {
9133 if (strid != STR_UNDEFINED) indsp->
name = strid;
9136 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9151 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9159 if (indtspec !=
nullptr) {
9162 if (indtsp !=
nullptr) {
9163 _industile_mngr.SetEntitySpec(indtsp);
9172 for (uint i = 0; i < 3; i++) {
9177 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9191 if (objectspec !=
nullptr) {
9193 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9210 if (airportspec !=
nullptr) {
9212 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9213 _airport_mngr.SetEntitySpec(airportspec[i]);
9219 if (airporttilespec !=
nullptr) {
9221 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9222 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9235 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9249 static const SpecialSpriteHandler handlers[][GLS_END] = {
9250 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9251 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9252 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9253 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9254 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9255 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9256 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9257 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9258 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9259 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9260 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9261 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9262 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9264 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9267 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9270 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9275 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9276 if (it == _grf_line_to_action6_sprite_override.end()) {
9282 buf = _grf_line_to_action6_sprite_override[location];
9283 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9293 byte action = bufp->ReadByte();
9295 if (action == 0xFF) {
9296 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9297 }
else if (action == 0xFE) {
9298 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9299 }
else if (action >=
lengthof(handlers)) {
9300 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9301 }
else if (handlers[action][stage] ==
nullptr) {
9302 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9304 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9305 handlers[action][stage](bufp);
9308 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9315 extern const byte _grf_cont_v2_sig[8] = {
'G',
'R',
'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9349 const char *filename = config->
filename;
9360 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9362 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9368 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of file slots has been reached", filename);
9370 config->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9380 DEBUG(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9384 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9388 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9400 if (compression != 0) {
9401 DEBUG(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9413 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9427 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9438 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9439 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9503 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9504 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9505 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9506 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9507 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9508 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9519 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9523 int *grf_overrides =
AllocaM(
int, num_grfs);
9524 for (
int i = 0; i < num_grfs; i++) {
9525 grf_overrides[i] = -1;
9528 uint32
override = _grf_id_overrides[source->grfid];
9529 if (
override == 0)
continue;
9532 if (dest ==
nullptr)
continue;
9535 assert(grf_overrides[i] >= 0);
9539 for (
int i = 0; i < num_grfs; i++) {
9540 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9548 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9551 DEBUG(grf, 3,
"'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9557 for (
int i = num_grfs - 1; i >= 0; i--) {
9558 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9566 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9569 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9575 for (
int i = 0; i < num_grfs; i++) {
9576 if (grf_overrides[i] < 0)
continue;
9584 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9585 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9587 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9595 if (file->grf_version >= 8)
continue;
9596 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9597 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9599 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9602 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9609 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9610 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9611 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9613 price_base_multipliers[p] = 0;
9618 DEBUG(grf, 3,
"'%s' sets global price base multiplier %d", file->filename, p);
9620 price_base_multipliers[p] = 0;
9622 DEBUG(grf, 3,
"'%s' sets local price base multiplier %d", file->filename, p);
9637 _string_to_grf_mapping.clear();
9640 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9643 _grf_line_to_action6_sprite_override.clear();
9706 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9715 if (
_gted[e->
index].roadtramtype < list->size())
9717 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9735 e->u.rail.railtype = railtype;
9745 _grm_sprites.clear();
9754 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9794 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9801 if (stage == GLS_RESERVE) {
9802 static const uint32 overrides[][2] = {
9803 { 0x44442202, 0x44440111 },
9804 { 0x6D620402, 0x6D620401 },
9805 { 0x4D656f20, 0x4D656F17 },
9807 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9812 uint slot = file_index;
9813 uint num_non_static = 0;
9822 DEBUG(grf, 0,
"NewGRF file is missing '%s'; disabling", c->
filename);
9831 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9833 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9839 if (stage == GLS_RESERVE) {
9841 }
else if (stage == GLS_ACTIVATION) {
9846 DEBUG(sprite, 2,
"LoadNewGRF: Currently %i sprites are loaded", _cur.
spriteid);