51 #include "table/strings.h"
68 const std::vector<GRFFile *> &GetAllGRFFiles()
118 this->skip_sprites = 0;
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
124 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.
sprite = first_sprite + i * numents;
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
179 return this->spritesets[feature].find(set)->second.sprite;
191 return this->spritesets[feature].find(set)->second.num_sprites;
204 template <VehicleType T>
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
219 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
221 inline byte ReadByte()
223 if (data < end)
return *(data)++;
229 uint16 val = ReadByte();
230 return val | (ReadByte() << 8);
233 uint16 ReadExtendedByte()
235 uint16 val = ReadByte();
236 return val == 0xFF ? ReadWord() : val;
241 uint32 val = ReadWord();
242 return val | (ReadWord() << 16);
245 uint32 ReadVarSize(
byte size)
248 case 1:
return ReadByte();
249 case 2:
return ReadWord();
250 case 4:
return ReadDWord();
257 const char *ReadString()
259 char *
string =
reinterpret_cast<char *
>(data);
260 size_t string_length =
ttd_strnlen(
string, Remaining());
262 if (string_length == Remaining()) {
264 string[string_length - 1] =
'\0';
265 grfmsg(7,
"String was not terminated with a zero byte.");
275 inline size_t Remaining()
const
280 inline bool HasData(
size_t count = 1)
const
282 return data + count <= end;
290 inline void Skip(
size_t len)
299 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
312 uint16 cargo_allowed;
313 uint16 cargo_disallowed;
314 RailTypeLabel railtypelabel;
331 }
else if (this->refittability ==
UNSET) {
332 this->refittability =
EMPTY;
352 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
356 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
361 return this->grfid == other.grfid && this->nfoline == other.nfoline;
365 static std::map<GRFLocation, SpriteID> _grm_sprites;
366 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
367 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
379 void CDECL
grfmsg(
int severity,
const char *str, ...)
399 if (file->grfid == grfid)
return file;
412 if (strcmp(file->filename, filename) == 0)
return file;
438 if (config !=
nullptr) {
449 if (message != STR_NULL) {
450 delete config->error;
451 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
455 return config->error;
466 typedef std::vector<StringIDMapping> StringIDMappingVector;
467 static StringIDMappingVector _string_to_grf_mapping;
476 *target = STR_UNDEFINED;
477 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
490 static const StringID units_volume[] = {
491 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 static_assert(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
531 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535 #undef TEXTID_TO_STRINGID
537 if (str == STR_NULL)
return STR_EMPTY;
539 DEBUG(grf, 0,
"Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
578 static std::map<uint32, uint32> _grf_id_overrides;
587 _grf_id_overrides[source_grfid] = target_grfid;
588 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
603 uint32 scope_grfid = INVALID_GRFID;
606 scope_grfid = file->grfid;
607 uint32
override = _grf_id_overrides[file->grfid];
609 scope_grfid =
override;
611 if (grf_match ==
nullptr) {
612 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
619 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
628 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
634 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
638 if (!static_access) {
640 eid->
grfid = scope_grfid;
646 if (static_access)
return nullptr;
649 grfmsg(0,
"Can't allocate any more engines");
660 assert(_engine_mngr.size() == e->
index);
661 _engine_mngr.push_back({
674 memset(
_gted + engine_pool_size, 0, len);
680 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
697 uint32 scope_grfid = INVALID_GRFID;
699 scope_grfid = file->grfid;
700 uint32
override = _grf_id_overrides[file->grfid];
701 if (
override != 0) scope_grfid =
override;
704 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
744 grf_sprite->
sprite = buf->ReadWord();
745 grf_sprite->
pal = buf->ReadWord();
750 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
754 uint index =
GB(grf_sprite->
sprite, 0, 14);
756 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757 grf_sprite->
sprite = SPR_IMG_QUERY;
758 grf_sprite->
pal = PAL_NONE;
761 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
766 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
773 uint index =
GB(grf_sprite->
pal, 0, 14);
775 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776 grf_sprite->
pal = PAL_NONE;
779 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
784 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
814 regs.delta.
parent[0] = buf->ReadByte();
815 regs.delta.
parent[1] = buf->ReadByte();
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
855 bool has_flags =
HasBit(num_building_sprites, 6);
856 ClrBit(num_building_sprites, 6);
859 dts->
Allocate(num_building_sprites);
861 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
862 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
863 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
871 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
879 for (uint i = 0; i < num_building_sprites; i++) {
882 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
885 if (flags & ~valid_flags) {
886 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
891 seq->
delta_x = buf->ReadByte();
892 seq->delta_y = buf->ReadByte();
894 if (!no_z_position) seq->
delta_z = buf->ReadByte();
897 seq->size_x = buf->ReadByte();
898 seq->size_y = buf->ReadByte();
899 seq->size_z = buf->ReadByte();
907 bool is_consistent =
true;
909 for (uint i = 0; i < num_building_sprites + 1; i++) {
910 if (max_sprite_offset[i] > 0) {
914 is_consistent =
false;
918 if (max_palette_offset[i] > 0) {
922 is_consistent =
false;
931 if (!is_consistent || dts->registers !=
nullptr) {
935 for (uint i = 0; i < num_building_sprites + 1; i++) {
950 CargoTypes result = 0;
969 if (base_pointer == 0) {
970 *index = INVALID_PRICE;
974 static const uint32 start = 0x4B34;
975 static const uint32 size = 6;
977 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
982 *index = (
Price)((base_pointer - start) / size);
1011 ei->decay_speed = buf->ReadByte();
1028 ei->load_amount = buf->ReadByte();
1050 for (
int i = 0; i < numinfo; i++) {
1059 uint8 tracktype = buf->ReadByte();
1061 if (tracktype < _cur.grffile->railtype_list.size()) {
1066 switch (tracktype) {
1067 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1068 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1069 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1071 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1084 uint16 speed = buf->ReadWord();
1085 if (speed == 0xFFFF) speed = 0;
1092 rvi->
power = buf->ReadWord();
1095 if (rvi->
power != 0) {
1113 uint8 spriteid = buf->ReadByte();
1114 uint8 orig_spriteid = spriteid;
1118 if (spriteid < 0xFD) spriteid >>= 1;
1120 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121 rvi->image_index = spriteid;
1123 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124 rvi->image_index = 0;
1130 uint8 dual = buf->ReadByte();
1135 rvi->railveh_type = rvi->
power == 0 ?
1147 uint8 ctype = buf->ReadByte();
1149 if (ctype == 0xFF) {
1152 }
else if (_cur.
grffile->grf_version >= 8) {
1157 ei->cargo_type = ctype;
1160 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1166 SB(rvi->
weight, 0, 8, buf->ReadByte());
1174 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1186 uint8 traction = buf->ReadByte();
1189 if (traction <= 0x07) {
1191 }
else if (traction <= 0x27) {
1193 }
else if (traction <= 0x31) {
1195 }
else if (traction <= 0x37) {
1197 }
else if (traction <= 0x41) {
1223 ei->refit_cost = buf->ReadByte();
1227 uint32 mask = buf->ReadDWord();
1265 byte weight = buf->ReadByte();
1268 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1290 _gted[e->
index].cargo_allowed = buf->ReadWord();
1296 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1310 uint8 count = buf->ReadByte();
1344 for (
int i = 0; i < numinfo; i++) {
1355 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1363 rvi->running_cost = buf->ReadByte();
1371 uint8 spriteid = buf->ReadByte();
1372 uint8 orig_spriteid = spriteid;
1375 if (spriteid == 0xFF) spriteid = 0xFD;
1377 if (spriteid < 0xFD) spriteid >>= 1;
1379 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1380 rvi->image_index = spriteid;
1382 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1383 rvi->image_index = 0;
1389 rvi->capacity = buf->ReadByte();
1394 uint8 ctype = buf->ReadByte();
1396 if (ctype == 0xFF) {
1399 }
else if (_cur.
grffile->grf_version >= 8) {
1404 ei->cargo_type = ctype;
1407 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1413 rvi->cost_factor = buf->ReadByte();
1421 rvi->
power = buf->ReadByte();
1425 rvi->
weight = buf->ReadByte();
1433 uint32 mask = buf->ReadDWord();
1453 ei->refit_cost = buf->ReadByte();
1466 _gted[e->
index].cargo_allowed = buf->ReadWord();
1472 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1504 uint8 count = buf->ReadByte();
1538 for (
int i = 0; i < numinfo; i++) {
1547 uint8 spriteid = buf->ReadByte();
1548 uint8 orig_spriteid = spriteid;
1551 if (spriteid == 0xFF) spriteid = 0xFD;
1553 if (spriteid < 0xFD) spriteid >>= 1;
1555 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1556 svi->image_index = spriteid;
1558 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1559 svi->image_index = 0;
1569 svi->cost_factor = buf->ReadByte();
1578 uint8 ctype = buf->ReadByte();
1580 if (ctype == 0xFF) {
1583 }
else if (_cur.
grffile->grf_version >= 8) {
1588 ei->cargo_type = ctype;
1591 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1597 svi->capacity = buf->ReadWord();
1601 svi->running_cost = buf->ReadByte();
1609 uint32 mask = buf->ReadDWord();
1621 ei->refit_cost = buf->ReadByte();
1642 _gted[e->
index].cargo_allowed = buf->ReadWord();
1648 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1676 uint8 count = buf->ReadByte();
1710 for (
int i = 0; i < numinfo; i++) {
1719 uint8 spriteid = buf->ReadByte();
1720 uint8 orig_spriteid = spriteid;
1723 if (spriteid == 0xFF) spriteid = 0xFD;
1725 if (spriteid < 0xFD) spriteid >>= 1;
1727 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1728 avi->image_index = spriteid;
1730 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1731 avi->image_index = 0;
1737 if (buf->ReadByte() == 0) {
1745 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1749 avi->cost_factor = buf->ReadByte();
1753 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1757 avi->acceleration = buf->ReadByte();
1761 avi->running_cost = buf->ReadByte();
1777 uint32 mask = buf->ReadDWord();
1789 ei->refit_cost = buf->ReadByte();
1802 _gted[e->
index].cargo_allowed = buf->ReadWord();
1808 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1826 uint8 count = buf->ReadByte();
1872 for (
int i = 0; i < numinfo; i++) {
1876 if (statspec ==
nullptr && prop != 0x08) {
1877 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1886 if (*spec ==
nullptr) *spec = CallocT<StationSpec>(1);
1889 uint32 classid = buf->ReadDWord();
1890 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1895 statspec->
tiles = buf->ReadExtendedByte();
1899 for (uint t = 0; t < statspec->
tiles; t++) {
1903 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1906 dts->
Clone(&_station_display_datas_rail[t % 8]);
1914 static std::vector<DrawTileSeqStruct> tmp_layout;
1921 dtss.
delta_x = buf->ReadByte();
1923 dtss.delta_y = buf->ReadByte();
1924 dtss.
delta_z = buf->ReadByte();
1925 dtss.size_x = buf->ReadByte();
1926 dtss.size_y = buf->ReadByte();
1927 dtss.size_z = buf->ReadByte();
1933 dts->
Clone(tmp_layout.data());
1938 byte srcid = buf->ReadByte();
1941 if (srcstatspec ==
nullptr) {
1942 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1950 for (uint t = 0; t < statspec->
tiles; t++) {
1969 statspec->copied_layouts =
false;
1971 while (buf->HasData()) {
1972 byte length = buf->ReadByte();
1973 byte number = buf->ReadByte();
1974 StationLayout layout;
1977 if (length == 0 || number == 0)
break;
1979 if (length > statspec->lengths) {
1980 byte diff_length = length - statspec->lengths;
1981 statspec->platforms =
ReallocT(statspec->platforms, length);
1982 memset(statspec->platforms + statspec->lengths, 0, diff_length);
1984 statspec->layouts =
ReallocT(statspec->layouts, length);
1985 memset(statspec->layouts + statspec->lengths, 0, diff_length *
sizeof(*statspec->layouts));
1987 statspec->lengths = length;
1991 if (number > statspec->platforms[l]) {
1992 statspec->layouts[l] =
ReallocT(statspec->layouts[l], number);
1994 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1995 (number - statspec->platforms[l]) *
sizeof(**statspec->layouts));
1997 statspec->platforms[l] = number;
2001 layout = MallocT<byte>(length * number);
2003 for (l = 0; l < length; l++) {
2004 for (p = 0; p < number; p++) {
2005 layout[l * number + p] = buf->ReadByte();
2015 free(statspec->layouts[l][p]);
2016 statspec->layouts[l][p] = layout;
2021 byte srcid = buf->ReadByte();
2024 if (srcstatspec ==
nullptr) {
2025 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2029 statspec->lengths = srcstatspec->lengths;
2030 statspec->platforms = srcstatspec->platforms;
2031 statspec->layouts = srcstatspec->layouts;
2032 statspec->copied_layouts =
true;
2041 statspec->
pylons = buf->ReadByte();
2045 if (_cur.
grffile->grf_version >= 7) {
2053 statspec->
flags = buf->ReadByte();
2057 statspec->
wires = buf->ReadByte();
2061 statspec->
blocked = buf->ReadByte();
2065 statspec->animation.
frames = buf->ReadByte();
2066 statspec->animation.
status = buf->ReadByte();
2070 statspec->animation.
speed = buf->ReadByte();
2074 statspec->animation.
triggers = buf->ReadWord();
2078 statspec->
tiles = buf->ReadExtendedByte();
2082 for (uint t = 0; t < statspec->
tiles; t++) {
2084 uint num_building_sprites = buf->ReadByte();
2111 if (
id + numinfo > CF_END) {
2112 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2116 for (
int i = 0; i < numinfo; i++) {
2125 cp->
flags = buf->ReadByte();
2150 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2154 for (
int i = 0; i < numinfo; i++) {
2160 byte year = buf->ReadByte();
2175 bridge->
price = buf->ReadByte();
2179 bridge->
speed = buf->ReadWord();
2183 byte tableid = buf->ReadByte();
2184 byte numtables = buf->ReadByte();
2191 for (; numtables-- != 0; tableid++) {
2193 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2194 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2199 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2202 for (
byte sprite = 0; sprite < 32; sprite++) {
2216 bridge->
flags = buf->ReadByte();
2225 if (newone != STR_UNDEFINED) bridge->
material = newone;
2232 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2237 bridge->
price = buf->ReadWord();
2294 for (uint j = 0; j < 4; j++) buf->ReadByte();
2298 byte count = buf->ReadByte();
2299 for (
byte j = 0; j < count; j++) buf->ReadByte();
2304 buf->Skip(buf->ReadByte() * 2);
2327 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2332 if (_cur.
grffile->housespec ==
nullptr) {
2336 for (
int i = 0; i < numinfo; i++) {
2339 if (prop != 0x08 && housespec ==
nullptr) {
2342 if (cir > ret) ret = cir;
2349 byte subs_id = buf->ReadByte();
2351 if (subs_id == 0xFF) {
2354 HouseSpec::Get(hid + i)->
enabled =
false;
2358 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2363 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2367 MemCpyT(housespec, HouseSpec::Get(subs_id));
2371 housespec->
grf_prop.subst_id = subs_id;
2393 uint16 years = buf->ReadWord();
2413 int8 goods = buf->ReadByte();
2449 byte override = buf->ReadByte();
2453 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2457 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2466 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2488 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2496 uint32 cargotypes = buf->ReadDWord();
2499 if (cargotypes == 0xFFFFFFFF)
break;
2501 for (uint j = 0; j < 3; j++) {
2503 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2521 byte count = buf->ReadByte();
2522 for (
byte j = 0; j < count; j++) {
2530 housespec->
min_year = buf->ReadWord();
2534 housespec->
max_year = buf->ReadWord();
2538 uint count = buf->ReadByte();
2541 error->param_value[1] = prop;
2590 template <
typename T>
2594 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2598 translation_table.clear();
2599 for (
int i = 0; i < numinfo; i++) {
2600 uint32 item = buf->ReadDWord();
2601 translation_table.push_back(
BSWAP32(item));
2637 for (
int i = 0; i < numinfo; i++) {
2640 int factor = buf->ReadByte();
2641 uint price = gvid + i;
2643 if (price < PR_END) {
2646 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2655 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2663 uint32 rate = buf->ReadDWord();
2671 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2678 uint16 options = buf->ReadWord();
2687 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2694 uint32 tempfix = buf->ReadDWord();
2700 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2707 uint32 tempfix = buf->ReadDWord();
2713 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2720 Year year_euro = buf->ReadWord();
2725 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2732 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2734 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2740 table[i][j] = buf->ReadByte();
2741 if (_cur.
grffile->grf_version >= 8) {
2744 if (table[i][j] >= 128) {
2766 uint curidx = gvid + i;
2768 if (lang ==
nullptr) {
2769 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2774 while (buf->ReadByte() != 0) {
2784 uint plural_form = buf->ReadByte();
2785 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2786 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2793 byte newgrf_id = buf->ReadByte();
2794 while (newgrf_id != 0) {
2795 const char *name = buf->ReadString();
2810 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2817 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2822 newgrf_id = buf->ReadByte();
2858 for (
int i = 0; i < numinfo; i++) {
2882 uint32 s = buf->ReadDWord();
2883 uint32 t = buf->ReadDWord();
2890 while (buf->ReadByte() != 0) {
2918 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2922 for (
int i = 0; i < numinfo; i++) {
2927 cs->
bitnum = buf->ReadByte();
2965 cs->
sprite = buf->ReadWord();
2969 cs->
weight = buf->ReadByte();
2973 cs->transit_days[0] = buf->ReadByte();
2977 cs->transit_days[1] = buf->ReadByte();
2981 cs->initial_payment = buf->ReadDWord();
2985 cs->rating_colour = buf->ReadByte();
2989 cs->legend_colour = buf->ReadByte();
2997 cs->
classes = buf->ReadWord();
3001 cs->
label = buf->ReadDWord();
3006 uint8 substitute_type = buf->ReadByte();
3008 switch (substitute_type) {
3015 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3031 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3056 if (_cur.
grffile->sound_offset == 0) {
3057 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3062 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3066 for (
int i = 0; i < numinfo; i++) {
3071 sound->volume = buf->ReadByte();
3075 sound->priority = buf->ReadByte();
3079 SoundID orig_sound = buf->ReadByte();
3084 SoundEntry *old_sound = GetSound(orig_sound);
3087 *old_sound = *sound;
3129 buf->Skip(buf->ReadByte() * 2);
3157 if (_cur.
grffile->indtspec ==
nullptr) {
3161 for (
int i = 0; i < numinfo; i++) {
3164 if (prop != 0x08 && tsp ==
nullptr) {
3166 if (cir > ret) ret = cir;
3173 byte subs_id = buf->ReadByte();
3177 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3182 if (*tilespec ==
nullptr) {
3183 *tilespec = CallocT<IndustryTileSpec>(1);
3186 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3204 byte ovrid = buf->ReadByte();
3208 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3212 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3219 uint16 acctp = buf->ReadWord();
3251 byte num_cargoes = buf->ReadByte();
3254 error->param_value[1] = prop;
3258 if (i < num_cargoes) {
3325 byte num_table = buf->ReadByte();
3326 for (
byte j = 0; j < num_table; j++) {
3327 for (uint k = 0;; k++) {
3328 byte x = buf->ReadByte();
3329 if (x == 0xFE && k == 0) {
3335 byte y = buf->ReadByte();
3336 if (x == 0 && y == 0x80)
break;
3338 byte gfx = buf->ReadByte();
3339 if (gfx == 0xFE) buf->ReadWord();
3346 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3353 buf->Skip(buf->ReadByte());
3357 int num_inputs = buf->ReadByte();
3358 int num_outputs = buf->ReadByte();
3359 buf->Skip(num_inputs * num_outputs * 2);
3377 const size_t size = layout.size();
3378 for (
size_t i = 0; i < size - 1; i++) {
3379 for (
size_t j = i + 1; j < size; j++) {
3380 if (layout[i].ti.x == layout[j].ti.x &&
3381 layout[i].ti.y == layout[j].ti.y) {
3407 if (_cur.
grffile->industryspec ==
nullptr) {
3411 for (
int i = 0; i < numinfo; i++) {
3414 if (prop != 0x08 && indsp ==
nullptr) {
3416 if (cir > ret) ret = cir;
3423 byte subs_id = buf->ReadByte();
3425 if (subs_id == 0xFF) {
3428 _industry_specs[indid + i].
enabled =
false;
3432 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3439 if (*indspec ==
nullptr) {
3443 *indsp = _origin_industry_specs[subs_id];
3446 indsp->
grf_prop.subst_id = subs_id;
3456 byte ovrid = buf->ReadByte();
3460 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3464 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3469 byte new_num_layouts = buf->ReadByte();
3470 uint32 definition_size = buf->ReadDWord();
3471 uint32 bytes_read = 0;
3472 std::vector<IndustryTileLayout> new_layouts;
3475 for (
byte j = 0; j < new_num_layouts; j++) {
3478 for (uint k = 0;; k++) {
3479 if (bytes_read >= definition_size) {
3480 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3482 definition_size = UINT32_MAX;
3488 it.ti.
x = buf->ReadByte();
3491 if (it.ti.
x == 0xFE && k == 0) {
3493 IndustryType type = buf->ReadByte();
3494 byte laynbr = buf->ReadByte();
3497 if (type >=
lengthof(_origin_industry_specs)) {
3498 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3502 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3503 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3507 layout = _origin_industry_specs[type].layouts[laynbr];
3511 it.ti.
y = buf->ReadByte();
3514 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3520 it.gfx = buf->ReadByte();
3523 if (it.gfx == 0xFE) {
3525 int local_tile_id = buf->ReadWord();
3529 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3532 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3537 }
else if (it.gfx == 0xFF) {
3538 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3539 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3548 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3554 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3558 new_layouts.push_back(layout);
3588 for (
byte j = 0; j < 2; j++) {
3594 for (
byte j = 0; j < 3; j++) {
3602 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3615 sounds[j] = buf->ReadByte();
3631 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3657 uint32 multiples = buf->ReadDWord();
3673 byte aflag = buf->ReadByte();
3683 uint16 str = buf->ReadWord();
3693 byte num_cargoes = buf->ReadByte();
3694 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3696 error->param_value[1] = prop;
3699 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3700 if (i < num_cargoes) {
3702 indsp->produced_cargo[i] = cargo;
3711 byte num_cargoes = buf->ReadByte();
3714 error->param_value[1] = prop;
3718 if (i < num_cargoes) {
3729 byte num_cargoes = buf->ReadByte();
3730 if (num_cargoes >
lengthof(indsp->production_rate)) {
3732 error->param_value[1] = prop;
3735 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3736 if (i < num_cargoes) {
3737 indsp->production_rate[i] = buf->ReadByte();
3739 indsp->production_rate[i] = 0;
3746 byte num_inputs = buf->ReadByte();
3747 byte num_outputs = buf->ReadByte();
3750 error->param_value[1] = prop;
3754 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3756 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3780 for (
int i = 0; i < as->
num_table; i++) {
3785 }
while ((++it)->ti.x != -0x80);
3786 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3789 as->
table = table_list;
3811 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3816 if (_cur.
grffile->airportspec ==
nullptr) {
3820 for (
int i = 0; i < numinfo; i++) {
3823 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3824 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3830 byte subs_id = buf->ReadByte();
3832 if (subs_id == 0xFF) {
3839 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3847 if (*spec ==
nullptr) {
3848 *spec = MallocT<AirportSpec>(1);
3857 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3868 uint32 defsize = buf->ReadDWord();
3874 for (
byte j = 0; j < as->
num_table; j++) {
3876 for (
int k = 0;; k++) {
3877 att[k].
ti.
x = buf->ReadByte();
3878 att[k].
ti.
y = buf->ReadByte();
3880 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3883 att[k].
ti.
x = -0x80;
3892 att[k].
gfx = buf->ReadByte();
3894 if (att[k].gfx == 0xFE) {
3896 int local_tile_id = buf->ReadWord();
3899 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3902 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3905 att[k].
gfx = tempid;
3907 }
else if (att[k].gfx == 0xFF) {
3908 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3909 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3920 tile_table[j] = CallocT<AirportTileTable>(size);
3921 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3924 as->
table = tile_table;
3927 for (
int i = 0; i < as->
num_table; i++) {
3928 free(tile_table[i]);
4034 if (_cur.
grffile->objectspec ==
nullptr) {
4038 for (
int i = 0; i < numinfo; i++) {
4041 if (prop != 0x08 && spec ==
nullptr) {
4044 if (cir > ret) ret = cir;
4053 if (*ospec ==
nullptr) {
4054 *ospec = CallocT<ObjectSpec>(1);
4055 (*ospec)->views = 1;
4059 uint32 classid = buf->ReadDWord();
4060 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4061 (*ospec)->enabled =
true;
4076 spec->
climate = buf->ReadByte();
4080 spec->
size = buf->ReadByte();
4123 spec->
height = buf->ReadByte();
4127 spec->
views = buf->ReadByte();
4129 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4162 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4166 for (
int i = 0; i < numinfo; i++) {
4179 uint16 str = buf->ReadWord();
4181 if (_cur.
grffile->grf_version < 8) {
4211 int n = buf->ReadByte();
4212 for (
int j = 0; j != n; j++) {
4213 RailTypeLabel label = buf->ReadDWord();
4273 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4292 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4296 for (
int i = 0; i < numinfo; i++) {
4300 RailTypeLabel rtl = buf->ReadDWord();
4309 _cur.
grffile->railtype_map[
id + i] = rt;
4327 int n = buf->ReadByte();
4328 for (
int j = 0; j != n; j++) {
4333 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4340 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4381 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4385 for (
int i = 0; i < numinfo; i++) {
4398 uint16 str = buf->ReadWord();
4425 int n = buf->ReadByte();
4426 for (
int j = 0; j != n; j++) {
4427 RoadTypeLabel label = buf->ReadDWord();
4474 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4505 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4509 for (
int i = 0; i < numinfo; i++) {
4512 RoadTypeLabel rtl = buf->ReadDWord();
4519 }
else if (GetRoadTramType(rt) != rtt) {
4520 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4524 type_map[
id + i] = rt;
4541 int n = buf->ReadByte();
4542 for (
int j = 0; j != n; j++) {
4547 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4553 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4577 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4582 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4595 if (_cur.
grffile->airtspec ==
nullptr) {
4599 for (
int i = 0; i < numinfo; i++) {
4602 if (prop != 0x08 && tsp ==
nullptr) {
4603 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4610 byte subs_id = buf->ReadByte();
4614 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4619 if (*tilespec ==
nullptr) {
4620 *tilespec = CallocT<AirportTileSpec>(1);
4637 byte override = buf->ReadByte();
4641 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4645 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4675 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4678 default: NOT_REACHED();
4688 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4692 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4705 static void FeatureChangeInfo(
ByteReader *buf)
4718 static const VCI_Handler handler[] = {
4736 AirportTilesChangeInfo,
4741 uint8 feature = buf->ReadByte();
4742 uint8 numprops = buf->ReadByte();
4743 uint numinfo = buf->ReadByte();
4744 uint engine = buf->ReadExtendedByte();
4746 if (feature >= GSF_END) {
4747 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4751 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4752 feature, numprops, engine, numinfo);
4754 if (feature >=
lengthof(handler) || handler[feature] ==
nullptr) {
4755 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4762 while (numprops-- && buf->HasData()) {
4763 uint8 prop = buf->ReadByte();
4766 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4773 uint8 feature = buf->ReadByte();
4774 uint8 numprops = buf->ReadByte();
4775 uint numinfo = buf->ReadByte();
4776 buf->ReadExtendedByte();
4778 if (feature == GSF_BRIDGES && numprops == 1) {
4779 uint8 prop = buf->ReadByte();
4782 if (prop == 0x0D)
return;
4783 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4784 uint8 prop = buf->ReadByte();
4787 bool is_safe =
true;
4788 for (uint i = 0; i < numinfo; i++) {
4789 uint32 s = buf->ReadDWord();
4797 if (is_safe)
return;
4808 static void ReserveChangeInfo(
ByteReader *buf)
4810 uint8 feature = buf->ReadByte();
4812 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4814 uint8 numprops = buf->ReadByte();
4815 uint8 numinfo = buf->ReadByte();
4816 uint8 index = buf->ReadExtendedByte();
4818 while (numprops-- && buf->HasData()) {
4819 uint8 prop = buf->ReadByte();
4823 default: NOT_REACHED();
4829 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4833 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4837 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4841 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4845 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4866 uint8 feature = buf->ReadByte();
4867 uint16 num_sets = buf->ReadByte();
4868 uint16 first_set = 0;
4870 if (num_sets == 0 && buf->HasData(3)) {
4873 first_set = buf->ReadExtendedByte();
4874 num_sets = buf->ReadExtendedByte();
4876 uint16 num_ents = buf->ReadExtendedByte();
4878 if (feature >= GSF_END) {
4880 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4886 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4887 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4890 for (
int i = 0; i < num_sets * num_ents; i++) {
4900 uint16 num_sets = buf->ReadByte();
4902 if (num_sets == 0 && buf->HasData(3)) {
4905 buf->ReadExtendedByte();
4906 num_sets = buf->ReadExtendedByte();
4908 uint16 num_ents = buf->ReadExtendedByte();
4917 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4919 if (
HasBit(groupid, 15)) {
4924 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4925 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4929 return _cur.spritegroups[groupid];
4942 if (
HasBit(spriteid, 15)) {
4948 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4953 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4956 assert(spriteset_start + num_sprites <= _cur.
spriteid);
4977 uint8 feature = buf->ReadByte();
4978 if (feature >= GSF_END) {
4979 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4983 uint8 setid = buf->ReadByte();
4984 uint8 type = buf->ReadByte();
5008 switch (
GB(type, 2, 2)) {
5009 default: NOT_REACHED();
5010 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5011 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5012 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5015 static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5025 adjust.variable = buf->ReadByte();
5026 if (adjust.variable == 0x7E) {
5028 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5033 varadjust = buf->ReadByte();
5034 adjust.shift_num =
GB(varadjust, 0, 5);
5035 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5036 adjust.and_mask = buf->ReadVarSize(varsize);
5038 if (adjust.type != DSGA_TYPE_NONE) {
5039 adjust.add_val = buf->ReadVarSize(varsize);
5040 adjust.divmod_val = buf->ReadVarSize(varsize);
5043 adjust.divmod_val = 0;
5047 }
while (
HasBit(varadjust, 5));
5049 group->num_adjusts = (uint)adjusts.size();
5050 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5051 MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
5053 std::vector<DeterministicSpriteGroupRange> ranges;
5054 ranges.resize(buf->ReadByte());
5055 for (uint i = 0; i < ranges.size(); i++) {
5056 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5057 ranges[i].low = buf->ReadVarSize(varsize);
5058 ranges[i].high = buf->ReadVarSize(varsize);
5061 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5062 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5064 group->calculated_result = ranges.size() == 0;
5067 std::vector<uint32> bounds;
5068 for (uint i = 0; i < ranges.size(); i++) {
5069 bounds.push_back(ranges[i].low);
5070 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5072 std::sort(bounds.begin(), bounds.end());
5073 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5075 std::vector<const SpriteGroup *> target;
5076 for (uint j = 0; j < bounds.size(); ++j) {
5077 uint32 v = bounds[j];
5079 for (uint i = 0; i < ranges.size(); i++) {
5080 if (ranges[i].low <= v && v <= ranges[i].high) {
5081 t = ranges[i].group;
5085 target.push_back(t);
5087 assert(target.size() == bounds.size());
5089 std::vector<DeterministicSpriteGroupRange> optimised;
5090 for (uint j = 0; j < bounds.size(); ) {
5091 if (target[j] != group->default_group) {
5093 r.group = target[j];
5095 while (j < bounds.size() && target[j] == r.group) {
5098 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5099 optimised.push_back(r);
5105 group->num_ranges = (uint)optimised.size();
5106 if (group->num_ranges > 0) {
5107 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5108 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5126 group->count = buf->ReadByte();
5129 uint8 triggers = buf->ReadByte();
5130 group->triggers =
GB(triggers, 0, 7);
5131 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5136 for (uint i = 0; i < group->
num_groups; i++) {
5137 group->
groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5148 case GSF_ROADVEHICLES:
5159 byte num_loaded = type;
5160 byte num_loading = buf->ReadByte();
5163 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5174 if (num_loaded > 0) group->
loaded = CallocT<const SpriteGroup*>(num_loaded);
5175 if (num_loading > 0) group->
loading = CallocT<const SpriteGroup*>(num_loading);
5177 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5178 setid, num_loaded, num_loading);
5180 for (uint i = 0; i < num_loaded; i++) {
5181 uint16 spriteid = buf->ReadWord();
5183 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5186 for (uint i = 0; i < num_loading; i++) {
5187 uint16 spriteid = buf->ReadWord();
5189 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5196 case GSF_AIRPORTTILES:
5198 case GSF_INDUSTRYTILES: {
5199 byte num_building_sprites = std::max((uint8)1, type);
5207 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5211 case GSF_INDUSTRIES: {
5213 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5224 for (uint i = 0; i < 3; i++) {
5228 for (uint i = 0; i < 2; i++) {
5231 group->again = buf->ReadByte();
5232 }
else if (type == 1) {
5234 for (uint i = 0; i < 3; i++) {
5238 for (uint i = 0; i < 2; i++) {
5241 group->again = buf->ReadByte();
5242 }
else if (type == 2) {
5246 error->data =
"too many inputs (max 16)";
5249 for (uint i = 0; i < group->
num_input; i++) {
5250 byte rawcargo = buf->ReadByte();
5259 error->data =
"duplicate input cargo";
5268 error->data =
"too many outputs (max 16)";
5271 for (uint i = 0; i < group->
num_output; i++) {
5272 byte rawcargo = buf->ReadByte();
5279 error->data =
"duplicate output cargo";
5285 group->again = buf->ReadByte();
5293 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5298 _cur.spritegroups[setid] = act_group;
5301 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5303 if (feature == GSF_OBJECTS) {
5308 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5313 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5314 if (ctype == 0xFF)
return CT_PURCHASE;
5319 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5324 FOR_ALL_CARGOSPECS(cs) {
5325 if (cs->
bitnum == ctype) {
5326 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->
Index());
5331 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5337 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5344 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5350 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));
5354 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);
5359 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5361 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5362 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5369 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5372 static uint last_engines_count;
5373 bool wagover =
false;
5376 if (
HasBit(idcount, 7)) {
5379 idcount =
GB(idcount, 0, 7);
5381 if (last_engines_count == 0) {
5382 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5386 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5387 last_engines_count, idcount);
5389 if (last_engines_count != idcount) {
5390 last_engines =
ReallocT(last_engines, idcount);
5391 last_engines_count = idcount;
5396 for (uint i = 0; i < idcount; i++) {
5402 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5406 engines[i] = e->
index;
5407 if (!wagover) last_engines[i] = engines[i];
5410 uint8 cidcount = buf->ReadByte();
5411 for (uint c = 0; c < cidcount; c++) {
5412 uint8 ctype = buf->ReadByte();
5413 uint16 groupid = buf->ReadWord();
5414 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5416 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5418 ctype = TranslateCargo(feature, ctype);
5421 for (uint i = 0; i < idcount; i++) {
5424 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5427 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5429 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5434 uint16 groupid = buf->ReadWord();
5435 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5437 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5439 for (uint i = 0; i < idcount; i++) {
5443 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5445 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5452 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5455 for (uint i = 0; i < idcount; i++) {
5459 uint8 cidcount = buf->ReadByte();
5460 buf->Skip(cidcount * 3);
5462 uint16 groupid = buf->ReadWord();
5463 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5465 for (uint i = 0; i < idcount; i++) {
5469 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5479 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5481 uint8 *stations =
AllocaM(uint8, idcount);
5482 for (uint i = 0; i < idcount; i++) {
5483 stations[i] = buf->ReadByte();
5486 uint8 cidcount = buf->ReadByte();
5487 for (uint c = 0; c < cidcount; c++) {
5488 uint8 ctype = buf->ReadByte();
5489 uint16 groupid = buf->ReadWord();
5490 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5492 ctype = TranslateCargo(GSF_STATIONS, ctype);
5495 for (uint i = 0; i < idcount; i++) {
5498 if (statspec ==
nullptr) {
5499 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5507 uint16 groupid = buf->ReadWord();
5508 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5510 for (uint i = 0; i < idcount; i++) {
5513 if (statspec ==
nullptr) {
5514 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5519 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5526 StationClass::Assign(statspec);
5531 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5533 uint8 *houses =
AllocaM(uint8, idcount);
5534 for (uint i = 0; i < idcount; i++) {
5535 houses[i] = buf->ReadByte();
5539 uint8 cidcount = buf->ReadByte();
5540 buf->Skip(cidcount * 3);
5542 uint16 groupid = buf->ReadWord();
5543 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5545 if (_cur.
grffile->housespec ==
nullptr) {
5546 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5550 for (uint i = 0; i < idcount; i++) {
5553 if (hs ==
nullptr) {
5554 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5562 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5564 uint8 *industries =
AllocaM(uint8, idcount);
5565 for (uint i = 0; i < idcount; i++) {
5566 industries[i] = buf->ReadByte();
5570 uint8 cidcount = buf->ReadByte();
5571 buf->Skip(cidcount * 3);
5573 uint16 groupid = buf->ReadWord();
5574 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5576 if (_cur.
grffile->industryspec ==
nullptr) {
5577 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5581 for (uint i = 0; i < idcount; i++) {
5584 if (indsp ==
nullptr) {
5585 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5593 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5595 uint8 *indtiles =
AllocaM(uint8, idcount);
5596 for (uint i = 0; i < idcount; i++) {
5597 indtiles[i] = buf->ReadByte();
5601 uint8 cidcount = buf->ReadByte();
5602 buf->Skip(cidcount * 3);
5604 uint16 groupid = buf->ReadWord();
5605 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5607 if (_cur.
grffile->indtspec ==
nullptr) {
5608 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5612 for (uint i = 0; i < idcount; i++) {
5615 if (indtsp ==
nullptr) {
5616 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5624 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5627 for (uint i = 0; i < idcount; i++) {
5628 cargoes[i] = buf->ReadByte();
5632 uint8 cidcount = buf->ReadByte();
5633 buf->Skip(cidcount * 3);
5635 uint16 groupid = buf->ReadWord();
5636 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5638 for (uint i = 0; i < idcount; i++) {
5642 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5648 cs->group = _cur.spritegroups[groupid];
5652 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5654 if (_cur.
grffile->objectspec ==
nullptr) {
5655 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5659 uint8 *objects =
AllocaM(uint8, idcount);
5660 for (uint i = 0; i < idcount; i++) {
5661 objects[i] = buf->ReadByte();
5664 uint8 cidcount = buf->ReadByte();
5665 for (uint c = 0; c < cidcount; c++) {
5666 uint8 ctype = buf->ReadByte();
5667 uint16 groupid = buf->ReadWord();
5668 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5670 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5673 for (uint i = 0; i < idcount; i++) {
5676 if (spec ==
nullptr) {
5677 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5685 uint16 groupid = buf->ReadWord();
5686 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5688 for (uint i = 0; i < idcount; i++) {
5691 if (spec ==
nullptr) {
5692 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5697 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5707 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5709 uint8 *railtypes =
AllocaM(uint8, idcount);
5710 for (uint i = 0; i < idcount; i++) {
5711 uint8
id = buf->ReadByte();
5715 uint8 cidcount = buf->ReadByte();
5716 for (uint c = 0; c < cidcount; c++) {
5717 uint8 ctype = buf->ReadByte();
5718 uint16 groupid = buf->ReadWord();
5719 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5721 if (ctype >= RTSG_END)
continue;
5724 for (uint i = 0; i < idcount; i++) {
5729 rti->
group[ctype] = _cur.spritegroups[groupid];
5738 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5742 uint8 *roadtypes =
AllocaM(uint8, idcount);
5743 for (uint i = 0; i < idcount; i++) {
5744 uint8
id = buf->ReadByte();
5748 uint8 cidcount = buf->ReadByte();
5749 for (uint c = 0; c < cidcount; c++) {
5750 uint8 ctype = buf->ReadByte();
5751 uint16 groupid = buf->ReadWord();
5752 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5754 if (ctype >= ROTSG_END)
continue;
5757 for (uint i = 0; i < idcount; i++) {
5762 rti->
group[ctype] = _cur.spritegroups[groupid];
5771 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5773 uint8 *airports =
AllocaM(uint8, idcount);
5774 for (uint i = 0; i < idcount; i++) {
5775 airports[i] = buf->ReadByte();
5779 uint8 cidcount = buf->ReadByte();
5780 buf->Skip(cidcount * 3);
5782 uint16 groupid = buf->ReadWord();
5783 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5785 if (_cur.
grffile->airportspec ==
nullptr) {
5786 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5790 for (uint i = 0; i < idcount; i++) {
5793 if (as ==
nullptr) {
5794 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5802 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5804 uint8 *airptiles =
AllocaM(uint8, idcount);
5805 for (uint i = 0; i < idcount; i++) {
5806 airptiles[i] = buf->ReadByte();
5810 uint8 cidcount = buf->ReadByte();
5811 buf->Skip(cidcount * 3);
5813 uint16 groupid = buf->ReadWord();
5814 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5816 if (_cur.
grffile->airtspec ==
nullptr) {
5817 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5821 for (uint i = 0; i < idcount; i++) {
5824 if (airtsp ==
nullptr) {
5825 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5835 static void FeatureMapSpriteGroup(
ByteReader *buf)
5851 uint8 feature = buf->ReadByte();
5852 uint8 idcount = buf->ReadByte();
5854 if (feature >= GSF_END) {
5855 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5863 uint16 groupid = buf->ReadWord();
5864 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5866 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5875 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5879 case GSF_ROADVEHICLES:
5882 VehicleMapSpriteGroup(buf, feature, idcount);
5886 CanalMapSpriteGroup(buf, idcount);
5890 StationMapSpriteGroup(buf, idcount);
5894 TownHouseMapSpriteGroup(buf, idcount);
5897 case GSF_INDUSTRIES:
5898 IndustryMapSpriteGroup(buf, idcount);
5901 case GSF_INDUSTRYTILES:
5902 IndustrytileMapSpriteGroup(buf, idcount);
5906 CargoMapSpriteGroup(buf, idcount);
5910 AirportMapSpriteGroup(buf, idcount);
5914 ObjectMapSpriteGroup(buf, idcount);
5918 RailTypeMapSpriteGroup(buf, idcount);
5922 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5926 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5929 case GSF_AIRPORTTILES:
5930 AirportTileMapSpriteGroup(buf, idcount);
5934 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5958 bool new_scheme = _cur.
grffile->grf_version >= 7;
5960 uint8 feature = buf->ReadByte();
5961 if (feature >= GSF_END && feature != 0x48) {
5962 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5966 uint8 lang = buf->ReadByte();
5967 uint8 num = buf->ReadByte();
5968 bool generic =
HasBit(lang, 7);
5971 id = buf->ReadWord();
5972 }
else if (feature <= GSF_AIRCRAFT) {
5973 id = buf->ReadExtendedByte();
5975 id = buf->ReadByte();
5980 uint16 endid =
id + num;
5982 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5983 id, endid, feature, lang);
5985 for (;
id < endid && buf->HasData();
id++) {
5986 const char *name = buf->ReadString();
5987 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
5991 case GSF_ROADVEHICLES:
5996 if (e ==
nullptr)
break;
6010 switch (
GB(
id, 8, 8)) {
6012 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6013 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6021 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6022 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6029 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6030 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6037 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6038 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6045 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6064 if (offset >= max_sprites) {
6065 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6066 uint orig_num = num;
6071 if (offset + num > max_sprites) {
6072 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6073 uint orig_num = num;
6074 num = std::max(max_sprites - offset, 0);
6075 return orig_num - num;
6104 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6106 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6136 uint8 type = buf->ReadByte();
6137 uint16 num = buf->ReadExtendedByte();
6138 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6144 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6161 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6172 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6179 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);
6189 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);
6200 for (; num > 0; num--) {
6271 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6301 *value = _game_mode;
6335 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6344 *value = _openttd_newgrf_version;
6359 default:
return false;
6363 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6381 if (cond_val ==
nullptr) {
6385 uint32 index = *cond_val / 0x20;
6401 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6424 byte *preload_sprite =
nullptr;
6428 preload_sprite = MallocT<byte>(num);
6436 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6437 free(preload_sprite);
6442 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6443 if (it != _grf_line_to_action6_sprite_override.end()) {
6444 free(preload_sprite);
6445 preload_sprite = _grf_line_to_action6_sprite_override[location];
6447 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6460 param_num = buf->ReadByte();
6461 if (param_num == 0xFF)
break;
6465 param_size = buf->ReadByte();
6469 add_value =
HasBit(param_size, 7);
6470 param_size =
GB(param_size, 0, 7);
6473 offset = buf->ReadExtendedByte();
6477 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6478 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6482 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6485 for (i = 0; i < param_size && offset + i < num; i++) {
6486 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6489 if (i % 4 == 0) carry =
false;
6492 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6493 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6495 carry = new_value >= 256;
6497 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6529 uint32 cond_val = 0;
6533 uint8 param = buf->ReadByte();
6534 uint8 paramsize = buf->ReadByte();
6535 uint8 condtype = buf->ReadByte();
6542 switch (paramsize) {
6543 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6544 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6545 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6546 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6550 if (param < 0x80 && _cur.grffile->param_end <= param) {
6551 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6555 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6560 if (condtype >= 0x0B) {
6591 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6593 }
else if (param == 0x88) {
6603 if (condtype != 10 && c ==
nullptr) {
6604 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6631 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6635 uint32 param_val = GetParamVal(param, &cond_val);
6637 case 0x00: result = !!(param_val & (1 << cond_val));
6639 case 0x01: result = !(param_val & (1 << cond_val));
6641 case 0x02: result = (param_val & mask) == cond_val;
6643 case 0x03: result = (param_val & mask) != cond_val;
6645 case 0x04: result = (param_val & mask) < cond_val;
6647 case 0x05: result = (param_val & mask) > cond_val;
6649 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6654 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6658 uint8 numsprites = buf->ReadByte();
6666 if (label->label != numsprites)
continue;
6669 if (choice ==
nullptr) choice = label;
6671 if (label->nfo_line > _cur.
nfo_line) {
6677 if (choice !=
nullptr) {
6678 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6684 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6703 uint8 grf_version = buf->ReadByte();
6704 uint32 grfid = buf->ReadDWord();
6705 const char *name = buf->ReadString();
6709 if (grf_version < 2 || grf_version > 8) {
6711 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);
6719 if (buf->HasData()) {
6720 const char *info = buf->ReadString();
6738 uint8 version = buf->ReadByte();
6739 uint32 grfid = buf->ReadDWord();
6740 const char *name = buf->ReadString();
6743 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6747 if (_cur.
grffile->grfid != grfid) {
6748 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));
6752 _cur.
grffile->grf_version = version;
6770 uint8 num_sets = buf->ReadByte();
6772 for (uint i = 0; i < num_sets; i++) {
6773 uint8 num_sprites = buf->ReadByte();
6774 uint16 first_sprite = buf->ReadWord();
6776 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6777 i, num_sprites, first_sprite
6780 for (uint j = 0; j < num_sprites; j++) {
6781 int load_index = first_sprite + j;
6787 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6797 uint8 num_sets = buf->ReadByte();
6799 for (uint i = 0; i < num_sets; i++) {
6828 STR_NEWGRF_ERROR_VERSION_NUMBER,
6829 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6830 STR_NEWGRF_ERROR_UNSET_SWITCH,
6831 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6832 STR_NEWGRF_ERROR_LOAD_BEFORE,
6833 STR_NEWGRF_ERROR_LOAD_AFTER,
6834 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6838 STR_NEWGRF_ERROR_MSG_INFO,
6839 STR_NEWGRF_ERROR_MSG_WARNING,
6840 STR_NEWGRF_ERROR_MSG_ERROR,
6841 STR_NEWGRF_ERROR_MSG_FATAL
6844 byte severity = buf->ReadByte();
6845 byte lang = buf->ReadByte();
6846 byte message_id = buf->ReadByte();
6849 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6853 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6854 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6859 if (severity >=
lengthof(sevstr)) {
6860 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6862 }
else if (severity == 3) {
6872 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6873 grfmsg(7,
"GRFLoadError: Invalid message id.");
6877 if (buf->Remaining() <= 1) {
6878 grfmsg(7,
"GRFLoadError: No message data supplied.");
6887 if (message_id == 0xFF) {
6889 if (buf->HasData()) {
6890 const char *message = buf->ReadString();
6894 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6895 error->custom_message.clear();
6898 error->message = msgstr[message_id];
6901 if (buf->HasData()) {
6902 const char *data = buf->ReadString();
6906 grfmsg(7,
"GRFLoadError: No message data supplied.");
6907 error->data.clear();
6911 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6912 uint param_number = buf->ReadByte();
6926 if (!buf->HasData())
return;
6928 const char *text = buf->ReadString();
6929 grfmsg(2,
"GRFComment: %s", text);
6935 uint8 target = buf->ReadByte();
6938 if (target < 0x80 || target == 0x9E)
return;
6952 static uint32 GetPatchVariable(uint8 param)
6962 case 0x0F:
return 0;
6978 case 0x11:
return SPR_2CCMAP_BASE;
6995 byte max_edge = std::max(log_X, log_Y);
6997 if (log_X == log_Y) {
7000 if (max_edge == log_Y)
SetBit(map_bits, 1);
7003 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7004 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7013 return SPR_SLOPES_BASE;
7020 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7026 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7039 for (uint i = start; i < num_ids; i++) {
7043 if (op == 2 || op == 3)
break;
7048 if (size == count)
break;
7051 if (size == count) {
7053 if (op == 0 || op == 3) {
7054 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7055 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7061 if (op != 4 && op != 5) {
7063 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7068 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7098 uint8 target = buf->ReadByte();
7099 uint8 oper = buf->ReadByte();
7100 uint32 src1 = buf->ReadByte();
7101 uint32 src2 = buf->ReadByte();
7104 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7113 if (target < 0x80 && target < _cur.grffile->param_end) {
7114 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7118 oper =
GB(oper, 0, 7);
7122 if (
GB(data, 0, 8) == 0xFF) {
7123 if (data == 0x0000FFFF) {
7125 src1 = GetPatchVariable(src1);
7129 uint8 feature =
GB(data, 8, 8);
7130 uint16 count =
GB(data, 16, 16);
7132 if (_cur.
stage == GLS_RESERVE) {
7133 if (feature == 0x08) {
7137 if (_cur.
spriteid + count >= 16384) {
7138 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7144 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7151 }
else if (_cur.
stage == GLS_ACTIVATION) {
7180 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7188 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7199 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7216 }
else if (src1 == 0xFE) {
7228 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7229 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7251 res = (int32)src1 * (int32)src2;
7255 if ((int32)src2 < 0) {
7256 res = src1 >> -(int32)src2;
7258 res = src1 << (src2 & 0x1F);
7263 if ((int32)src2 < 0) {
7264 res = (int32)src1 >> -(int32)src2;
7266 res = (int32)src1 << (src2 & 0x1F);
7290 res = (int32)src1 / (int32)src2;
7306 res = (int32)src1 % (int32)src2;
7310 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7339 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7350 uint32 safe_bits = 0;
7351 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7360 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7364 if (target < 0x80) {
7365 _cur.
grffile->param[target] = res;
7369 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7383 uint8 num = buf->ReadByte();
7385 for (uint i = 0; i < num; i++) {
7386 uint32 grfid = buf->ReadDWord();
7408 uint8 num = buf->ReadByte();
7410 for (uint i = 0; i < num; i++) {
7411 uint32 grfid = buf->ReadDWord();
7415 if (file !=
nullptr && file != _cur.
grfconfig) {
7433 uint32 grfid = _cur.
grffile->grfid;
7437 byte id = buf->ReadByte();
7438 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7443 bool new_scheme = _cur.
grffile->grf_version >= 7;
7445 byte lang = buf->ReadByte();
7447 byte nb_gen = townname->nb_gen;
7451 const char *name = buf->ReadString();
7454 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7456 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7458 lang = buf->ReadByte();
7459 }
while (lang != 0);
7460 townname->id[nb_gen] = id;
7464 byte nb = buf->ReadByte();
7465 grfmsg(6,
"FeatureTownName: %u parts", nb);
7467 townname->nbparts[id] = nb;
7468 townname->partlist[id] = CallocT<NamePartList>(nb);
7470 for (
int i = 0; i < nb; i++) {
7471 byte nbtext = buf->ReadByte();
7472 townname->partlist[id][i].bitstart = buf->ReadByte();
7473 townname->partlist[id][i].bitcount = buf->ReadByte();
7474 townname->partlist[id][i].maxprob = 0;
7475 townname->partlist[id][i].partcount = nbtext;
7476 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7477 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);
7479 for (
int j = 0; j < nbtext; j++) {
7480 byte prob = buf->ReadByte();
7483 byte ref_id = buf->ReadByte();
7485 if (townname->nbparts[ref_id] == 0) {
7486 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7487 DelGRFTownName(grfid);
7492 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7493 townname->partlist[id][i].parts[j].data.
id = ref_id;
7495 const char *text = buf->ReadString();
7497 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7499 townname->partlist[id][i].parts[j].
prob = prob;
7500 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7502 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7514 byte nfo_label = buf->ReadByte();
7516 GRFLabel *label = MallocT<GRFLabel>(1);
7517 label->label = nfo_label;
7520 label->next =
nullptr;
7528 for (l = _cur.
grffile->
label; l->next !=
nullptr; l = l->next) {}
7532 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7546 if (file ==
nullptr || file->sound_offset == 0) {
7547 grfmsg(1,
"ImportGRFSound: Source file not available");
7551 if (sound_id >= file->num_sounds) {
7552 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7556 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7558 *sound = *GetSound(file->sound_offset + sound_id);
7561 sound->volume = 128;
7562 sound->priority = 0;
7573 sound->volume = 0x80;
7574 sound->priority = 0;
7576 if (offs != SIZE_MAX) {
7579 sound->file_offset = offs;
7591 uint16 num = buf->ReadWord();
7592 if (num == 0)
return;
7595 if (_cur.
grffile->sound_offset == 0) {
7596 _cur.
grffile->sound_offset = GetNumSounds();
7597 _cur.
grffile->num_sounds = num;
7600 sound = GetSound(_cur.
grffile->sound_offset);
7603 for (
int i = 0; i < num; i++) {
7608 bool invalid = i >= _cur.
grffile->num_sounds;
7618 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7620 }
else if (len != 4) {
7621 grfmsg(1,
"GRFSound: Invalid sprite section import");
7631 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7638 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7646 if (_cur.
stage == GLS_INIT) {
7648 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7657 if (_cur.
stage == GLS_ACTIVATION) {
7668 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7697 uint8 num_def = buf->ReadByte();
7699 for (uint i = 0; i < num_def; i++) {
7701 uint8 num_char = buf->ReadByte();
7702 uint16 base_char = buf->ReadWord();
7704 if (size >= FS_END) {
7705 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7708 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7710 for (uint c = 0; c < num_char; c++) {
7728 uint8 num_def = buf->ReadByte();
7730 for (uint i = 0; i < num_def; i++) {
7754 uint32 grfid = buf->ReadDWord();
7757 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7767 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE,
lastof(tmp));
7778 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7779 byte num_strings = buf->ReadByte();
7780 uint16 first_id = buf->ReadWord();
7782 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7783 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7787 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7788 const char *
string = buf->ReadString();
7791 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7795 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7824 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7836 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7839 char data = buf->ReadByte();
7847 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7862 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7865 char data = buf->ReadByte();
7871 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7884 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7897 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7902 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7933 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7940 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7950 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7952 }
else if (len != 8) {
7953 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
7956 uint32 min_value = buf->ReadDWord();
7957 uint32 max_value = buf->ReadDWord();
7958 if (min_value <= max_value) {
7962 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7971 if (len < 1 || len > 3) {
7972 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
7975 byte param_nr = buf->ReadByte();
7977 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7993 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8029 this->handler.data = handler;
8041 this->handler.text = handler;
8053 this->handler.call_handler =
true;
8054 this->handler.u.branch = handler;
8066 this->handler.call_handler =
false;
8067 this->handler.u.subtags =
subtags;
8096 byte type = buf->ReadByte();
8098 uint32
id = buf->ReadDWord();
8100 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8102 type = buf->ReadByte();
8106 byte langid = buf->ReadByte();
8107 const char *name_string = buf->ReadString();
8118 type = buf->ReadByte();
8143 byte type = buf->ReadByte();
8145 uint32
id = buf->ReadDWord();
8147 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8149 type = buf->ReadByte();
8162 type = buf->ReadByte();
8199 byte new_type = buf->ReadByte();
8200 while (new_type != 0) {
8203 new_type = buf->ReadByte();
8214 uint16 size = buf->ReadWord();
8238 while ((tag = &subtags[i++])->type != 0) {
8241 default: NOT_REACHED();
8244 byte langid = buf->ReadByte();
8245 return tag->handler.
text(langid, buf->ReadString());
8249 size_t len = buf->ReadWord();
8250 if (buf->Remaining() < len)
return false;
8251 return tag->handler.
data(len, buf);
8256 return tag->handler.u.branch(buf);
8262 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8274 byte type = buf->ReadByte();
8276 uint32
id = buf->ReadDWord();
8277 if (!
HandleNode(type,
id, buf, subtags))
return false;
8278 type = buf->ReadByte();
8400 if (stations ==
nullptr)
continue;
8402 if (stations[i] ==
nullptr)
continue;
8408 if (!statspec->copied_layouts) {
8409 for (uint l = 0; l < statspec->lengths; l++) {
8410 for (uint p = 0; p < statspec->platforms[l]; p++) {
8411 free(statspec->layouts[l][p]);
8413 free(statspec->layouts[l]);
8415 free(statspec->layouts);
8416 free(statspec->platforms);
8433 HouseSpec **&housespec = file->housespec;
8434 if (housespec ==
nullptr)
continue;
8440 housespec =
nullptr;
8449 if (aslist !=
nullptr) {
8453 if (as !=
nullptr) {
8455 for (
int j = 0; j < as->
num_table; j++) {
8467 file->airportspec =
nullptr;
8471 if (airporttilespec !=
nullptr) {
8473 free(airporttilespec[i]);
8475 free(airporttilespec);
8476 airporttilespec =
nullptr;
8490 if (industryspec !=
nullptr) {
8497 industryspec =
nullptr;
8500 if (indtspec ==
nullptr)
continue;
8515 if (objectspec ==
nullptr)
continue;
8517 free(objectspec[i]);
8521 objectspec =
nullptr;
8553 CleanUpGRFTownNames();
8597 ObjectClass::Reset();
8602 StationClass::Reset();
8606 AirportClass::Reset();
8635 _grf_id_overrides.clear();
8637 InitializeSoundPool();
8685 if (newfile !=
nullptr) {
8691 newfile =
new GRFFile(config);
8709 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8714 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8721 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8725 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8741 free(this->filename);
8751 'PASS',
'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
8752 'IORE',
'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
8753 'WATR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8757 static const CargoLabel _default_refitmasks_road[] = {
8760 static const CargoLabel _default_refitmasks_ships[] = {
8761 'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
'IORE',
8762 'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
'WATR',
8763 'RUBR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8767 static const CargoLabel _default_refitmasks_aircraft[] = {
8768 'PASS',
'MAIL',
'GOOD',
'VALU',
'GOLD',
'DIAM',
'FOOD',
'FRUT',
'SUGR',
8769 'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
'PLST',
'FZDR',
8772 static const CargoLabel *
const _default_refitmasks[] = {
8774 _default_refitmasks_road,
8775 _default_refitmasks_ships,
8776 _default_refitmasks_aircraft,
8788 bool only_defaultcargo;
8792 CargoTypes mask = 0;
8793 CargoTypes not_mask = 0;
8794 CargoTypes xor_mask = ei->refit_mask;
8800 if (
_gted[engine].cargo_allowed != 0) {
8803 FOR_ALL_CARGOSPECS(cs) {
8809 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8815 CargoTypes xor_mask = 0;
8820 for (uint i = 0;; i++) {
8821 if (cl[i] == 0)
break;
8833 only_defaultcargo = (ei->refit_mask == 0);
8847 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8849 const uint8 *cargo_map_for_first_refittable =
nullptr;
8852 if (file ==
nullptr) file = e->
GetGRF();
8853 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8854 cargo_map_for_first_refittable = file->
cargo_map;
8858 if (cargo_map_for_first_refittable !=
nullptr) {
8860 byte best_local_slot = 0xFF;
8862 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8863 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8864 if (local_slot < best_local_slot) {
8865 best_local_slot = local_slot;
8866 ei->cargo_type = cargo_type;
8888 for (uint i = 0; i < CF_END; i++) {
8900 if (e->
GetGRF() ==
nullptr) {
8903 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
8938 default: NOT_REACHED();
8952 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8953 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8977 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);
8987 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);
8995 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);
9002 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);
9021 if (hs ==
nullptr || !hs->
enabled)
continue;
9026 if (min_year == 0)
return;
9030 if (hs ==
nullptr || !hs->
enabled)
continue;
9054 HouseSpec **&housespec = file->housespec;
9055 if (housespec ==
nullptr)
continue;
9060 if (hs ==
nullptr)
continue;
9118 if (industryspec !=
nullptr) {
9122 if (indsp !=
nullptr && indsp->
enabled) {
9128 if (strid != STR_UNDEFINED) indsp->
name = strid;
9131 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9146 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9154 if (indtspec !=
nullptr) {
9157 if (indtsp !=
nullptr) {
9158 _industile_mngr.SetEntitySpec(indtsp);
9167 for (uint i = 0; i < 3; i++) {
9172 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9186 if (objectspec !=
nullptr) {
9188 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9205 if (airportspec !=
nullptr) {
9207 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9208 _airport_mngr.SetEntitySpec(airportspec[i]);
9214 if (airporttilespec !=
nullptr) {
9216 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9217 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9230 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9244 static const SpecialSpriteHandler handlers[][GLS_END] = {
9245 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9246 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9247 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9248 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9249 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9250 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9251 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9252 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9253 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9254 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9255 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9256 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9257 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9259 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9262 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9265 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9270 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9271 if (it == _grf_line_to_action6_sprite_override.end()) {
9277 buf = _grf_line_to_action6_sprite_override[location];
9278 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9288 byte action = bufp->ReadByte();
9290 if (action == 0xFF) {
9291 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9292 }
else if (action == 0xFE) {
9293 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9294 }
else if (action >=
lengthof(handlers)) {
9295 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9296 }
else if (handlers[action][stage] ==
nullptr) {
9297 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9299 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9300 handlers[action][stage](bufp);
9303 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9310 extern const byte _grf_cont_v2_sig[8] = {
'G',
'R',
'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9344 const char *filename = config->
filename;
9355 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9357 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9363 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of file slots has been reached", filename);
9365 config->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9375 DEBUG(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9379 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9383 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9395 if (compression != 0) {
9396 DEBUG(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9408 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9422 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9433 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9434 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9498 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9499 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9500 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9501 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9502 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9503 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9514 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9518 int *grf_overrides =
AllocaM(
int, num_grfs);
9519 for (
int i = 0; i < num_grfs; i++) {
9520 grf_overrides[i] = -1;
9523 uint32
override = _grf_id_overrides[source->grfid];
9524 if (
override == 0)
continue;
9527 if (dest ==
nullptr)
continue;
9530 assert(grf_overrides[i] >= 0);
9534 for (
int i = 0; i < num_grfs; i++) {
9535 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9543 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9546 DEBUG(grf, 3,
"'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9552 for (
int i = num_grfs - 1; i >= 0; i--) {
9553 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9561 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9564 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9570 for (
int i = 0; i < num_grfs; i++) {
9571 if (grf_overrides[i] < 0)
continue;
9579 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9580 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9582 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9590 if (file->grf_version >= 8)
continue;
9591 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9592 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9594 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9597 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9604 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9605 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9606 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9608 price_base_multipliers[p] = 0;
9613 DEBUG(grf, 3,
"'%s' sets global price base multiplier %d", file->filename, p);
9615 price_base_multipliers[p] = 0;
9617 DEBUG(grf, 3,
"'%s' sets local price base multiplier %d", file->filename, p);
9632 _string_to_grf_mapping.clear();
9635 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9638 _grf_line_to_action6_sprite_override.clear();
9701 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9710 if (
_gted[e->
index].roadtramtype < list->size())
9712 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9730 e->u.rail.railtype = railtype;
9740 _grm_sprites.clear();
9749 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9789 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9796 if (stage == GLS_RESERVE) {
9797 static const uint32 overrides[][2] = {
9798 { 0x44442202, 0x44440111 },
9799 { 0x6D620402, 0x6D620401 },
9800 { 0x4D656f20, 0x4D656F17 },
9802 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9807 uint slot = file_index;
9808 uint num_non_static = 0;
9817 DEBUG(grf, 0,
"NewGRF file is missing '%s'; disabling", c->
filename);
9826 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9828 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9834 if (stage == GLS_RESERVE) {
9836 }
else if (stage == GLS_ACTIVATION) {
9841 DEBUG(sprite, 2,
"LoadNewGRF: Currently %i sprites are loaded", _cur.
spriteid);