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();
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);
3869 uint32 defsize = buf->ReadDWord();
3875 for (
byte j = 0; j < as->
num_table; j++) {
3877 for (
int k = 0;; k++) {
3878 att[k].
ti.
x = buf->ReadByte();
3879 att[k].
ti.
y = buf->ReadByte();
3881 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3884 att[k].
ti.
x = -0x80;
3893 att[k].
gfx = buf->ReadByte();
3895 if (att[k].gfx == 0xFE) {
3897 int local_tile_id = buf->ReadWord();
3900 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3903 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3906 att[k].
gfx = tempid;
3908 }
else if (att[k].gfx == 0xFF) {
3909 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3910 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3921 tile_table[j] = CallocT<AirportTileTable>(size);
3922 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3925 for (
int j = 0; j < old_num_table; j++) {
3931 as->
table = tile_table;
3934 for (
int i = 0; i < as->
num_table; i++) {
3935 free(tile_table[i]);
4041 if (_cur.
grffile->objectspec ==
nullptr) {
4045 for (
int i = 0; i < numinfo; i++) {
4048 if (prop != 0x08 && spec ==
nullptr) {
4051 if (cir > ret) ret = cir;
4060 if (*ospec ==
nullptr) {
4061 *ospec = CallocT<ObjectSpec>(1);
4062 (*ospec)->views = 1;
4063 (*ospec)->size = 0x11;
4067 uint32 classid = buf->ReadDWord();
4068 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4069 (*ospec)->enabled =
true;
4084 spec->
climate = buf->ReadByte();
4088 spec->
size = buf->ReadByte();
4089 if ((spec->
size & 0xF0) == 0 || (spec->
size & 0x0F) == 0) {
4090 grfmsg(1,
"ObjectChangeInfo: Invalid object size requested (%u) for object id %u. Ignoring.", spec->
size,
id + i);
4135 spec->
height = buf->ReadByte();
4139 spec->
views = buf->ReadByte();
4141 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4174 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4178 for (
int i = 0; i < numinfo; i++) {
4191 uint16 str = buf->ReadWord();
4193 if (_cur.
grffile->grf_version < 8) {
4223 int n = buf->ReadByte();
4224 for (
int j = 0; j != n; j++) {
4225 RailTypeLabel label = buf->ReadDWord();
4285 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4304 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4308 for (
int i = 0; i < numinfo; i++) {
4312 RailTypeLabel rtl = buf->ReadDWord();
4321 _cur.
grffile->railtype_map[
id + i] = rt;
4339 int n = buf->ReadByte();
4340 for (
int j = 0; j != n; j++) {
4345 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4352 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4393 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4397 for (
int i = 0; i < numinfo; i++) {
4410 uint16 str = buf->ReadWord();
4437 int n = buf->ReadByte();
4438 for (
int j = 0; j != n; j++) {
4439 RoadTypeLabel label = buf->ReadDWord();
4486 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4517 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4521 for (
int i = 0; i < numinfo; i++) {
4524 RoadTypeLabel rtl = buf->ReadDWord();
4531 }
else if (GetRoadTramType(rt) != rtt) {
4532 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4536 type_map[
id + i] = rt;
4553 int n = buf->ReadByte();
4554 for (
int j = 0; j != n; j++) {
4559 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4565 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4589 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4594 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4607 if (_cur.
grffile->airtspec ==
nullptr) {
4611 for (
int i = 0; i < numinfo; i++) {
4614 if (prop != 0x08 && tsp ==
nullptr) {
4615 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4622 byte subs_id = buf->ReadByte();
4626 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4631 if (*tilespec ==
nullptr) {
4632 *tilespec = CallocT<AirportTileSpec>(1);
4649 byte override = buf->ReadByte();
4653 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4657 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4687 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4690 default: NOT_REACHED();
4700 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4704 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4717 static void FeatureChangeInfo(
ByteReader *buf)
4730 static const VCI_Handler handler[] = {
4748 AirportTilesChangeInfo,
4753 uint8 feature = buf->ReadByte();
4754 uint8 numprops = buf->ReadByte();
4755 uint numinfo = buf->ReadByte();
4756 uint engine = buf->ReadExtendedByte();
4758 if (feature >= GSF_END) {
4759 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4763 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4764 feature, numprops, engine, numinfo);
4766 if (feature >=
lengthof(handler) || handler[feature] ==
nullptr) {
4767 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4774 while (numprops-- && buf->HasData()) {
4775 uint8 prop = buf->ReadByte();
4778 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4785 uint8 feature = buf->ReadByte();
4786 uint8 numprops = buf->ReadByte();
4787 uint numinfo = buf->ReadByte();
4788 buf->ReadExtendedByte();
4790 if (feature == GSF_BRIDGES && numprops == 1) {
4791 uint8 prop = buf->ReadByte();
4794 if (prop == 0x0D)
return;
4795 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4796 uint8 prop = buf->ReadByte();
4799 bool is_safe =
true;
4800 for (uint i = 0; i < numinfo; i++) {
4801 uint32 s = buf->ReadDWord();
4809 if (is_safe)
return;
4820 static void ReserveChangeInfo(
ByteReader *buf)
4822 uint8 feature = buf->ReadByte();
4824 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4826 uint8 numprops = buf->ReadByte();
4827 uint8 numinfo = buf->ReadByte();
4828 uint8 index = buf->ReadExtendedByte();
4830 while (numprops-- && buf->HasData()) {
4831 uint8 prop = buf->ReadByte();
4835 default: NOT_REACHED();
4841 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4845 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4849 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4853 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4857 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4878 uint8 feature = buf->ReadByte();
4879 uint16 num_sets = buf->ReadByte();
4880 uint16 first_set = 0;
4882 if (num_sets == 0 && buf->HasData(3)) {
4885 first_set = buf->ReadExtendedByte();
4886 num_sets = buf->ReadExtendedByte();
4888 uint16 num_ents = buf->ReadExtendedByte();
4890 if (feature >= GSF_END) {
4892 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4898 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4899 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4902 for (
int i = 0; i < num_sets * num_ents; i++) {
4912 uint16 num_sets = buf->ReadByte();
4914 if (num_sets == 0 && buf->HasData(3)) {
4917 buf->ReadExtendedByte();
4918 num_sets = buf->ReadExtendedByte();
4920 uint16 num_ents = buf->ReadExtendedByte();
4929 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4931 if (
HasBit(groupid, 15)) {
4936 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4937 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4941 return _cur.spritegroups[groupid];
4954 if (
HasBit(spriteid, 15)) {
4960 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4965 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4968 assert(spriteset_start + num_sprites <= _cur.
spriteid);
4989 uint8 feature = buf->ReadByte();
4990 if (feature >= GSF_END) {
4991 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4995 uint8 setid = buf->ReadByte();
4996 uint8 type = buf->ReadByte();
5020 switch (
GB(type, 2, 2)) {
5021 default: NOT_REACHED();
5022 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5023 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5024 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5027 static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5037 adjust.variable = buf->ReadByte();
5038 if (adjust.variable == 0x7E) {
5040 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5045 varadjust = buf->ReadByte();
5046 adjust.shift_num =
GB(varadjust, 0, 5);
5047 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5048 adjust.and_mask = buf->ReadVarSize(varsize);
5050 if (adjust.type != DSGA_TYPE_NONE) {
5051 adjust.add_val = buf->ReadVarSize(varsize);
5052 adjust.divmod_val = buf->ReadVarSize(varsize);
5055 adjust.divmod_val = 0;
5059 }
while (
HasBit(varadjust, 5));
5061 group->num_adjusts = (uint)adjusts.size();
5062 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5063 MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
5065 std::vector<DeterministicSpriteGroupRange> ranges;
5066 ranges.resize(buf->ReadByte());
5067 for (uint i = 0; i < ranges.size(); i++) {
5068 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5069 ranges[i].low = buf->ReadVarSize(varsize);
5070 ranges[i].high = buf->ReadVarSize(varsize);
5073 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5074 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5076 group->calculated_result = ranges.size() == 0;
5079 std::vector<uint32> bounds;
5080 for (uint i = 0; i < ranges.size(); i++) {
5081 bounds.push_back(ranges[i].low);
5082 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5084 std::sort(bounds.begin(), bounds.end());
5085 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5087 std::vector<const SpriteGroup *> target;
5088 for (uint j = 0; j < bounds.size(); ++j) {
5089 uint32 v = bounds[j];
5091 for (uint i = 0; i < ranges.size(); i++) {
5092 if (ranges[i].low <= v && v <= ranges[i].high) {
5093 t = ranges[i].group;
5097 target.push_back(t);
5099 assert(target.size() == bounds.size());
5101 std::vector<DeterministicSpriteGroupRange> optimised;
5102 for (uint j = 0; j < bounds.size(); ) {
5103 if (target[j] != group->default_group) {
5105 r.group = target[j];
5107 while (j < bounds.size() && target[j] == r.group) {
5110 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5111 optimised.push_back(r);
5117 group->num_ranges = (uint)optimised.size();
5118 if (group->num_ranges > 0) {
5119 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5120 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5138 group->count = buf->ReadByte();
5141 uint8 triggers = buf->ReadByte();
5142 group->triggers =
GB(triggers, 0, 7);
5143 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5148 for (uint i = 0; i < group->
num_groups; i++) {
5149 group->
groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5160 case GSF_ROADVEHICLES:
5171 byte num_loaded = type;
5172 byte num_loading = buf->ReadByte();
5175 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5186 if (num_loaded > 0) group->
loaded = CallocT<const SpriteGroup*>(num_loaded);
5187 if (num_loading > 0) group->
loading = CallocT<const SpriteGroup*>(num_loading);
5189 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5190 setid, num_loaded, num_loading);
5192 for (uint i = 0; i < num_loaded; i++) {
5193 uint16 spriteid = buf->ReadWord();
5195 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5198 for (uint i = 0; i < num_loading; i++) {
5199 uint16 spriteid = buf->ReadWord();
5201 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5208 case GSF_AIRPORTTILES:
5210 case GSF_INDUSTRYTILES: {
5211 byte num_building_sprites = std::max((uint8)1, type);
5219 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5223 case GSF_INDUSTRIES: {
5225 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5236 for (uint i = 0; i < 3; i++) {
5240 for (uint i = 0; i < 2; i++) {
5243 group->again = buf->ReadByte();
5244 }
else if (type == 1) {
5246 for (uint i = 0; i < 3; i++) {
5250 for (uint i = 0; i < 2; i++) {
5253 group->again = buf->ReadByte();
5254 }
else if (type == 2) {
5258 error->data =
"too many inputs (max 16)";
5261 for (uint i = 0; i < group->
num_input; i++) {
5262 byte rawcargo = buf->ReadByte();
5271 error->data =
"duplicate input cargo";
5280 error->data =
"too many outputs (max 16)";
5283 for (uint i = 0; i < group->
num_output; i++) {
5284 byte rawcargo = buf->ReadByte();
5291 error->data =
"duplicate output cargo";
5297 group->again = buf->ReadByte();
5305 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5310 _cur.spritegroups[setid] = act_group;
5313 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5315 if (feature == GSF_OBJECTS) {
5320 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5325 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5326 if (ctype == 0xFF)
return CT_PURCHASE;
5331 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5336 FOR_ALL_CARGOSPECS(cs) {
5337 if (cs->
bitnum == ctype) {
5338 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->
Index());
5343 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5349 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5356 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5362 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));
5366 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);
5371 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5373 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5374 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5381 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5384 static uint last_engines_count;
5385 bool wagover =
false;
5388 if (
HasBit(idcount, 7)) {
5391 idcount =
GB(idcount, 0, 7);
5393 if (last_engines_count == 0) {
5394 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5398 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5399 last_engines_count, idcount);
5401 if (last_engines_count != idcount) {
5402 last_engines =
ReallocT(last_engines, idcount);
5403 last_engines_count = idcount;
5408 for (uint i = 0; i < idcount; i++) {
5414 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5418 engines[i] = e->
index;
5419 if (!wagover) last_engines[i] = engines[i];
5422 uint8 cidcount = buf->ReadByte();
5423 for (uint c = 0; c < cidcount; c++) {
5424 uint8 ctype = buf->ReadByte();
5425 uint16 groupid = buf->ReadWord();
5426 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5428 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5430 ctype = TranslateCargo(feature, ctype);
5433 for (uint i = 0; i < idcount; i++) {
5436 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5439 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5441 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5446 uint16 groupid = buf->ReadWord();
5447 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5449 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5451 for (uint i = 0; i < idcount; i++) {
5455 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5457 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5464 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5467 for (uint i = 0; i < idcount; i++) {
5471 uint8 cidcount = buf->ReadByte();
5472 buf->Skip(cidcount * 3);
5474 uint16 groupid = buf->ReadWord();
5475 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5477 for (uint i = 0; i < idcount; i++) {
5481 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5491 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5493 uint8 *stations =
AllocaM(uint8, idcount);
5494 for (uint i = 0; i < idcount; i++) {
5495 stations[i] = buf->ReadByte();
5498 uint8 cidcount = buf->ReadByte();
5499 for (uint c = 0; c < cidcount; c++) {
5500 uint8 ctype = buf->ReadByte();
5501 uint16 groupid = buf->ReadWord();
5502 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5504 ctype = TranslateCargo(GSF_STATIONS, ctype);
5507 for (uint i = 0; i < idcount; i++) {
5510 if (statspec ==
nullptr) {
5511 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5519 uint16 groupid = buf->ReadWord();
5520 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5522 for (uint i = 0; i < idcount; i++) {
5525 if (statspec ==
nullptr) {
5526 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5531 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5538 StationClass::Assign(statspec);
5543 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5545 uint8 *houses =
AllocaM(uint8, idcount);
5546 for (uint i = 0; i < idcount; i++) {
5547 houses[i] = buf->ReadByte();
5551 uint8 cidcount = buf->ReadByte();
5552 buf->Skip(cidcount * 3);
5554 uint16 groupid = buf->ReadWord();
5555 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5557 if (_cur.
grffile->housespec ==
nullptr) {
5558 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5562 for (uint i = 0; i < idcount; i++) {
5565 if (hs ==
nullptr) {
5566 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5574 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5576 uint8 *industries =
AllocaM(uint8, idcount);
5577 for (uint i = 0; i < idcount; i++) {
5578 industries[i] = buf->ReadByte();
5582 uint8 cidcount = buf->ReadByte();
5583 buf->Skip(cidcount * 3);
5585 uint16 groupid = buf->ReadWord();
5586 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5588 if (_cur.
grffile->industryspec ==
nullptr) {
5589 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5593 for (uint i = 0; i < idcount; i++) {
5596 if (indsp ==
nullptr) {
5597 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5605 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5607 uint8 *indtiles =
AllocaM(uint8, idcount);
5608 for (uint i = 0; i < idcount; i++) {
5609 indtiles[i] = buf->ReadByte();
5613 uint8 cidcount = buf->ReadByte();
5614 buf->Skip(cidcount * 3);
5616 uint16 groupid = buf->ReadWord();
5617 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5619 if (_cur.
grffile->indtspec ==
nullptr) {
5620 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5624 for (uint i = 0; i < idcount; i++) {
5627 if (indtsp ==
nullptr) {
5628 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5636 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5639 for (uint i = 0; i < idcount; i++) {
5640 cargoes[i] = buf->ReadByte();
5644 uint8 cidcount = buf->ReadByte();
5645 buf->Skip(cidcount * 3);
5647 uint16 groupid = buf->ReadWord();
5648 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5650 for (uint i = 0; i < idcount; i++) {
5654 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5660 cs->group = _cur.spritegroups[groupid];
5664 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5666 if (_cur.
grffile->objectspec ==
nullptr) {
5667 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5671 uint8 *objects =
AllocaM(uint8, idcount);
5672 for (uint i = 0; i < idcount; i++) {
5673 objects[i] = buf->ReadByte();
5676 uint8 cidcount = buf->ReadByte();
5677 for (uint c = 0; c < cidcount; c++) {
5678 uint8 ctype = buf->ReadByte();
5679 uint16 groupid = buf->ReadWord();
5680 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5682 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5685 for (uint i = 0; i < idcount; i++) {
5688 if (spec ==
nullptr) {
5689 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5697 uint16 groupid = buf->ReadWord();
5698 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5700 for (uint i = 0; i < idcount; i++) {
5703 if (spec ==
nullptr) {
5704 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5709 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5719 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5721 uint8 *railtypes =
AllocaM(uint8, idcount);
5722 for (uint i = 0; i < idcount; i++) {
5723 uint8
id = buf->ReadByte();
5727 uint8 cidcount = buf->ReadByte();
5728 for (uint c = 0; c < cidcount; c++) {
5729 uint8 ctype = buf->ReadByte();
5730 uint16 groupid = buf->ReadWord();
5731 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5733 if (ctype >= RTSG_END)
continue;
5736 for (uint i = 0; i < idcount; i++) {
5741 rti->
group[ctype] = _cur.spritegroups[groupid];
5750 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5754 uint8 *roadtypes =
AllocaM(uint8, idcount);
5755 for (uint i = 0; i < idcount; i++) {
5756 uint8
id = buf->ReadByte();
5760 uint8 cidcount = buf->ReadByte();
5761 for (uint c = 0; c < cidcount; c++) {
5762 uint8 ctype = buf->ReadByte();
5763 uint16 groupid = buf->ReadWord();
5764 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5766 if (ctype >= ROTSG_END)
continue;
5769 for (uint i = 0; i < idcount; i++) {
5774 rti->
group[ctype] = _cur.spritegroups[groupid];
5783 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5785 uint8 *airports =
AllocaM(uint8, idcount);
5786 for (uint i = 0; i < idcount; i++) {
5787 airports[i] = buf->ReadByte();
5791 uint8 cidcount = buf->ReadByte();
5792 buf->Skip(cidcount * 3);
5794 uint16 groupid = buf->ReadWord();
5795 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5797 if (_cur.
grffile->airportspec ==
nullptr) {
5798 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5802 for (uint i = 0; i < idcount; i++) {
5805 if (as ==
nullptr) {
5806 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5814 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5816 uint8 *airptiles =
AllocaM(uint8, idcount);
5817 for (uint i = 0; i < idcount; i++) {
5818 airptiles[i] = buf->ReadByte();
5822 uint8 cidcount = buf->ReadByte();
5823 buf->Skip(cidcount * 3);
5825 uint16 groupid = buf->ReadWord();
5826 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5828 if (_cur.
grffile->airtspec ==
nullptr) {
5829 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5833 for (uint i = 0; i < idcount; i++) {
5836 if (airtsp ==
nullptr) {
5837 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5847 static void FeatureMapSpriteGroup(
ByteReader *buf)
5863 uint8 feature = buf->ReadByte();
5864 uint8 idcount = buf->ReadByte();
5866 if (feature >= GSF_END) {
5867 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5875 uint16 groupid = buf->ReadWord();
5876 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5878 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5887 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5891 case GSF_ROADVEHICLES:
5894 VehicleMapSpriteGroup(buf, feature, idcount);
5898 CanalMapSpriteGroup(buf, idcount);
5902 StationMapSpriteGroup(buf, idcount);
5906 TownHouseMapSpriteGroup(buf, idcount);
5909 case GSF_INDUSTRIES:
5910 IndustryMapSpriteGroup(buf, idcount);
5913 case GSF_INDUSTRYTILES:
5914 IndustrytileMapSpriteGroup(buf, idcount);
5918 CargoMapSpriteGroup(buf, idcount);
5922 AirportMapSpriteGroup(buf, idcount);
5926 ObjectMapSpriteGroup(buf, idcount);
5930 RailTypeMapSpriteGroup(buf, idcount);
5934 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5938 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5941 case GSF_AIRPORTTILES:
5942 AirportTileMapSpriteGroup(buf, idcount);
5946 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5970 bool new_scheme = _cur.
grffile->grf_version >= 7;
5972 uint8 feature = buf->ReadByte();
5973 if (feature >= GSF_END && feature != 0x48) {
5974 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5978 uint8 lang = buf->ReadByte();
5979 uint8 num = buf->ReadByte();
5980 bool generic =
HasBit(lang, 7);
5983 id = buf->ReadWord();
5984 }
else if (feature <= GSF_AIRCRAFT) {
5985 id = buf->ReadExtendedByte();
5987 id = buf->ReadByte();
5992 uint16 endid =
id + num;
5994 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5995 id, endid, feature, lang);
5997 for (;
id < endid && buf->HasData();
id++) {
5998 const char *name = buf->ReadString();
5999 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6003 case GSF_ROADVEHICLES:
6008 if (e ==
nullptr)
break;
6022 switch (
GB(
id, 8, 8)) {
6024 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6025 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6033 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6034 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6041 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6042 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6049 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6050 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6057 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6076 if (offset >= max_sprites) {
6077 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6078 uint orig_num = num;
6083 if (offset + num > max_sprites) {
6084 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6085 uint orig_num = num;
6086 num = std::max(max_sprites - offset, 0);
6087 return orig_num - num;
6116 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6118 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6148 uint8 type = buf->ReadByte();
6149 uint16 num = buf->ReadExtendedByte();
6150 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6156 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6173 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6184 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6191 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);
6201 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);
6212 for (; num > 0; num--) {
6283 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6313 *value = _game_mode;
6347 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6356 *value = _openttd_newgrf_version;
6371 default:
return false;
6375 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6393 if (cond_val ==
nullptr) {
6397 uint32 index = *cond_val / 0x20;
6413 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6436 byte *preload_sprite =
nullptr;
6440 preload_sprite = MallocT<byte>(num);
6448 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6449 free(preload_sprite);
6454 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6455 if (it != _grf_line_to_action6_sprite_override.end()) {
6456 free(preload_sprite);
6457 preload_sprite = _grf_line_to_action6_sprite_override[location];
6459 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6472 param_num = buf->ReadByte();
6473 if (param_num == 0xFF)
break;
6477 param_size = buf->ReadByte();
6481 add_value =
HasBit(param_size, 7);
6482 param_size =
GB(param_size, 0, 7);
6485 offset = buf->ReadExtendedByte();
6489 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6490 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6494 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6497 for (i = 0; i < param_size && offset + i < num; i++) {
6498 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6501 if (i % 4 == 0) carry =
false;
6504 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6505 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6507 carry = new_value >= 256;
6509 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6541 uint32 cond_val = 0;
6545 uint8 param = buf->ReadByte();
6546 uint8 paramsize = buf->ReadByte();
6547 uint8 condtype = buf->ReadByte();
6554 switch (paramsize) {
6555 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6556 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6557 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6558 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6562 if (param < 0x80 && _cur.grffile->param_end <= param) {
6563 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6567 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6572 if (condtype >= 0x0B) {
6603 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6605 }
else if (param == 0x88) {
6615 if (condtype != 10 && c ==
nullptr) {
6616 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6643 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6647 uint32 param_val = GetParamVal(param, &cond_val);
6649 case 0x00: result = !!(param_val & (1 << cond_val));
6651 case 0x01: result = !(param_val & (1 << cond_val));
6653 case 0x02: result = (param_val & mask) == cond_val;
6655 case 0x03: result = (param_val & mask) != cond_val;
6657 case 0x04: result = (param_val & mask) < cond_val;
6659 case 0x05: result = (param_val & mask) > cond_val;
6661 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6666 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6670 uint8 numsprites = buf->ReadByte();
6678 if (label->label != numsprites)
continue;
6681 if (choice ==
nullptr) choice = label;
6683 if (label->nfo_line > _cur.
nfo_line) {
6689 if (choice !=
nullptr) {
6690 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6696 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6715 uint8 grf_version = buf->ReadByte();
6716 uint32 grfid = buf->ReadDWord();
6717 const char *name = buf->ReadString();
6721 if (grf_version < 2 || grf_version > 8) {
6723 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);
6731 if (buf->HasData()) {
6732 const char *info = buf->ReadString();
6750 uint8 version = buf->ReadByte();
6751 uint32 grfid = buf->ReadDWord();
6752 const char *name = buf->ReadString();
6755 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6759 if (_cur.
grffile->grfid != grfid) {
6760 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));
6764 _cur.
grffile->grf_version = version;
6782 uint8 num_sets = buf->ReadByte();
6784 for (uint i = 0; i < num_sets; i++) {
6785 uint8 num_sprites = buf->ReadByte();
6786 uint16 first_sprite = buf->ReadWord();
6788 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6789 i, num_sprites, first_sprite
6792 for (uint j = 0; j < num_sprites; j++) {
6793 int load_index = first_sprite + j;
6799 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6809 uint8 num_sets = buf->ReadByte();
6811 for (uint i = 0; i < num_sets; i++) {
6840 STR_NEWGRF_ERROR_VERSION_NUMBER,
6841 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6842 STR_NEWGRF_ERROR_UNSET_SWITCH,
6843 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6844 STR_NEWGRF_ERROR_LOAD_BEFORE,
6845 STR_NEWGRF_ERROR_LOAD_AFTER,
6846 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6850 STR_NEWGRF_ERROR_MSG_INFO,
6851 STR_NEWGRF_ERROR_MSG_WARNING,
6852 STR_NEWGRF_ERROR_MSG_ERROR,
6853 STR_NEWGRF_ERROR_MSG_FATAL
6856 byte severity = buf->ReadByte();
6857 byte lang = buf->ReadByte();
6858 byte message_id = buf->ReadByte();
6861 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6865 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6866 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6871 if (severity >=
lengthof(sevstr)) {
6872 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6874 }
else if (severity == 3) {
6884 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6885 grfmsg(7,
"GRFLoadError: Invalid message id.");
6889 if (buf->Remaining() <= 1) {
6890 grfmsg(7,
"GRFLoadError: No message data supplied.");
6899 if (message_id == 0xFF) {
6901 if (buf->HasData()) {
6902 const char *message = buf->ReadString();
6906 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6907 error->custom_message.clear();
6910 error->message = msgstr[message_id];
6913 if (buf->HasData()) {
6914 const char *data = buf->ReadString();
6918 grfmsg(7,
"GRFLoadError: No message data supplied.");
6919 error->data.clear();
6923 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6924 uint param_number = buf->ReadByte();
6938 if (!buf->HasData())
return;
6940 const char *text = buf->ReadString();
6941 grfmsg(2,
"GRFComment: %s", text);
6947 uint8 target = buf->ReadByte();
6950 if (target < 0x80 || target == 0x9E)
return;
6964 static uint32 GetPatchVariable(uint8 param)
6974 case 0x0F:
return 0;
6990 case 0x11:
return SPR_2CCMAP_BASE;
7007 byte max_edge = std::max(log_X, log_Y);
7009 if (log_X == log_Y) {
7012 if (max_edge == log_Y)
SetBit(map_bits, 1);
7015 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7016 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7025 return SPR_SLOPES_BASE;
7032 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7038 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7051 for (uint i = start; i < num_ids; i++) {
7055 if (op == 2 || op == 3)
break;
7060 if (size == count)
break;
7063 if (size == count) {
7065 if (op == 0 || op == 3) {
7066 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7067 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7073 if (op != 4 && op != 5) {
7075 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7080 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7110 uint8 target = buf->ReadByte();
7111 uint8 oper = buf->ReadByte();
7112 uint32 src1 = buf->ReadByte();
7113 uint32 src2 = buf->ReadByte();
7116 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7125 if (target < 0x80 && target < _cur.grffile->param_end) {
7126 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7130 oper =
GB(oper, 0, 7);
7134 if (
GB(data, 0, 8) == 0xFF) {
7135 if (data == 0x0000FFFF) {
7137 src1 = GetPatchVariable(src1);
7141 uint8 feature =
GB(data, 8, 8);
7142 uint16 count =
GB(data, 16, 16);
7144 if (_cur.
stage == GLS_RESERVE) {
7145 if (feature == 0x08) {
7149 if (_cur.
spriteid + count >= 16384) {
7150 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7156 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7163 }
else if (_cur.
stage == GLS_ACTIVATION) {
7192 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7200 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7211 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7228 }
else if (src1 == 0xFE) {
7240 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7241 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7263 res = (int32)src1 * (int32)src2;
7267 if ((int32)src2 < 0) {
7268 res = src1 >> -(int32)src2;
7270 res = src1 << (src2 & 0x1F);
7275 if ((int32)src2 < 0) {
7276 res = (int32)src1 >> -(int32)src2;
7278 res = (int32)src1 << (src2 & 0x1F);
7302 res = (int32)src1 / (int32)src2;
7318 res = (int32)src1 % (int32)src2;
7322 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7351 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7362 uint32 safe_bits = 0;
7363 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7372 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7376 if (target < 0x80) {
7377 _cur.
grffile->param[target] = res;
7381 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7395 uint8 num = buf->ReadByte();
7397 for (uint i = 0; i < num; i++) {
7398 uint32 grfid = buf->ReadDWord();
7420 uint8 num = buf->ReadByte();
7422 for (uint i = 0; i < num; i++) {
7423 uint32 grfid = buf->ReadDWord();
7427 if (file !=
nullptr && file != _cur.
grfconfig) {
7445 uint32 grfid = _cur.
grffile->grfid;
7449 byte id = buf->ReadByte();
7450 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7455 bool new_scheme = _cur.
grffile->grf_version >= 7;
7457 byte lang = buf->ReadByte();
7459 byte nb_gen = townname->nb_gen;
7463 const char *name = buf->ReadString();
7466 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7468 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7470 lang = buf->ReadByte();
7471 }
while (lang != 0);
7472 townname->id[nb_gen] = id;
7476 byte nb = buf->ReadByte();
7477 grfmsg(6,
"FeatureTownName: %u parts", nb);
7479 townname->nbparts[id] = nb;
7480 townname->partlist[id] = CallocT<NamePartList>(nb);
7482 for (
int i = 0; i < nb; i++) {
7483 byte nbtext = buf->ReadByte();
7484 townname->partlist[id][i].bitstart = buf->ReadByte();
7485 townname->partlist[id][i].bitcount = buf->ReadByte();
7486 townname->partlist[id][i].maxprob = 0;
7487 townname->partlist[id][i].partcount = nbtext;
7488 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7489 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);
7491 for (
int j = 0; j < nbtext; j++) {
7492 byte prob = buf->ReadByte();
7495 byte ref_id = buf->ReadByte();
7497 if (townname->nbparts[ref_id] == 0) {
7498 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7499 DelGRFTownName(grfid);
7504 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7505 townname->partlist[id][i].parts[j].data.
id = ref_id;
7507 const char *text = buf->ReadString();
7509 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7511 townname->partlist[id][i].parts[j].
prob = prob;
7512 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7514 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7526 byte nfo_label = buf->ReadByte();
7528 GRFLabel *label = MallocT<GRFLabel>(1);
7529 label->label = nfo_label;
7532 label->next =
nullptr;
7540 for (l = _cur.
grffile->
label; l->next !=
nullptr; l = l->next) {}
7544 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7558 if (file ==
nullptr || file->sound_offset == 0) {
7559 grfmsg(1,
"ImportGRFSound: Source file not available");
7563 if (sound_id >= file->num_sounds) {
7564 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7568 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7570 *sound = *GetSound(file->sound_offset + sound_id);
7573 sound->volume = 128;
7574 sound->priority = 0;
7585 sound->volume = 0x80;
7586 sound->priority = 0;
7588 if (offs != SIZE_MAX) {
7591 sound->file_offset = offs;
7603 uint16 num = buf->ReadWord();
7604 if (num == 0)
return;
7607 if (_cur.
grffile->sound_offset == 0) {
7608 _cur.
grffile->sound_offset = GetNumSounds();
7609 _cur.
grffile->num_sounds = num;
7612 sound = GetSound(_cur.
grffile->sound_offset);
7615 for (
int i = 0; i < num; i++) {
7620 bool invalid = i >= _cur.
grffile->num_sounds;
7630 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7632 }
else if (len != 4) {
7633 grfmsg(1,
"GRFSound: Invalid sprite section import");
7643 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7650 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7658 if (_cur.
stage == GLS_INIT) {
7660 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7669 if (_cur.
stage == GLS_ACTIVATION) {
7680 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7709 uint8 num_def = buf->ReadByte();
7711 for (uint i = 0; i < num_def; i++) {
7713 uint8 num_char = buf->ReadByte();
7714 uint16 base_char = buf->ReadWord();
7716 if (size >= FS_END) {
7717 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7720 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7722 for (uint c = 0; c < num_char; c++) {
7740 uint8 num_def = buf->ReadByte();
7742 for (uint i = 0; i < num_def; i++) {
7766 uint32 grfid = buf->ReadDWord();
7769 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7779 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE,
lastof(tmp));
7790 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7791 byte num_strings = buf->ReadByte();
7792 uint16 first_id = buf->ReadWord();
7794 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7795 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7799 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7800 const char *
string = buf->ReadString();
7803 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7807 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7836 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7848 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7851 char data = buf->ReadByte();
7859 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7874 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7877 char data = buf->ReadByte();
7883 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7896 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7909 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7914 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7945 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7952 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7962 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7964 }
else if (len != 8) {
7965 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
7968 uint32 min_value = buf->ReadDWord();
7969 uint32 max_value = buf->ReadDWord();
7970 if (min_value <= max_value) {
7974 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7983 if (len < 1 || len > 3) {
7984 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
7987 byte param_nr = buf->ReadByte();
7989 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8005 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8041 this->handler.data = handler;
8053 this->handler.text = handler;
8065 this->handler.call_handler =
true;
8066 this->handler.u.branch = handler;
8078 this->handler.call_handler =
false;
8079 this->handler.u.subtags =
subtags;
8108 byte type = buf->ReadByte();
8110 uint32
id = buf->ReadDWord();
8112 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8114 type = buf->ReadByte();
8118 byte langid = buf->ReadByte();
8119 const char *name_string = buf->ReadString();
8130 type = buf->ReadByte();
8155 byte type = buf->ReadByte();
8157 uint32
id = buf->ReadDWord();
8159 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8161 type = buf->ReadByte();
8174 type = buf->ReadByte();
8211 byte new_type = buf->ReadByte();
8212 while (new_type != 0) {
8215 new_type = buf->ReadByte();
8226 uint16 size = buf->ReadWord();
8250 while ((tag = &subtags[i++])->type != 0) {
8253 default: NOT_REACHED();
8256 byte langid = buf->ReadByte();
8257 return tag->handler.
text(langid, buf->ReadString());
8261 size_t len = buf->ReadWord();
8262 if (buf->Remaining() < len)
return false;
8263 return tag->handler.
data(len, buf);
8268 return tag->handler.u.branch(buf);
8274 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8286 byte type = buf->ReadByte();
8288 uint32
id = buf->ReadDWord();
8289 if (!
HandleNode(type,
id, buf, subtags))
return false;
8290 type = buf->ReadByte();
8412 if (stations ==
nullptr)
continue;
8414 if (stations[i] ==
nullptr)
continue;
8420 if (!statspec->copied_layouts) {
8421 for (uint l = 0; l < statspec->lengths; l++) {
8422 for (uint p = 0; p < statspec->platforms[l]; p++) {
8423 free(statspec->layouts[l][p]);
8425 free(statspec->layouts[l]);
8427 free(statspec->layouts);
8428 free(statspec->platforms);
8445 HouseSpec **&housespec = file->housespec;
8446 if (housespec ==
nullptr)
continue;
8452 housespec =
nullptr;
8461 if (aslist !=
nullptr) {
8465 if (as !=
nullptr) {
8467 for (
int j = 0; j < as->
num_table; j++) {
8479 file->airportspec =
nullptr;
8483 if (airporttilespec !=
nullptr) {
8485 free(airporttilespec[i]);
8487 free(airporttilespec);
8488 airporttilespec =
nullptr;
8502 if (industryspec !=
nullptr) {
8509 industryspec =
nullptr;
8512 if (indtspec ==
nullptr)
continue;
8527 if (objectspec ==
nullptr)
continue;
8529 free(objectspec[i]);
8533 objectspec =
nullptr;
8565 CleanUpGRFTownNames();
8609 ObjectClass::Reset();
8614 StationClass::Reset();
8618 AirportClass::Reset();
8647 _grf_id_overrides.clear();
8649 InitializeSoundPool();
8697 if (newfile !=
nullptr) {
8703 newfile =
new GRFFile(config);
8721 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8726 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8733 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8737 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8753 free(this->filename);
8763 'PASS',
'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
8764 'IORE',
'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
8765 'WATR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8769 static const CargoLabel _default_refitmasks_road[] = {
8772 static const CargoLabel _default_refitmasks_ships[] = {
8773 'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
'IORE',
8774 'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
'WATR',
8775 'RUBR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8779 static const CargoLabel _default_refitmasks_aircraft[] = {
8780 'PASS',
'MAIL',
'GOOD',
'VALU',
'GOLD',
'DIAM',
'FOOD',
'FRUT',
'SUGR',
8781 'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
'PLST',
'FZDR',
8784 static const CargoLabel *
const _default_refitmasks[] = {
8786 _default_refitmasks_road,
8787 _default_refitmasks_ships,
8788 _default_refitmasks_aircraft,
8800 bool only_defaultcargo;
8804 CargoTypes mask = 0;
8805 CargoTypes not_mask = 0;
8806 CargoTypes xor_mask = ei->refit_mask;
8812 if (
_gted[engine].cargo_allowed != 0) {
8815 FOR_ALL_CARGOSPECS(cs) {
8821 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8827 CargoTypes xor_mask = 0;
8832 for (uint i = 0;; i++) {
8833 if (cl[i] == 0)
break;
8845 only_defaultcargo = (ei->refit_mask == 0);
8859 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8861 const uint8 *cargo_map_for_first_refittable =
nullptr;
8864 if (file ==
nullptr) file = e->
GetGRF();
8865 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8866 cargo_map_for_first_refittable = file->
cargo_map;
8870 if (cargo_map_for_first_refittable !=
nullptr) {
8872 byte best_local_slot = 0xFF;
8874 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8875 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8876 if (local_slot < best_local_slot) {
8877 best_local_slot = local_slot;
8878 ei->cargo_type = cargo_type;
8900 for (uint i = 0; i < CF_END; i++) {
8912 if (e->
GetGRF() ==
nullptr) {
8915 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
8950 default: NOT_REACHED();
8964 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8965 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8989 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);
8999 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);
9007 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);
9014 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);
9033 if (hs ==
nullptr || !hs->
enabled)
continue;
9038 if (min_year == 0)
return;
9042 if (hs ==
nullptr || !hs->
enabled)
continue;
9066 HouseSpec **&housespec = file->housespec;
9067 if (housespec ==
nullptr)
continue;
9072 if (hs ==
nullptr)
continue;
9130 if (industryspec !=
nullptr) {
9134 if (indsp !=
nullptr && indsp->
enabled) {
9140 if (strid != STR_UNDEFINED) indsp->
name = strid;
9143 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9158 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9166 if (indtspec !=
nullptr) {
9169 if (indtsp !=
nullptr) {
9170 _industile_mngr.SetEntitySpec(indtsp);
9179 for (uint i = 0; i < 3; i++) {
9184 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9198 if (objectspec !=
nullptr) {
9200 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9217 if (airportspec !=
nullptr) {
9219 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9220 _airport_mngr.SetEntitySpec(airportspec[i]);
9226 if (airporttilespec !=
nullptr) {
9228 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9229 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9242 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9256 static const SpecialSpriteHandler handlers[][GLS_END] = {
9257 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9258 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9259 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9260 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9261 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9262 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9263 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9264 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9265 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9266 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9267 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9268 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9269 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9271 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9274 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9277 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9282 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9283 if (it == _grf_line_to_action6_sprite_override.end()) {
9289 buf = _grf_line_to_action6_sprite_override[location];
9290 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9300 byte action = bufp->ReadByte();
9302 if (action == 0xFF) {
9303 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9304 }
else if (action == 0xFE) {
9305 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9306 }
else if (action >=
lengthof(handlers)) {
9307 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9308 }
else if (handlers[action][stage] ==
nullptr) {
9309 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9311 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9312 handlers[action][stage](bufp);
9315 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9322 extern const byte _grf_cont_v2_sig[8] = {
'G',
'R',
'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9356 const char *filename = config->
filename;
9367 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9369 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9375 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of file slots has been reached", filename);
9377 config->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9387 DEBUG(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9391 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9395 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9407 if (compression != 0) {
9408 DEBUG(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9420 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9434 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9445 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9446 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9510 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9511 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9512 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9513 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9514 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9515 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9526 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9530 int *grf_overrides =
AllocaM(
int, num_grfs);
9531 for (
int i = 0; i < num_grfs; i++) {
9532 grf_overrides[i] = -1;
9535 uint32
override = _grf_id_overrides[source->grfid];
9536 if (
override == 0)
continue;
9539 if (dest ==
nullptr)
continue;
9542 assert(grf_overrides[i] >= 0);
9546 for (
int i = 0; i < num_grfs; i++) {
9547 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9555 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9558 DEBUG(grf, 3,
"'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9564 for (
int i = num_grfs - 1; i >= 0; i--) {
9565 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9573 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9576 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9582 for (
int i = 0; i < num_grfs; i++) {
9583 if (grf_overrides[i] < 0)
continue;
9591 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9592 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9594 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9602 if (file->grf_version >= 8)
continue;
9603 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9604 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9606 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9609 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9616 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9617 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9618 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9620 price_base_multipliers[p] = 0;
9625 DEBUG(grf, 3,
"'%s' sets global price base multiplier %d", file->filename, p);
9627 price_base_multipliers[p] = 0;
9629 DEBUG(grf, 3,
"'%s' sets local price base multiplier %d", file->filename, p);
9644 _string_to_grf_mapping.clear();
9647 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9650 _grf_line_to_action6_sprite_override.clear();
9713 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9722 if (
_gted[e->
index].roadtramtype < list->size())
9724 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9742 e->u.rail.railtype = railtype;
9752 _grm_sprites.clear();
9761 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9801 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9808 if (stage == GLS_RESERVE) {
9809 static const uint32 overrides[][2] = {
9810 { 0x44442202, 0x44440111 },
9811 { 0x6D620402, 0x6D620401 },
9812 { 0x4D656f20, 0x4D656F17 },
9814 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9819 uint slot = file_index;
9820 uint num_non_static = 0;
9829 DEBUG(grf, 0,
"NewGRF file is missing '%s'; disabling", c->
filename);
9838 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9840 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9846 if (stage == GLS_RESERVE) {
9848 }
else if (stage == GLS_ACTIVATION) {
9853 DEBUG(sprite, 2,
"LoadNewGRF: Currently %i sprites are loaded", _cur.
spriteid);