52 #include "table/strings.h"
69 const std::vector<GRFFile *> &GetAllGRFFiles()
118 this->skip_sprites = 0;
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
124 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.
sprite = first_sprite + i * numents;
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
179 return this->spritesets[feature].find(set)->second.sprite;
191 return this->spritesets[feature].find(set)->second.num_sprites;
204 template <VehicleType T>
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
219 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
221 inline byte *ReadBytes(
size_t size)
223 if (data + size >= end) {
234 inline byte ReadByte()
236 if (data < end)
return *(data)++;
242 uint16 val = ReadByte();
243 return val | (ReadByte() << 8);
246 uint16 ReadExtendedByte()
248 uint16 val = ReadByte();
249 return val == 0xFF ? ReadWord() : val;
254 uint32 val = ReadWord();
255 return val | (ReadWord() << 16);
258 uint32 ReadVarSize(
byte size)
261 case 1:
return ReadByte();
262 case 2:
return ReadWord();
263 case 4:
return ReadDWord();
270 const char *ReadString()
272 char *
string =
reinterpret_cast<char *
>(data);
273 size_t string_length =
ttd_strnlen(
string, Remaining());
275 if (string_length == Remaining()) {
277 string[string_length - 1] =
'\0';
278 grfmsg(7,
"String was not terminated with a zero byte.");
288 inline size_t Remaining()
const
293 inline bool HasData(
size_t count = 1)
const
295 return data + count <= end;
303 inline void Skip(
size_t len)
312 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
325 uint16 cargo_allowed;
326 uint16 cargo_disallowed;
327 RailTypeLabel railtypelabel;
343 }
else if (this->refittability ==
UNSET) {
344 this->refittability =
EMPTY;
364 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
368 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
373 return this->grfid == other.grfid && this->nfoline == other.nfoline;
377 static std::map<GRFLocation, SpriteID> _grm_sprites;
378 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
379 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
391 void CDECL
grfmsg(
int severity,
const char *str, ...)
411 if (file->grfid == grfid)
return file;
424 if (strcmp(file->filename, filename) == 0)
return file;
444 if (config !=
nullptr) {
455 if (message != STR_NULL) {
456 delete config->error;
457 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
461 return config->error;
472 typedef std::vector<StringIDMapping> StringIDMappingVector;
473 static StringIDMappingVector _string_to_grf_mapping;
482 *target = STR_UNDEFINED;
483 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
496 static const StringID units_volume[] = {
497 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
498 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
499 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
500 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
501 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
502 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
503 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
504 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
510 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
511 static_assert(stringend - stringid == end - begin); \
512 if (str >= begin && str <= end) return str + (stringid - begin)
515 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
516 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
517 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
518 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
519 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
520 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
525 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
526 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
527 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
530 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
531 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
532 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
533 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
534 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
537 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
538 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
539 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
541 #undef TEXTID_TO_STRINGID
543 if (str == STR_NULL)
return STR_EMPTY;
545 Debug(grf, 0,
"Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
584 static std::map<uint32, uint32> _grf_id_overrides;
593 _grf_id_overrides[source_grfid] = target_grfid;
594 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
609 uint32 scope_grfid = INVALID_GRFID;
612 scope_grfid = file->grfid;
613 uint32
override = _grf_id_overrides[file->grfid];
615 scope_grfid =
override;
617 if (grf_match ==
nullptr) {
618 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
625 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
634 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
640 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
644 if (!static_access) {
646 eid->
grfid = scope_grfid;
652 if (static_access)
return nullptr;
655 grfmsg(0,
"Can't allocate any more engines");
666 assert(_engine_mngr.size() == e->
index);
667 _engine_mngr.push_back({
680 memset(
_gted + engine_pool_size, 0, len);
686 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
703 uint32 scope_grfid = INVALID_GRFID;
705 scope_grfid = file->grfid;
706 uint32
override = _grf_id_overrides[file->grfid];
707 if (
override != 0) scope_grfid =
override;
710 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
750 grf_sprite->
sprite = buf->ReadWord();
751 grf_sprite->
pal = buf->ReadWord();
756 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
760 uint index =
GB(grf_sprite->
sprite, 0, 14);
762 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
763 grf_sprite->
sprite = SPR_IMG_QUERY;
764 grf_sprite->
pal = PAL_NONE;
767 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
772 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
773 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
779 uint index =
GB(grf_sprite->
pal, 0, 14);
781 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
782 grf_sprite->
pal = PAL_NONE;
785 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
790 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
791 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
820 regs.delta.
parent[0] = buf->ReadByte();
821 regs.delta.
parent[1] = buf->ReadByte();
833 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
842 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
861 bool has_flags =
HasBit(num_building_sprites, 6);
862 ClrBit(num_building_sprites, 6);
865 dts->
Allocate(num_building_sprites);
867 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
868 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
869 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
870 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
877 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
878 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
885 for (uint i = 0; i < num_building_sprites; i++) {
888 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
891 if (flags & ~valid_flags) {
892 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
893 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
897 seq->
delta_x = buf->ReadByte();
898 seq->delta_y = buf->ReadByte();
900 if (!no_z_position) seq->
delta_z = buf->ReadByte();
903 seq->size_x = buf->ReadByte();
904 seq->size_y = buf->ReadByte();
905 seq->size_z = buf->ReadByte();
913 bool is_consistent =
true;
915 for (uint i = 0; i < num_building_sprites + 1; i++) {
916 if (max_sprite_offset[i] > 0) {
920 is_consistent =
false;
924 if (max_palette_offset[i] > 0) {
928 is_consistent =
false;
937 if (!is_consistent || dts->registers !=
nullptr) {
941 for (uint i = 0; i < num_building_sprites + 1; i++) {
956 CargoTypes result = 0;
974 if (base_pointer == 0) {
975 *index = INVALID_PRICE;
979 static const uint32 start = 0x4B34;
980 static const uint32 size = 6;
982 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
983 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
987 *index = (
Price)((base_pointer - start) / size);
1016 ei->decay_speed = buf->ReadByte();
1033 ei->load_amount = buf->ReadByte();
1055 for (
int i = 0; i < numinfo; i++) {
1064 uint8 tracktype = buf->ReadByte();
1066 if (tracktype < _cur.grffile->railtype_list.size()) {
1071 switch (tracktype) {
1072 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1073 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1074 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1076 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1089 uint16 speed = buf->ReadWord();
1090 if (speed == 0xFFFF) speed = 0;
1097 rvi->
power = buf->ReadWord();
1100 if (rvi->
power != 0) {
1118 uint8 spriteid = buf->ReadByte();
1119 uint8 orig_spriteid = spriteid;
1123 if (spriteid < 0xFD) spriteid >>= 1;
1125 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1126 rvi->image_index = spriteid;
1128 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1129 rvi->image_index = 0;
1135 uint8 dual = buf->ReadByte();
1140 rvi->railveh_type = rvi->
power == 0 ?
1152 uint8 ctype = buf->ReadByte();
1154 if (ctype == 0xFF) {
1157 }
else if (_cur.
grffile->grf_version >= 8) {
1162 ei->cargo_type = ctype;
1165 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1171 SB(rvi->
weight, 0, 8, buf->ReadByte());
1179 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1191 uint8 traction = buf->ReadByte();
1194 if (traction <= 0x07) {
1196 }
else if (traction <= 0x27) {
1198 }
else if (traction <= 0x31) {
1200 }
else if (traction <= 0x37) {
1202 }
else if (traction <= 0x41) {
1228 ei->refit_cost = buf->ReadByte();
1232 uint32 mask = buf->ReadDWord();
1270 byte weight = buf->ReadByte();
1273 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1294 _gted[e->
index].cargo_allowed = buf->ReadWord();
1300 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1314 uint8 count = buf->ReadByte();
1360 for (
int i = 0; i < numinfo; i++) {
1371 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1379 rvi->running_cost = buf->ReadByte();
1387 uint8 spriteid = buf->ReadByte();
1388 uint8 orig_spriteid = spriteid;
1391 if (spriteid == 0xFF) spriteid = 0xFD;
1393 if (spriteid < 0xFD) spriteid >>= 1;
1395 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1396 rvi->image_index = spriteid;
1398 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1399 rvi->image_index = 0;
1405 rvi->capacity = buf->ReadByte();
1410 uint8 ctype = buf->ReadByte();
1412 if (ctype == 0xFF) {
1415 }
else if (_cur.
grffile->grf_version >= 8) {
1420 ei->cargo_type = ctype;
1423 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1429 rvi->cost_factor = buf->ReadByte();
1437 rvi->
power = buf->ReadByte();
1441 rvi->
weight = buf->ReadByte();
1449 uint32 mask = buf->ReadDWord();
1469 ei->refit_cost = buf->ReadByte();
1482 _gted[e->
index].cargo_allowed = buf->ReadWord();
1488 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1520 uint8 count = buf->ReadByte();
1562 for (
int i = 0; i < numinfo; i++) {
1571 uint8 spriteid = buf->ReadByte();
1572 uint8 orig_spriteid = spriteid;
1575 if (spriteid == 0xFF) spriteid = 0xFD;
1577 if (spriteid < 0xFD) spriteid >>= 1;
1579 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1580 svi->image_index = spriteid;
1582 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1583 svi->image_index = 0;
1593 svi->cost_factor = buf->ReadByte();
1602 uint8 ctype = buf->ReadByte();
1604 if (ctype == 0xFF) {
1607 }
else if (_cur.
grffile->grf_version >= 8) {
1612 ei->cargo_type = ctype;
1615 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1621 svi->capacity = buf->ReadWord();
1625 svi->running_cost = buf->ReadByte();
1633 uint32 mask = buf->ReadDWord();
1645 ei->refit_cost = buf->ReadByte();
1666 _gted[e->
index].cargo_allowed = buf->ReadWord();
1672 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1700 uint8 count = buf->ReadByte();
1742 for (
int i = 0; i < numinfo; i++) {
1751 uint8 spriteid = buf->ReadByte();
1752 uint8 orig_spriteid = spriteid;
1755 if (spriteid == 0xFF) spriteid = 0xFD;
1757 if (spriteid < 0xFD) spriteid >>= 1;
1759 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1760 avi->image_index = spriteid;
1762 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1763 avi->image_index = 0;
1769 if (buf->ReadByte() == 0) {
1777 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1781 avi->cost_factor = buf->ReadByte();
1785 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1789 avi->acceleration = buf->ReadByte();
1793 avi->running_cost = buf->ReadByte();
1809 uint32 mask = buf->ReadDWord();
1821 ei->refit_cost = buf->ReadByte();
1834 _gted[e->
index].cargo_allowed = buf->ReadWord();
1840 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1858 uint8 count = buf->ReadByte();
1912 for (
int i = 0; i < numinfo; i++) {
1916 if (statspec ==
nullptr && prop != 0x08) {
1917 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1929 uint32 classid = buf->ReadDWord();
1930 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1935 uint16 tiles = buf->ReadExtendedByte();
1939 for (uint t = 0; t < tiles; t++) {
1943 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1946 dts->
Clone(&_station_display_datas_rail[t % 8]);
1954 static std::vector<DrawTileSeqStruct> tmp_layout;
1961 dtss.
delta_x = buf->ReadByte();
1963 dtss.delta_y = buf->ReadByte();
1964 dtss.
delta_z = buf->ReadByte();
1965 dtss.size_x = buf->ReadByte();
1966 dtss.size_y = buf->ReadByte();
1967 dtss.size_z = buf->ReadByte();
1973 dts->
Clone(tmp_layout.data());
1978 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
1985 byte srcid = buf->ReadByte();
1988 if (srcstatspec ==
nullptr) {
1989 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1996 for (
const auto &it : srcstatspec->
renderdata) {
2016 while (buf->HasData()) {
2017 byte length = buf->ReadByte();
2018 byte number = buf->ReadByte();
2020 if (length == 0 || number == 0)
break;
2022 if (statspec->
layouts.size() < length) statspec->
layouts.resize(length);
2023 if (statspec->
layouts[length - 1].size() < number) statspec->
layouts[length - 1].resize(number);
2025 const byte *layout = buf->ReadBytes(length * number);
2026 statspec->
layouts[length - 1][number - 1].assign(layout, layout + length * number);
2029 for (
auto &tile : statspec->
layouts[length - 1][number - 1]) {
2030 if ((tile & 6) != tile) {
2031 grfmsg(1,
"StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
2039 byte srcid = buf->ReadByte();
2042 if (srcstatspec ==
nullptr) {
2043 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2056 statspec->
pylons = buf->ReadByte();
2060 if (_cur.
grffile->grf_version >= 7) {
2068 statspec->
flags = buf->ReadByte();
2072 statspec->
wires = buf->ReadByte();
2076 statspec->
blocked = buf->ReadByte();
2080 statspec->animation.
frames = buf->ReadByte();
2081 statspec->animation.
status = buf->ReadByte();
2085 statspec->animation.
speed = buf->ReadByte();
2089 statspec->animation.
triggers = buf->ReadWord();
2093 uint16 tiles = buf->ReadExtendedByte();
2097 for (uint t = 0; t < tiles; t++) {
2099 uint num_building_sprites = buf->ReadByte();
2106 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
2133 if (
id + numinfo > CF_END) {
2134 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2138 for (
int i = 0; i < numinfo; i++) {
2147 cp->
flags = buf->ReadByte();
2172 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2176 for (
int i = 0; i < numinfo; i++) {
2182 byte year = buf->ReadByte();
2197 bridge->
price = buf->ReadByte();
2201 bridge->
speed = buf->ReadWord();
2202 if (bridge->
speed == 0) bridge->
speed = UINT16_MAX;
2206 byte tableid = buf->ReadByte();
2207 byte numtables = buf->ReadByte();
2214 for (; numtables-- != 0; tableid++) {
2216 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2217 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2222 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2225 for (
byte sprite = 0; sprite < 32; sprite++) {
2239 bridge->
flags = buf->ReadByte();
2248 if (newone != STR_UNDEFINED) bridge->
material = newone;
2255 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2260 bridge->
price = buf->ReadWord();
2317 for (uint j = 0; j < 4; j++) buf->ReadByte();
2321 byte count = buf->ReadByte();
2322 for (
byte j = 0; j < count; j++) buf->ReadByte();
2327 buf->Skip(buf->ReadByte() * 2);
2350 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2355 if (_cur.
grffile->housespec ==
nullptr) {
2359 for (
int i = 0; i < numinfo; i++) {
2362 if (prop != 0x08 && housespec ==
nullptr) {
2365 if (cir > ret) ret = cir;
2372 byte subs_id = buf->ReadByte();
2374 if (subs_id == 0xFF) {
2377 HouseSpec::Get(hid + i)->
enabled =
false;
2381 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2386 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2390 MemCpyT(housespec, HouseSpec::Get(subs_id));
2394 housespec->
grf_prop.subst_id = subs_id;
2416 uint16 years = buf->ReadWord();
2436 int8 goods = buf->ReadByte();
2472 byte override = buf->ReadByte();
2476 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2480 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2489 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2511 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2519 uint32 cargotypes = buf->ReadDWord();
2522 if (cargotypes == 0xFFFFFFFF)
break;
2524 for (uint j = 0; j < 3; j++) {
2526 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2544 byte count = buf->ReadByte();
2545 for (
byte j = 0; j < count; j++) {
2553 housespec->
min_year = buf->ReadWord();
2557 housespec->
max_year = buf->ReadWord();
2561 uint count = buf->ReadByte();
2564 error->param_value[1] = prop;
2613 template <
typename T>
2617 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2621 translation_table.clear();
2622 for (
int i = 0; i < numinfo; i++) {
2623 uint32 item = buf->ReadDWord();
2624 translation_table.push_back(
BSWAP32(item));
2639 for (
int i = 0; i < 4; i++) output[i] = reader->ReadByte();
2643 return std::string(output);
2676 for (
int i = 0; i < numinfo; i++) {
2679 int factor = buf->ReadByte();
2680 uint price = gvid + i;
2682 if (price < PR_END) {
2685 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2694 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2702 uint32 rate = buf->ReadDWord();
2710 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2717 uint16 options = buf->ReadWord();
2726 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2738 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2750 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2757 Year year_euro = buf->ReadWord();
2762 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2769 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2771 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2777 table[i][j] = buf->ReadByte();
2778 if (_cur.
grffile->grf_version >= 8) {
2781 if (table[i][j] >= 128) {
2803 uint curidx = gvid + i;
2805 if (lang ==
nullptr) {
2806 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2811 while (buf->ReadByte() != 0) {
2821 uint plural_form = buf->ReadByte();
2822 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2823 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2830 byte newgrf_id = buf->ReadByte();
2831 while (newgrf_id != 0) {
2832 const char *name = buf->ReadString();
2847 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2854 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2859 newgrf_id = buf->ReadByte();
2895 for (
int i = 0; i < numinfo; i++) {
2919 uint32 s = buf->ReadDWord();
2920 uint32 t = buf->ReadDWord();
2927 while (buf->ReadByte() != 0) {
2955 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2959 for (
int i = 0; i < numinfo; i++) {
2964 cs->
bitnum = buf->ReadByte();
3002 cs->
sprite = buf->ReadWord();
3006 cs->
weight = buf->ReadByte();
3010 cs->transit_days[0] = buf->ReadByte();
3014 cs->transit_days[1] = buf->ReadByte();
3022 cs->rating_colour = buf->ReadByte();
3026 cs->legend_colour = buf->ReadByte();
3034 cs->
classes = buf->ReadWord();
3038 cs->
label = buf->ReadDWord();
3043 uint8 substitute_type = buf->ReadByte();
3045 switch (substitute_type) {
3052 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3068 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3093 if (_cur.
grffile->sound_offset == 0) {
3094 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3099 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3103 for (
int i = 0; i < numinfo; i++) {
3108 sound->volume = buf->ReadByte();
3112 sound->priority = buf->ReadByte();
3116 SoundID orig_sound = buf->ReadByte();
3121 SoundEntry *old_sound = GetSound(orig_sound);
3124 *old_sound = *sound;
3166 buf->Skip(buf->ReadByte() * 2);
3194 if (_cur.
grffile->indtspec ==
nullptr) {
3198 for (
int i = 0; i < numinfo; i++) {
3201 if (prop != 0x08 && tsp ==
nullptr) {
3203 if (cir > ret) ret = cir;
3210 byte subs_id = buf->ReadByte();
3214 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3219 if (*tilespec ==
nullptr) {
3220 *tilespec = CallocT<IndustryTileSpec>(1);
3223 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3241 byte ovrid = buf->ReadByte();
3245 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3249 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3256 uint16 acctp = buf->ReadWord();
3288 byte num_cargoes = buf->ReadByte();
3291 error->param_value[1] = prop;
3295 if (i < num_cargoes) {
3362 byte num_table = buf->ReadByte();
3363 for (
byte j = 0; j < num_table; j++) {
3364 for (uint k = 0;; k++) {
3365 byte x = buf->ReadByte();
3366 if (x == 0xFE && k == 0) {
3372 byte y = buf->ReadByte();
3373 if (x == 0 && y == 0x80)
break;
3375 byte gfx = buf->ReadByte();
3376 if (gfx == 0xFE) buf->ReadWord();
3383 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3390 buf->Skip(buf->ReadByte());
3394 int num_inputs = buf->ReadByte();
3395 int num_outputs = buf->ReadByte();
3396 buf->Skip(num_inputs * num_outputs * 2);
3414 const size_t size = layout.size();
3415 if (size == 0)
return false;
3417 for (
size_t i = 0; i < size - 1; i++) {
3418 for (
size_t j = i + 1; j < size; j++) {
3419 if (layout[i].ti.x == layout[j].ti.x &&
3420 layout[i].ti.y == layout[j].ti.y) {
3426 bool have_regular_tile =
false;
3427 for (
size_t i = 0; i < size; i++) {
3429 have_regular_tile =
true;
3434 return have_regular_tile;
3455 if (_cur.
grffile->industryspec ==
nullptr) {
3459 for (
int i = 0; i < numinfo; i++) {
3462 if (prop != 0x08 && indsp ==
nullptr) {
3464 if (cir > ret) ret = cir;
3471 byte subs_id = buf->ReadByte();
3473 if (subs_id == 0xFF) {
3476 _industry_specs[indid + i].
enabled =
false;
3480 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3487 if (*indspec ==
nullptr) {
3491 *indsp = _origin_industry_specs[subs_id];
3494 indsp->
grf_prop.subst_id = subs_id;
3504 byte ovrid = buf->ReadByte();
3508 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3512 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3517 byte new_num_layouts = buf->ReadByte();
3518 uint32 definition_size = buf->ReadDWord();
3519 uint32 bytes_read = 0;
3520 std::vector<IndustryTileLayout> new_layouts;
3523 for (
byte j = 0; j < new_num_layouts; j++) {
3526 for (uint k = 0;; k++) {
3527 if (bytes_read >= definition_size) {
3528 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3530 definition_size = UINT32_MAX;
3536 it.ti.
x = buf->ReadByte();
3539 if (it.ti.
x == 0xFE && k == 0) {
3541 IndustryType type = buf->ReadByte();
3542 byte laynbr = buf->ReadByte();
3545 if (type >=
lengthof(_origin_industry_specs)) {
3546 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3550 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3551 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3555 layout = _origin_industry_specs[type].layouts[laynbr];
3559 it.ti.
y = buf->ReadByte();
3562 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3568 it.gfx = buf->ReadByte();
3571 if (it.gfx == 0xFE) {
3573 int local_tile_id = buf->ReadWord();
3577 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3580 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3586 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3587 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3596 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3602 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3606 new_layouts.push_back(layout);
3636 for (
byte j = 0; j < 2; j++) {
3642 for (
byte j = 0; j < 3; j++) {
3650 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3663 sounds[j] = buf->ReadByte();
3679 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3705 uint32 multiples = buf->ReadDWord();
3721 byte aflag = buf->ReadByte();
3731 uint16 str = buf->ReadWord();
3741 byte num_cargoes = buf->ReadByte();
3742 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3744 error->param_value[1] = prop;
3747 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3748 if (i < num_cargoes) {
3750 indsp->produced_cargo[i] = cargo;
3759 byte num_cargoes = buf->ReadByte();
3762 error->param_value[1] = prop;
3766 if (i < num_cargoes) {
3777 byte num_cargoes = buf->ReadByte();
3778 if (num_cargoes >
lengthof(indsp->production_rate)) {
3780 error->param_value[1] = prop;
3783 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3784 if (i < num_cargoes) {
3785 indsp->production_rate[i] = buf->ReadByte();
3787 indsp->production_rate[i] = 0;
3794 byte num_inputs = buf->ReadByte();
3795 byte num_outputs = buf->ReadByte();
3798 error->param_value[1] = prop;
3802 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3804 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3828 for (
int i = 0; i < as->
num_table; i++) {
3833 }
while ((++it)->ti.x != -0x80);
3834 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3837 as->
table = table_list;
3859 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3864 if (_cur.
grffile->airportspec ==
nullptr) {
3868 for (
int i = 0; i < numinfo; i++) {
3871 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3872 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3878 byte subs_id = buf->ReadByte();
3880 if (subs_id == 0xFF) {
3887 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3895 if (*spec ==
nullptr) {
3896 *spec = MallocT<AirportSpec>(1);
3905 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3917 uint32 defsize = buf->ReadDWord();
3923 for (
byte j = 0; j < as->
num_table; j++) {
3925 for (
int k = 0;; k++) {
3926 att[k].
ti.
x = buf->ReadByte();
3927 att[k].
ti.
y = buf->ReadByte();
3929 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3932 att[k].
ti.
x = -0x80;
3941 att[k].
gfx = buf->ReadByte();
3943 if (att[k].gfx == 0xFE) {
3945 int local_tile_id = buf->ReadWord();
3948 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3951 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3954 att[k].
gfx = tempid;
3956 }
else if (att[k].gfx == 0xFF) {
3957 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3958 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3969 tile_table[j] = CallocT<AirportTileTable>(size);
3970 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3973 for (
int j = 0; j < old_num_table; j++) {
3979 as->
table = tile_table;
3982 for (
int i = 0; i < as->
num_table; i++) {
3983 free(tile_table[i]);
4089 if (_cur.
grffile->objectspec ==
nullptr) {
4093 for (
int i = 0; i < numinfo; i++) {
4096 if (prop != 0x08 && spec ==
nullptr) {
4099 if (cir > ret) ret = cir;
4108 if (*ospec ==
nullptr) {
4109 *ospec = CallocT<ObjectSpec>(1);
4110 (*ospec)->views = 1;
4115 uint32 classid = buf->ReadDWord();
4116 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4117 (*ospec)->enabled =
true;
4132 spec->
climate = buf->ReadByte();
4136 spec->
size = buf->ReadByte();
4137 if (
GB(spec->
size, 0, 4) == 0 ||
GB(spec->
size, 4, 4) == 0) {
4138 grfmsg(0,
"ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->
size,
id + i);
4183 spec->
height = buf->ReadByte();
4187 spec->
views = buf->ReadByte();
4189 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4222 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4226 for (
int i = 0; i < numinfo; i++) {
4239 uint16 str = buf->ReadWord();
4241 if (_cur.
grffile->grf_version < 8) {
4271 int n = buf->ReadByte();
4272 for (
int j = 0; j != n; j++) {
4273 RailTypeLabel label = buf->ReadDWord();
4333 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4352 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4356 for (
int i = 0; i < numinfo; i++) {
4360 RailTypeLabel rtl = buf->ReadDWord();
4369 _cur.
grffile->railtype_map[
id + i] = rt;
4387 int n = buf->ReadByte();
4388 for (
int j = 0; j != n; j++) {
4393 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4400 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4441 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4445 for (
int i = 0; i < numinfo; i++) {
4458 uint16 str = buf->ReadWord();
4485 int n = buf->ReadByte();
4486 for (
int j = 0; j != n; j++) {
4487 RoadTypeLabel label = buf->ReadDWord();
4534 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4565 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4569 for (
int i = 0; i < numinfo; i++) {
4572 RoadTypeLabel rtl = buf->ReadDWord();
4579 }
else if (GetRoadTramType(rt) != rtt) {
4580 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4584 type_map[
id + i] = rt;
4601 int n = buf->ReadByte();
4602 for (
int j = 0; j != n; j++) {
4607 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4613 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4637 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4642 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4655 if (_cur.
grffile->airtspec ==
nullptr) {
4659 for (
int i = 0; i < numinfo; i++) {
4662 if (prop != 0x08 && tsp ==
nullptr) {
4663 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4670 byte subs_id = buf->ReadByte();
4674 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4679 if (*tilespec ==
nullptr) {
4680 *tilespec = CallocT<AirportTileSpec>(1);
4697 byte override = buf->ReadByte();
4701 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4705 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4735 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4738 default: NOT_REACHED();
4748 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4752 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4765 static void FeatureChangeInfo(
ByteReader *buf)
4778 static const VCI_Handler handler[] = {
4796 AirportTilesChangeInfo,
4800 static_assert(GSF_END ==
lengthof(handler));
4802 uint8 feature = buf->ReadByte();
4803 uint8 numprops = buf->ReadByte();
4804 uint numinfo = buf->ReadByte();
4805 uint engine = buf->ReadExtendedByte();
4807 if (feature >= GSF_END) {
4808 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4812 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4813 feature, numprops, engine, numinfo);
4815 if (handler[feature] ==
nullptr) {
4816 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4823 while (numprops-- && buf->HasData()) {
4824 uint8 prop = buf->ReadByte();
4827 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4834 uint8 feature = buf->ReadByte();
4835 uint8 numprops = buf->ReadByte();
4836 uint numinfo = buf->ReadByte();
4837 buf->ReadExtendedByte();
4839 if (feature == GSF_BRIDGES && numprops == 1) {
4840 uint8 prop = buf->ReadByte();
4843 if (prop == 0x0D)
return;
4844 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4845 uint8 prop = buf->ReadByte();
4848 bool is_safe =
true;
4849 for (uint i = 0; i < numinfo; i++) {
4850 uint32 s = buf->ReadDWord();
4858 if (is_safe)
return;
4869 static void ReserveChangeInfo(
ByteReader *buf)
4871 uint8 feature = buf->ReadByte();
4873 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4875 uint8 numprops = buf->ReadByte();
4876 uint8 numinfo = buf->ReadByte();
4877 uint8 index = buf->ReadExtendedByte();
4879 while (numprops-- && buf->HasData()) {
4880 uint8 prop = buf->ReadByte();
4884 default: NOT_REACHED();
4890 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4894 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4898 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4902 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4906 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4927 uint8 feature = buf->ReadByte();
4928 uint16 num_sets = buf->ReadByte();
4929 uint16 first_set = 0;
4931 if (num_sets == 0 && buf->HasData(3)) {
4934 first_set = buf->ReadExtendedByte();
4935 num_sets = buf->ReadExtendedByte();
4937 uint16 num_ents = buf->ReadExtendedByte();
4939 if (feature >= GSF_END) {
4941 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4947 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4948 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4951 for (
int i = 0; i < num_sets * num_ents; i++) {
4961 uint16 num_sets = buf->ReadByte();
4963 if (num_sets == 0 && buf->HasData(3)) {
4966 buf->ReadExtendedByte();
4967 num_sets = buf->ReadExtendedByte();
4969 uint16 num_ents = buf->ReadExtendedByte();
4978 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4980 if (
HasBit(groupid, 15)) {
4985 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4986 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4990 return _cur.spritegroups[groupid];
5003 if (
HasBit(spriteid, 15)) {
5009 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
5014 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
5017 assert(spriteset_start + num_sprites <= _cur.
spriteid);
5038 uint8 feature = buf->ReadByte();
5039 if (feature >= GSF_END) {
5040 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5044 uint8 setid = buf->ReadByte();
5045 uint8 type = buf->ReadByte();
5069 switch (
GB(type, 2, 2)) {
5070 default: NOT_REACHED();
5071 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5072 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5073 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5083 adjust.variable = buf->ReadByte();
5084 if (adjust.variable == 0x7E) {
5086 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5091 varadjust = buf->ReadByte();
5092 adjust.shift_num =
GB(varadjust, 0, 5);
5093 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5094 adjust.and_mask = buf->ReadVarSize(varsize);
5096 if (adjust.type != DSGA_TYPE_NONE) {
5097 adjust.add_val = buf->ReadVarSize(varsize);
5098 adjust.divmod_val = buf->ReadVarSize(varsize);
5101 adjust.divmod_val = 0;
5105 }
while (
HasBit(varadjust, 5));
5107 std::vector<DeterministicSpriteGroupRange> ranges;
5108 ranges.resize(buf->ReadByte());
5109 for (uint i = 0; i < ranges.size(); i++) {
5110 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5111 ranges[i].low = buf->ReadVarSize(varsize);
5112 ranges[i].high = buf->ReadVarSize(varsize);
5115 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5116 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5118 group->calculated_result = ranges.size() == 0;
5121 std::vector<uint32> bounds;
5122 for (uint i = 0; i < ranges.size(); i++) {
5123 bounds.push_back(ranges[i].low);
5124 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5126 std::sort(bounds.begin(), bounds.end());
5127 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5129 std::vector<const SpriteGroup *> target;
5130 for (uint j = 0; j < bounds.size(); ++j) {
5131 uint32 v = bounds[j];
5133 for (uint i = 0; i < ranges.size(); i++) {
5134 if (ranges[i].low <= v && v <= ranges[i].high) {
5135 t = ranges[i].group;
5139 target.push_back(t);
5141 assert(target.size() == bounds.size());
5143 for (uint j = 0; j < bounds.size(); ) {
5144 if (target[j] != group->default_group) {
5146 r.group = target[j];
5148 while (j < bounds.size() && target[j] == r.group) {
5151 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5173 group->count = buf->ReadByte();
5176 uint8 triggers = buf->ReadByte();
5177 group->triggers =
GB(triggers, 0, 7);
5178 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5181 byte num_groups = buf->ReadByte();
5183 grfmsg(1,
"NewSpriteGroup: Random Action 2 nrand should be power of 2");
5186 for (uint i = 0; i < num_groups; i++) {
5187 group->
groups.push_back(GetGroupFromGroupID(setid, type, buf->ReadWord()));
5198 case GSF_ROADVEHICLES:
5209 byte num_loaded = type;
5210 byte num_loading = buf->ReadByte();
5213 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5217 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5218 setid, num_loaded, num_loading);
5220 if (num_loaded + num_loading == 0) {
5221 grfmsg(1,
"NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
5225 if (num_loaded + num_loading == 1) {
5227 uint16 spriteid = buf->ReadWord();
5229 grfmsg(8,
"NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
5233 std::vector<uint16> loaded;
5234 std::vector<uint16> loading;
5236 for (uint i = 0; i < num_loaded; i++) {
5237 loaded.push_back(buf->ReadWord());
5238 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, loaded[i]);
5241 for (uint i = 0; i < num_loading; i++) {
5242 loading.push_back(buf->ReadWord());
5243 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
5246 if (std::adjacent_find(loaded.begin(), loaded.end(), std::not_equal_to<>()) == loaded.end() &&
5247 std::adjacent_find(loading.begin(), loading.end(), std::not_equal_to<>()) == loading.end() &&
5248 loaded[0] == loading[0])
5252 grfmsg(8,
"NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
5261 for (uint16 spriteid : loaded) {
5263 group->
loaded.push_back(t);
5266 for (uint16 spriteid : loading) {
5275 case GSF_AIRPORTTILES:
5277 case GSF_INDUSTRYTILES: {
5278 byte num_building_sprites = std::max((uint8)1, type);
5286 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5290 case GSF_INDUSTRIES: {
5292 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5303 for (uint i = 0; i < 3; i++) {
5307 for (uint i = 0; i < 2; i++) {
5310 group->again = buf->ReadByte();
5311 }
else if (type == 1) {
5313 for (uint i = 0; i < 3; i++) {
5317 for (uint i = 0; i < 2; i++) {
5320 group->again = buf->ReadByte();
5321 }
else if (type == 2) {
5325 error->data =
"too many inputs (max 16)";
5328 for (uint i = 0; i < group->
num_input; i++) {
5329 byte rawcargo = buf->ReadByte();
5338 error->data =
"duplicate input cargo";
5347 error->data =
"too many outputs (max 16)";
5350 for (uint i = 0; i < group->
num_output; i++) {
5351 byte rawcargo = buf->ReadByte();
5358 error->data =
"duplicate output cargo";
5364 group->again = buf->ReadByte();
5372 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5377 _cur.spritegroups[setid] = act_group;
5380 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5382 if (feature == GSF_OBJECTS) {
5387 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5392 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5393 if (ctype == 0xFF)
return CT_PURCHASE;
5398 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5403 if (cs->bitnum == ctype) {
5404 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5409 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5415 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5422 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5428 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));
5432 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);
5437 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5439 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5440 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5447 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5450 static uint last_engines_count;
5451 bool wagover =
false;
5454 if (
HasBit(idcount, 7)) {
5457 idcount =
GB(idcount, 0, 7);
5459 if (last_engines_count == 0) {
5460 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5464 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5465 last_engines_count, idcount);
5467 if (last_engines_count != idcount) {
5468 last_engines =
ReallocT(last_engines, idcount);
5469 last_engines_count = idcount;
5474 for (uint i = 0; i < idcount; i++) {
5480 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5484 engines[i] = e->
index;
5485 if (!wagover) last_engines[i] = engines[i];
5488 uint8 cidcount = buf->ReadByte();
5489 for (uint c = 0; c < cidcount; c++) {
5490 uint8 ctype = buf->ReadByte();
5491 uint16 groupid = buf->ReadWord();
5492 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5494 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5496 ctype = TranslateCargo(feature, ctype);
5499 for (uint i = 0; i < idcount; i++) {
5502 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5505 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5507 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5512 uint16 groupid = buf->ReadWord();
5513 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5515 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5517 for (uint i = 0; i < idcount; i++) {
5521 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5523 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5530 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5533 for (uint i = 0; i < idcount; i++) {
5537 uint8 cidcount = buf->ReadByte();
5538 buf->Skip(cidcount * 3);
5540 uint16 groupid = buf->ReadWord();
5541 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5543 for (uint i = 0; i < idcount; i++) {
5547 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5557 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5559 uint8 *stations =
AllocaM(uint8, idcount);
5560 for (uint i = 0; i < idcount; i++) {
5561 stations[i] = buf->ReadByte();
5564 uint8 cidcount = buf->ReadByte();
5565 for (uint c = 0; c < cidcount; c++) {
5566 uint8 ctype = buf->ReadByte();
5567 uint16 groupid = buf->ReadWord();
5568 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5570 ctype = TranslateCargo(GSF_STATIONS, ctype);
5573 for (uint i = 0; i < idcount; i++) {
5576 if (statspec ==
nullptr) {
5577 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5585 uint16 groupid = buf->ReadWord();
5586 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5588 for (uint i = 0; i < idcount; i++) {
5591 if (statspec ==
nullptr) {
5592 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5597 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5604 StationClass::Assign(statspec);
5609 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5611 uint8 *houses =
AllocaM(uint8, idcount);
5612 for (uint i = 0; i < idcount; i++) {
5613 houses[i] = buf->ReadByte();
5617 uint8 cidcount = buf->ReadByte();
5618 buf->Skip(cidcount * 3);
5620 uint16 groupid = buf->ReadWord();
5621 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5623 if (_cur.
grffile->housespec ==
nullptr) {
5624 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5628 for (uint i = 0; i < idcount; i++) {
5631 if (hs ==
nullptr) {
5632 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5640 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5642 uint8 *industries =
AllocaM(uint8, idcount);
5643 for (uint i = 0; i < idcount; i++) {
5644 industries[i] = buf->ReadByte();
5648 uint8 cidcount = buf->ReadByte();
5649 buf->Skip(cidcount * 3);
5651 uint16 groupid = buf->ReadWord();
5652 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5654 if (_cur.
grffile->industryspec ==
nullptr) {
5655 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5659 for (uint i = 0; i < idcount; i++) {
5662 if (indsp ==
nullptr) {
5663 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5671 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5673 uint8 *indtiles =
AllocaM(uint8, idcount);
5674 for (uint i = 0; i < idcount; i++) {
5675 indtiles[i] = buf->ReadByte();
5679 uint8 cidcount = buf->ReadByte();
5680 buf->Skip(cidcount * 3);
5682 uint16 groupid = buf->ReadWord();
5683 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5685 if (_cur.
grffile->indtspec ==
nullptr) {
5686 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5690 for (uint i = 0; i < idcount; i++) {
5693 if (indtsp ==
nullptr) {
5694 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5702 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5705 for (uint i = 0; i < idcount; i++) {
5706 cargoes[i] = buf->ReadByte();
5710 uint8 cidcount = buf->ReadByte();
5711 buf->Skip(cidcount * 3);
5713 uint16 groupid = buf->ReadWord();
5714 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5716 for (uint i = 0; i < idcount; i++) {
5720 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5726 cs->group = _cur.spritegroups[groupid];
5730 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5732 if (_cur.
grffile->objectspec ==
nullptr) {
5733 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5737 uint8 *objects =
AllocaM(uint8, idcount);
5738 for (uint i = 0; i < idcount; i++) {
5739 objects[i] = buf->ReadByte();
5742 uint8 cidcount = buf->ReadByte();
5743 for (uint c = 0; c < cidcount; c++) {
5744 uint8 ctype = buf->ReadByte();
5745 uint16 groupid = buf->ReadWord();
5746 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5748 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5751 for (uint i = 0; i < idcount; i++) {
5754 if (spec ==
nullptr) {
5755 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5763 uint16 groupid = buf->ReadWord();
5764 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5766 for (uint i = 0; i < idcount; i++) {
5769 if (spec ==
nullptr) {
5770 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5775 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5785 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5787 uint8 *railtypes =
AllocaM(uint8, idcount);
5788 for (uint i = 0; i < idcount; i++) {
5789 uint8
id = buf->ReadByte();
5793 uint8 cidcount = buf->ReadByte();
5794 for (uint c = 0; c < cidcount; c++) {
5795 uint8 ctype = buf->ReadByte();
5796 uint16 groupid = buf->ReadWord();
5797 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5799 if (ctype >= RTSG_END)
continue;
5802 for (uint i = 0; i < idcount; i++) {
5807 rti->
group[ctype] = _cur.spritegroups[groupid];
5816 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5820 uint8 *roadtypes =
AllocaM(uint8, idcount);
5821 for (uint i = 0; i < idcount; i++) {
5822 uint8
id = buf->ReadByte();
5826 uint8 cidcount = buf->ReadByte();
5827 for (uint c = 0; c < cidcount; c++) {
5828 uint8 ctype = buf->ReadByte();
5829 uint16 groupid = buf->ReadWord();
5830 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5832 if (ctype >= ROTSG_END)
continue;
5835 for (uint i = 0; i < idcount; i++) {
5840 rti->
group[ctype] = _cur.spritegroups[groupid];
5849 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5851 uint8 *airports =
AllocaM(uint8, idcount);
5852 for (uint i = 0; i < idcount; i++) {
5853 airports[i] = buf->ReadByte();
5857 uint8 cidcount = buf->ReadByte();
5858 buf->Skip(cidcount * 3);
5860 uint16 groupid = buf->ReadWord();
5861 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5863 if (_cur.
grffile->airportspec ==
nullptr) {
5864 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5868 for (uint i = 0; i < idcount; i++) {
5871 if (as ==
nullptr) {
5872 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5880 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5882 uint8 *airptiles =
AllocaM(uint8, idcount);
5883 for (uint i = 0; i < idcount; i++) {
5884 airptiles[i] = buf->ReadByte();
5888 uint8 cidcount = buf->ReadByte();
5889 buf->Skip(cidcount * 3);
5891 uint16 groupid = buf->ReadWord();
5892 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5894 if (_cur.
grffile->airtspec ==
nullptr) {
5895 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5899 for (uint i = 0; i < idcount; i++) {
5902 if (airtsp ==
nullptr) {
5903 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5913 static void FeatureMapSpriteGroup(
ByteReader *buf)
5929 uint8 feature = buf->ReadByte();
5930 uint8 idcount = buf->ReadByte();
5932 if (feature >= GSF_END) {
5933 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5941 uint16 groupid = buf->ReadWord();
5942 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5944 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5953 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5957 case GSF_ROADVEHICLES:
5960 VehicleMapSpriteGroup(buf, feature, idcount);
5964 CanalMapSpriteGroup(buf, idcount);
5968 StationMapSpriteGroup(buf, idcount);
5972 TownHouseMapSpriteGroup(buf, idcount);
5975 case GSF_INDUSTRIES:
5976 IndustryMapSpriteGroup(buf, idcount);
5979 case GSF_INDUSTRYTILES:
5980 IndustrytileMapSpriteGroup(buf, idcount);
5984 CargoMapSpriteGroup(buf, idcount);
5988 AirportMapSpriteGroup(buf, idcount);
5992 ObjectMapSpriteGroup(buf, idcount);
5996 RailTypeMapSpriteGroup(buf, idcount);
6000 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
6004 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
6007 case GSF_AIRPORTTILES:
6008 AirportTileMapSpriteGroup(buf, idcount);
6012 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
6036 bool new_scheme = _cur.
grffile->grf_version >= 7;
6038 uint8 feature = buf->ReadByte();
6039 if (feature >= GSF_END && feature != 0x48) {
6040 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
6044 uint8 lang = buf->ReadByte();
6045 uint8 num = buf->ReadByte();
6046 bool generic =
HasBit(lang, 7);
6049 id = buf->ReadWord();
6050 }
else if (feature <= GSF_AIRCRAFT) {
6051 id = buf->ReadExtendedByte();
6053 id = buf->ReadByte();
6058 uint16 endid =
id + num;
6060 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
6061 id, endid, feature, lang);
6063 for (;
id < endid && buf->HasData();
id++) {
6064 const char *name = buf->ReadString();
6065 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6069 case GSF_ROADVEHICLES:
6074 if (e ==
nullptr)
break;
6088 switch (
GB(
id, 8, 8)) {
6090 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6091 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6099 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6100 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6107 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6108 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6115 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6116 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6123 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6142 if (offset >= max_sprites) {
6143 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6144 uint orig_num = num;
6149 if (offset + num > max_sprites) {
6150 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6151 uint orig_num = num;
6152 num = std::max(max_sprites - offset, 0);
6153 return orig_num - num;
6182 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6184 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6214 uint8 type = buf->ReadByte();
6215 uint16 num = buf->ReadExtendedByte();
6216 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6222 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6239 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6250 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6257 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);
6267 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);
6279 bool dup_oneway_sprites = ((type == 0x09) && (offset + num <= SPR_ONEWAY_SLOPE_N_OFFSET));
6281 for (; num > 0; num--) {
6283 int load_index = (replace == 0 ? _cur.
spriteid++ : replace++);
6285 if (dup_oneway_sprites) {
6286 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_N_OFFSET);
6287 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_S_OFFSET);
6357 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6387 *value = _game_mode;
6421 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6430 *value = _openttd_newgrf_version;
6445 default:
return false;
6449 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6467 if (cond_val ==
nullptr) {
6471 uint32 index = *cond_val / 0x20;
6487 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6508 size_t pos = file.
GetPos();
6511 byte *preload_sprite =
nullptr;
6515 preload_sprite = MallocT<byte>(num);
6520 file.
SeekTo(pos, SEEK_SET);
6523 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6524 free(preload_sprite);
6529 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6530 if (it != _grf_line_to_action6_sprite_override.end()) {
6531 free(preload_sprite);
6532 preload_sprite = _grf_line_to_action6_sprite_override[location];
6534 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6547 param_num = buf->ReadByte();
6548 if (param_num == 0xFF)
break;
6552 param_size = buf->ReadByte();
6556 add_value =
HasBit(param_size, 7);
6557 param_size =
GB(param_size, 0, 7);
6560 offset = buf->ReadExtendedByte();
6564 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6565 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6569 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6572 for (i = 0; i < param_size && offset + i < num; i++) {
6573 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6576 if (i % 4 == 0) carry =
false;
6579 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6580 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6582 carry = new_value >= 256;
6584 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6616 uint32 cond_val = 0;
6620 uint8 param = buf->ReadByte();
6621 uint8 paramsize = buf->ReadByte();
6622 uint8 condtype = buf->ReadByte();
6629 switch (paramsize) {
6630 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6631 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6632 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6633 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6637 if (param < 0x80 && _cur.grffile->param_end <= param) {
6638 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6642 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6647 if (condtype >= 0x0B) {
6678 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6680 }
else if (param == 0x88) {
6690 if (condtype != 10 && c ==
nullptr) {
6691 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6718 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6722 uint32 param_val = GetParamVal(param, &cond_val);
6724 case 0x00: result = !!(param_val & (1 << cond_val));
6726 case 0x01: result = !(param_val & (1 << cond_val));
6728 case 0x02: result = (param_val & mask) == cond_val;
6730 case 0x03: result = (param_val & mask) != cond_val;
6732 case 0x04: result = (param_val & mask) < cond_val;
6734 case 0x05: result = (param_val & mask) > cond_val;
6736 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6741 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6745 uint8 numsprites = buf->ReadByte();
6753 if (label.label != numsprites)
continue;
6756 if (choice ==
nullptr) choice = &label;
6758 if (label.nfo_line > _cur.
nfo_line) {
6764 if (choice !=
nullptr) {
6765 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6771 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6790 uint8 grf_version = buf->ReadByte();
6791 uint32 grfid = buf->ReadDWord();
6792 const char *name = buf->ReadString();
6796 if (grf_version < 2 || grf_version > 8) {
6798 Debug(grf, 0,
"{}: NewGRF \"{}\" (GRFID {:08X}) uses GRF version {}, which is incompatible with this version of OpenTTD.", _cur.
grfconfig->
filename, name,
BSWAP32(grfid), grf_version);
6806 if (buf->HasData()) {
6807 const char *info = buf->ReadString();
6825 uint8 version = buf->ReadByte();
6826 uint32 grfid = buf->ReadDWord();
6827 const char *name = buf->ReadString();
6830 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6834 if (_cur.
grffile->grfid != grfid) {
6835 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));
6839 _cur.
grffile->grf_version = version;
6857 uint8 num_sets = buf->ReadByte();
6859 for (uint i = 0; i < num_sets; i++) {
6860 uint8 num_sprites = buf->ReadByte();
6861 uint16 first_sprite = buf->ReadWord();
6863 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6864 i, num_sprites, first_sprite
6867 for (uint j = 0; j < num_sprites; j++) {
6868 int load_index = first_sprite + j;
6874 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6884 uint8 num_sets = buf->ReadByte();
6886 for (uint i = 0; i < num_sets; i++) {
6915 STR_NEWGRF_ERROR_VERSION_NUMBER,
6916 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6917 STR_NEWGRF_ERROR_UNSET_SWITCH,
6918 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6919 STR_NEWGRF_ERROR_LOAD_BEFORE,
6920 STR_NEWGRF_ERROR_LOAD_AFTER,
6921 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6925 STR_NEWGRF_ERROR_MSG_INFO,
6926 STR_NEWGRF_ERROR_MSG_WARNING,
6927 STR_NEWGRF_ERROR_MSG_ERROR,
6928 STR_NEWGRF_ERROR_MSG_FATAL
6931 byte severity = buf->ReadByte();
6932 byte lang = buf->ReadByte();
6933 byte message_id = buf->ReadByte();
6936 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6940 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6941 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6946 if (severity >=
lengthof(sevstr)) {
6947 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6949 }
else if (severity == 3) {
6959 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6960 grfmsg(7,
"GRFLoadError: Invalid message id.");
6964 if (buf->Remaining() <= 1) {
6965 grfmsg(7,
"GRFLoadError: No message data supplied.");
6974 if (message_id == 0xFF) {
6976 if (buf->HasData()) {
6977 const char *message = buf->ReadString();
6981 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6982 error->custom_message.clear();
6985 error->message = msgstr[message_id];
6988 if (buf->HasData()) {
6989 const char *data = buf->ReadString();
6993 grfmsg(7,
"GRFLoadError: No message data supplied.");
6994 error->data.clear();
6998 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6999 uint param_number = buf->ReadByte();
7013 if (!buf->HasData())
return;
7015 const char *text = buf->ReadString();
7016 grfmsg(2,
"GRFComment: %s", text);
7022 uint8 target = buf->ReadByte();
7025 if (target < 0x80 || target == 0x9E)
return;
7039 static uint32 GetPatchVariable(uint8 param)
7049 case 0x0F:
return 0;
7065 case 0x11:
return SPR_2CCMAP_BASE;
7082 byte max_edge = std::max(log_X, log_Y);
7084 if (log_X == log_Y) {
7087 if (max_edge == log_Y)
SetBit(map_bits, 1);
7090 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7091 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7100 return SPR_SLOPES_BASE;
7111 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7117 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7130 for (uint i = start; i < num_ids; i++) {
7134 if (op == 2 || op == 3)
break;
7139 if (size == count)
break;
7142 if (size == count) {
7144 if (op == 0 || op == 3) {
7145 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7146 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7152 if (op != 4 && op != 5) {
7154 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7159 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7189 uint8 target = buf->ReadByte();
7190 uint8 oper = buf->ReadByte();
7191 uint32 src1 = buf->ReadByte();
7192 uint32 src2 = buf->ReadByte();
7195 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7204 if (target < 0x80 && target < _cur.grffile->param_end) {
7205 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7209 oper =
GB(oper, 0, 7);
7213 if (
GB(data, 0, 8) == 0xFF) {
7214 if (data == 0x0000FFFF) {
7216 src1 = GetPatchVariable(src1);
7220 uint8 feature =
GB(data, 8, 8);
7221 uint16 count =
GB(data, 16, 16);
7223 if (_cur.
stage == GLS_RESERVE) {
7224 if (feature == 0x08) {
7228 if (_cur.
spriteid + count >= 16384) {
7229 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7235 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7242 }
else if (_cur.
stage == GLS_ACTIVATION) {
7271 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7279 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7290 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7307 }
else if (src1 == 0xFE) {
7319 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7320 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7342 res = (int32)src1 * (int32)src2;
7346 if ((int32)src2 < 0) {
7347 res = src1 >> -(int32)src2;
7349 res = src1 << (src2 & 0x1F);
7354 if ((int32)src2 < 0) {
7355 res = (int32)src1 >> -(int32)src2;
7357 res = (int32)src1 << (src2 & 0x1F);
7381 res = (int32)src1 / (int32)src2;
7397 res = (int32)src1 % (int32)src2;
7401 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7430 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7441 uint32 safe_bits = 0;
7442 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7451 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7455 if (target < 0x80) {
7456 _cur.
grffile->param[target] = res;
7460 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7474 uint8 num = buf->ReadByte();
7476 for (uint i = 0; i < num; i++) {
7477 uint32 grfid = buf->ReadDWord();
7499 uint8 num = buf->ReadByte();
7501 for (uint i = 0; i < num; i++) {
7502 uint32 grfid = buf->ReadDWord();
7506 if (file !=
nullptr && file != _cur.
grfconfig) {
7524 uint32 grfid = _cur.
grffile->grfid;
7528 byte id = buf->ReadByte();
7529 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7534 bool new_scheme = _cur.
grffile->grf_version >= 7;
7536 byte lang = buf->ReadByte();
7538 byte nb_gen = townname->nb_gen;
7542 const char *name = buf->ReadString();
7545 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7547 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7549 lang = buf->ReadByte();
7550 }
while (lang != 0);
7551 townname->id[nb_gen] = id;
7555 byte nb = buf->ReadByte();
7556 grfmsg(6,
"FeatureTownName: %u parts", nb);
7558 townname->nbparts[id] = nb;
7559 townname->partlist[id] = CallocT<NamePartList>(nb);
7561 for (
int i = 0; i < nb; i++) {
7562 byte nbtext = buf->ReadByte();
7563 townname->partlist[id][i].bitstart = buf->ReadByte();
7564 townname->partlist[id][i].bitcount = buf->ReadByte();
7565 townname->partlist[id][i].maxprob = 0;
7566 townname->partlist[id][i].partcount = nbtext;
7567 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7568 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);
7570 for (
int j = 0; j < nbtext; j++) {
7571 byte prob = buf->ReadByte();
7574 byte ref_id = buf->ReadByte();
7576 if (townname->nbparts[ref_id] == 0) {
7577 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7578 DelGRFTownName(grfid);
7583 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7584 townname->partlist[id][i].parts[j].data.
id = ref_id;
7586 const char *text = buf->ReadString();
7588 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7590 townname->partlist[id][i].parts[j].
prob = prob;
7591 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7593 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7605 byte nfo_label = buf->ReadByte();
7609 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", nfo_label);
7623 if (file ==
nullptr || file->sound_offset == 0) {
7624 grfmsg(1,
"ImportGRFSound: Source file not available");
7628 if (sound_id >= file->num_sounds) {
7629 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7633 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7635 *sound = *GetSound(file->sound_offset + sound_id);
7638 sound->volume = 128;
7639 sound->priority = 0;
7650 sound->volume = 0x80;
7651 sound->priority = 0;
7653 if (offs != SIZE_MAX) {
7655 sound->file = _cur.
file;
7656 sound->file_offset = offs;
7668 uint16 num = buf->ReadWord();
7669 if (num == 0)
return;
7672 if (_cur.
grffile->sound_offset == 0) {
7673 _cur.
grffile->sound_offset = GetNumSounds();
7674 _cur.
grffile->num_sounds = num;
7677 sound = GetSound(_cur.
grffile->sound_offset);
7682 for (
int i = 0; i < num; i++) {
7687 bool invalid = i >= _cur.
grffile->num_sounds;
7689 size_t offs = file.
GetPos();
7694 if (grf_container_version >= 2 && type == 0xFD) {
7697 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7699 }
else if (len != 4) {
7700 grfmsg(1,
"GRFSound: Invalid sprite section import");
7710 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7717 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7725 if (_cur.
stage == GLS_INIT) {
7726 if (grf_container_version >= 2) {
7727 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7736 if (_cur.
stage == GLS_ACTIVATION) {
7739 if (file.
ReadByte() != 0)
grfmsg(1,
"GRFSound: Import type mismatch");
7747 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7776 uint8 num_def = buf->ReadByte();
7778 for (uint i = 0; i < num_def; i++) {
7780 uint8 num_char = buf->ReadByte();
7781 uint16 base_char = buf->ReadWord();
7783 if (size >= FS_END) {
7784 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7787 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7789 for (uint c = 0; c < num_char; c++) {
7807 uint8 num_def = buf->ReadByte();
7809 for (uint i = 0; i < num_def; i++) {
7833 uint32 grfid = buf->ReadDWord();
7836 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7845 error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7855 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7856 byte num_strings = buf->ReadByte();
7857 uint16 first_id = buf->ReadWord();
7859 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7860 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7864 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7865 const char *
string = buf->ReadString();
7868 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7872 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7901 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7913 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7916 char data = buf->ReadByte();
7924 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7939 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7942 char data = buf->ReadByte();
7948 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7961 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7974 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7979 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
8010 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
8017 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
8027 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
8029 }
else if (len != 8) {
8030 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
8033 uint32 min_value = buf->ReadDWord();
8034 uint32 max_value = buf->ReadDWord();
8035 if (min_value <= max_value) {
8039 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
8048 if (len < 1 || len > 3) {
8049 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
8052 byte param_nr = buf->ReadByte();
8054 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8070 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8106 this->handler.data = handler;
8118 this->handler.text = handler;
8130 this->handler.call_handler =
true;
8131 this->handler.u.branch = handler;
8143 this->handler.call_handler =
false;
8144 this->handler.u.subtags =
subtags;
8173 byte type = buf->ReadByte();
8175 uint32
id = buf->ReadDWord();
8177 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8179 type = buf->ReadByte();
8183 byte langid = buf->ReadByte();
8184 const char *name_string = buf->ReadString();
8195 type = buf->ReadByte();
8220 byte type = buf->ReadByte();
8222 uint32
id = buf->ReadDWord();
8224 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8226 type = buf->ReadByte();
8239 type = buf->ReadByte();
8276 byte new_type = buf->ReadByte();
8277 while (new_type != 0) {
8280 new_type = buf->ReadByte();
8291 uint16 size = buf->ReadWord();
8315 while ((tag = &subtags[i++])->type != 0) {
8318 default: NOT_REACHED();
8321 byte langid = buf->ReadByte();
8322 return tag->handler.
text(langid, buf->ReadString());
8326 size_t len = buf->ReadWord();
8327 if (buf->Remaining() < len)
return false;
8328 return tag->handler.
data(len, buf);
8333 return tag->handler.u.branch(buf);
8339 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8351 byte type = buf->ReadByte();
8353 uint32
id = buf->ReadDWord();
8354 if (!
HandleNode(type,
id, buf, subtags))
return false;
8355 type = buf->ReadByte();
8477 if (stations ==
nullptr)
continue;
8479 if (stations[i] ==
nullptr)
continue;
8496 HouseSpec **&housespec = file->housespec;
8497 if (housespec ==
nullptr)
continue;
8503 housespec =
nullptr;
8512 if (aslist !=
nullptr) {
8516 if (as !=
nullptr) {
8518 for (
int j = 0; j < as->
num_table; j++) {
8530 file->airportspec =
nullptr;
8534 if (airporttilespec !=
nullptr) {
8536 free(airporttilespec[i]);
8538 free(airporttilespec);
8539 airporttilespec =
nullptr;
8553 if (industryspec !=
nullptr) {
8560 industryspec =
nullptr;
8563 if (indtspec ==
nullptr)
continue;
8578 if (objectspec ==
nullptr)
continue;
8580 free(objectspec[i]);
8584 objectspec =
nullptr;
8616 CleanUpGRFTownNames();
8660 ObjectClass::Reset();
8665 StationClass::Reset();
8669 AirportClass::Reset();
8698 _grf_id_overrides.clear();
8700 InitializeSoundPool();
8748 if (newfile !=
nullptr) {
8754 newfile =
new GRFFile(config);
8772 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8777 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8784 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8788 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8804 free(this->filename);
8814 CargoTypes original_known_cargoes = 0;
8815 for (
int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
8823 bool only_defaultcargo;
8826 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
8829 static constexpr
byte T = 1 << LT_TEMPERATE;
8830 static constexpr
byte A = 1 << LT_ARCTIC;
8831 static constexpr
byte S = 1 << LT_TROPIC;
8832 static constexpr
byte Y = 1 << LT_TOYLAND;
8833 static const struct DefaultRefitMasks {
8836 CargoTypes cargo_allowed;
8837 CargoTypes cargo_disallowed;
8838 } _default_refit_masks[] = {
8840 {T | A | S , CT_MAIL,
CC_MAIL, 0},
8843 {T | A , CT_COAL,
CC_BULK, 0},
8844 { S , CT_COPPER_ORE,
CC_BULK, 0},
8859 switch (ei->cargo_type) {
8863 _gted[engine].cargo_disallowed = 0;
8868 _gted[engine].cargo_disallowed = 0;
8887 _gted[engine].cargo_disallowed = 0;
8890 for (
const auto &drm : _default_refit_masks) {
8892 if (drm.cargo_type != ei->cargo_type)
continue;
8894 _gted[engine].cargo_allowed = drm.cargo_allowed;
8895 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
8912 CargoTypes mask = 0;
8913 CargoTypes not_mask = 0;
8914 CargoTypes xor_mask = ei->refit_mask;
8920 if (
_gted[engine].cargo_allowed != 0) {
8923 if (
_gted[engine].cargo_allowed & cs->classes)
SetBit(mask, cs->Index());
8924 if (
_gted[engine].cargo_disallowed & cs->classes)
SetBit(not_mask, cs->Index());
8928 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8946 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8948 const uint8 *cargo_map_for_first_refittable =
nullptr;
8951 if (file ==
nullptr) file = e->
GetGRF();
8952 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8953 cargo_map_for_first_refittable = file->
cargo_map;
8957 if (cargo_map_for_first_refittable !=
nullptr) {
8959 byte best_local_slot = 0xFF;
8961 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8962 if (local_slot < best_local_slot) {
8963 best_local_slot = local_slot;
8964 ei->cargo_type = cargo_type;
8986 for (uint i = 0; i < CF_END; i++) {
8998 if (e->
GetGRF() ==
nullptr) {
9001 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
9037 default: NOT_REACHED();
9051 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
9052 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
9076 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
9086 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs->
grf_prop.
local_id);
9094 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9101 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs->
grf_prop.
local_id);
9120 if (hs ==
nullptr || !hs->
enabled)
continue;
9125 if (min_year == 0)
return;
9129 if (hs ==
nullptr || !hs->
enabled)
continue;
9153 HouseSpec **&housespec = file->housespec;
9154 if (housespec ==
nullptr)
continue;
9159 if (hs ==
nullptr)
continue;
9217 if (industryspec !=
nullptr) {
9221 if (indsp !=
nullptr && indsp->
enabled) {
9227 if (strid != STR_UNDEFINED) indsp->
name = strid;
9230 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9245 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9253 if (indtspec !=
nullptr) {
9256 if (indtsp !=
nullptr) {
9257 _industile_mngr.SetEntitySpec(indtsp);
9266 for (uint i = 0; i < 3; i++) {
9271 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9285 if (objectspec !=
nullptr) {
9287 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9304 if (airportspec !=
nullptr) {
9306 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9307 _airport_mngr.SetEntitySpec(airportspec[i]);
9313 if (airporttilespec !=
nullptr) {
9315 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9316 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9329 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9343 static const SpecialSpriteHandler handlers[][GLS_END] = {
9344 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9345 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9346 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9347 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9348 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9349 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9350 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9351 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9352 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9353 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9354 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9355 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9356 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9358 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9361 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9364 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9369 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9370 if (it == _grf_line_to_action6_sprite_override.end()) {
9376 buf = _grf_line_to_action6_sprite_override[location];
9377 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9387 byte action = bufp->ReadByte();
9389 if (action == 0xFF) {
9390 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9391 }
else if (action == 0xFE) {
9392 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9393 }
else if (action >=
lengthof(handlers)) {
9394 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9395 }
else if (handlers[action][stage] ==
nullptr) {
9396 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9398 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9399 handlers[action][stage](bufp);
9402 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9418 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config->
filename);
9421 if (grf_container_version == 0) {
9422 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9426 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9432 if (grf_container_version >= 2) file.
ReadDword();
9435 if (grf_container_version >= 2) {
9437 byte compression = file.
ReadByte();
9438 if (compression != 0) {
9439 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9448 if (num == 4 && file.
ReadByte() == 0xFF) {
9451 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9459 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
9465 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9476 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9477 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9481 if (grf_container_version >= 2 && type == 0xFD) {
9504 const char *filename = config->
filename;
9515 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9517 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9524 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
9578 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9579 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9580 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9581 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9582 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9583 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9594 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9598 int *grf_overrides =
AllocaM(
int, num_grfs);
9599 for (
int i = 0; i < num_grfs; i++) {
9600 grf_overrides[i] = -1;
9603 uint32
override = _grf_id_overrides[source->grfid];
9604 if (
override == 0)
continue;
9607 if (dest ==
nullptr)
continue;
9610 assert(grf_overrides[i] >= 0);
9614 for (
int i = 0; i < num_grfs; i++) {
9615 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9623 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9626 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
9632 for (
int i = num_grfs - 1; i >= 0; i--) {
9633 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9641 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9644 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
9650 for (
int i = 0; i < num_grfs; i++) {
9651 if (grf_overrides[i] < 0)
continue;
9659 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9660 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9662 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
9670 if (file->grf_version >= 8)
continue;
9671 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9672 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9674 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9677 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9684 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9685 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9686 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9688 price_base_multipliers[p] = 0;
9693 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file->
filename, p);
9695 price_base_multipliers[p] = 0;
9697 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file->
filename, p);
9712 _string_to_grf_mapping.clear();
9715 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9718 _grf_line_to_action6_sprite_override.clear();
9781 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9790 if (
_gted[e->
index].roadtramtype < list->size())
9792 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9821 _grm_sprites.clear();
9869 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9876 if (stage == GLS_RESERVE) {
9877 static const uint32 overrides[][2] = {
9878 { 0x44442202, 0x44440111 },
9879 { 0x6D620402, 0x6D620401 },
9880 { 0x4D656f20, 0x4D656F17 },
9882 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9888 uint num_non_static = 0;
9897 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->
filename);
9906 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9908 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9917 if (stage == GLS_RESERVE) {
9919 }
else if (stage == GLS_ACTIVATION) {
9924 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur.
spriteid);