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();
1364 for (
int i = 0; i < numinfo; i++) {
1375 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1383 rvi->running_cost = buf->ReadByte();
1391 uint8 spriteid = buf->ReadByte();
1392 uint8 orig_spriteid = spriteid;
1395 if (spriteid == 0xFF) spriteid = 0xFD;
1397 if (spriteid < 0xFD) spriteid >>= 1;
1399 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1400 rvi->image_index = spriteid;
1402 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1403 rvi->image_index = 0;
1409 rvi->capacity = buf->ReadByte();
1414 uint8 ctype = buf->ReadByte();
1416 if (ctype == 0xFF) {
1419 }
else if (_cur.
grffile->grf_version >= 8) {
1424 ei->cargo_type = ctype;
1427 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1433 rvi->cost_factor = buf->ReadByte();
1441 rvi->
power = buf->ReadByte();
1445 rvi->
weight = buf->ReadByte();
1453 uint32 mask = buf->ReadDWord();
1473 ei->refit_cost = buf->ReadByte();
1486 _gted[e->
index].cargo_allowed = buf->ReadWord();
1492 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1524 uint8 count = buf->ReadByte();
1570 for (
int i = 0; i < numinfo; i++) {
1579 uint8 spriteid = buf->ReadByte();
1580 uint8 orig_spriteid = spriteid;
1583 if (spriteid == 0xFF) spriteid = 0xFD;
1585 if (spriteid < 0xFD) spriteid >>= 1;
1587 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1588 svi->image_index = spriteid;
1590 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1591 svi->image_index = 0;
1601 svi->cost_factor = buf->ReadByte();
1610 uint8 ctype = buf->ReadByte();
1612 if (ctype == 0xFF) {
1615 }
else if (_cur.
grffile->grf_version >= 8) {
1620 ei->cargo_type = ctype;
1623 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1629 svi->capacity = buf->ReadWord();
1633 svi->running_cost = buf->ReadByte();
1641 uint32 mask = buf->ReadDWord();
1653 ei->refit_cost = buf->ReadByte();
1674 _gted[e->
index].cargo_allowed = buf->ReadWord();
1680 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1708 uint8 count = buf->ReadByte();
1754 for (
int i = 0; i < numinfo; i++) {
1763 uint8 spriteid = buf->ReadByte();
1764 uint8 orig_spriteid = spriteid;
1767 if (spriteid == 0xFF) spriteid = 0xFD;
1769 if (spriteid < 0xFD) spriteid >>= 1;
1771 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1772 avi->image_index = spriteid;
1774 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1775 avi->image_index = 0;
1781 if (buf->ReadByte() == 0) {
1789 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1793 avi->cost_factor = buf->ReadByte();
1797 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1801 avi->acceleration = buf->ReadByte();
1805 avi->running_cost = buf->ReadByte();
1821 uint32 mask = buf->ReadDWord();
1833 ei->refit_cost = buf->ReadByte();
1846 _gted[e->
index].cargo_allowed = buf->ReadWord();
1852 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1870 uint8 count = buf->ReadByte();
1928 for (
int i = 0; i < numinfo; i++) {
1932 if (statspec ==
nullptr && prop != 0x08) {
1933 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1945 uint32 classid = buf->ReadDWord();
1946 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1951 uint16 tiles = buf->ReadExtendedByte();
1955 for (uint t = 0; t < tiles; t++) {
1959 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1962 dts->
Clone(&_station_display_datas_rail[t % 8]);
1970 static std::vector<DrawTileSeqStruct> tmp_layout;
1977 dtss.
delta_x = buf->ReadByte();
1979 dtss.delta_y = buf->ReadByte();
1980 dtss.
delta_z = buf->ReadByte();
1981 dtss.size_x = buf->ReadByte();
1982 dtss.size_y = buf->ReadByte();
1983 dtss.size_z = buf->ReadByte();
1989 dts->
Clone(tmp_layout.data());
1994 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
2001 byte srcid = buf->ReadByte();
2004 if (srcstatspec ==
nullptr) {
2005 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
2012 for (
const auto &it : srcstatspec->
renderdata) {
2032 while (buf->HasData()) {
2033 byte length = buf->ReadByte();
2034 byte number = buf->ReadByte();
2036 if (length == 0 || number == 0)
break;
2038 if (statspec->
layouts.size() < length) statspec->
layouts.resize(length);
2039 if (statspec->
layouts[length - 1].size() < number) statspec->
layouts[length - 1].resize(number);
2041 const byte *layout = buf->ReadBytes(length * number);
2042 statspec->
layouts[length - 1][number - 1].assign(layout, layout + length * number);
2045 for (
auto &tile : statspec->
layouts[length - 1][number - 1]) {
2046 if ((tile & 6) != tile) {
2047 grfmsg(1,
"StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
2055 byte srcid = buf->ReadByte();
2058 if (srcstatspec ==
nullptr) {
2059 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2072 statspec->
pylons = buf->ReadByte();
2076 if (_cur.
grffile->grf_version >= 7) {
2084 statspec->
flags = buf->ReadByte();
2088 statspec->
wires = buf->ReadByte();
2092 statspec->
blocked = buf->ReadByte();
2096 statspec->animation.
frames = buf->ReadByte();
2097 statspec->animation.
status = buf->ReadByte();
2101 statspec->animation.
speed = buf->ReadByte();
2105 statspec->animation.
triggers = buf->ReadWord();
2109 uint16 tiles = buf->ReadExtendedByte();
2113 for (uint t = 0; t < tiles; t++) {
2115 uint num_building_sprites = buf->ReadByte();
2122 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
2149 if (
id + numinfo > CF_END) {
2150 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2154 for (
int i = 0; i < numinfo; i++) {
2163 cp->
flags = buf->ReadByte();
2188 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2192 for (
int i = 0; i < numinfo; i++) {
2198 byte year = buf->ReadByte();
2213 bridge->
price = buf->ReadByte();
2217 bridge->
speed = buf->ReadWord();
2218 if (bridge->
speed == 0) bridge->
speed = UINT16_MAX;
2222 byte tableid = buf->ReadByte();
2223 byte numtables = buf->ReadByte();
2230 for (; numtables-- != 0; tableid++) {
2232 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2233 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2238 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2241 for (
byte sprite = 0; sprite < 32; sprite++) {
2255 bridge->
flags = buf->ReadByte();
2264 if (newone != STR_UNDEFINED) bridge->
material = newone;
2271 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2276 bridge->
price = buf->ReadWord();
2333 for (uint j = 0; j < 4; j++) buf->ReadByte();
2337 byte count = buf->ReadByte();
2338 for (
byte j = 0; j < count; j++) buf->ReadByte();
2343 buf->Skip(buf->ReadByte() * 2);
2366 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2371 if (_cur.
grffile->housespec ==
nullptr) {
2375 for (
int i = 0; i < numinfo; i++) {
2378 if (prop != 0x08 && housespec ==
nullptr) {
2381 if (cir > ret) ret = cir;
2388 byte subs_id = buf->ReadByte();
2390 if (subs_id == 0xFF) {
2393 HouseSpec::Get(hid + i)->
enabled =
false;
2397 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2402 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2406 MemCpyT(housespec, HouseSpec::Get(subs_id));
2410 housespec->
grf_prop.subst_id = subs_id;
2432 uint16 years = buf->ReadWord();
2452 int8 goods = buf->ReadByte();
2488 byte override = buf->ReadByte();
2492 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2496 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2505 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2527 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2535 uint32 cargotypes = buf->ReadDWord();
2538 if (cargotypes == 0xFFFFFFFF)
break;
2540 for (uint j = 0; j < 3; j++) {
2542 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2560 byte count = buf->ReadByte();
2561 for (
byte j = 0; j < count; j++) {
2569 housespec->
min_year = buf->ReadWord();
2573 housespec->
max_year = buf->ReadWord();
2577 uint count = buf->ReadByte();
2580 error->param_value[1] = prop;
2629 template <
typename T>
2633 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2637 translation_table.clear();
2638 for (
int i = 0; i < numinfo; i++) {
2639 uint32 item = buf->ReadDWord();
2640 translation_table.push_back(
BSWAP32(item));
2655 for (
int i = 0; i < 4; i++) output[i] = reader->ReadByte();
2659 return std::string(output);
2692 for (
int i = 0; i < numinfo; i++) {
2695 int factor = buf->ReadByte();
2696 uint price = gvid + i;
2698 if (price < PR_END) {
2701 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2710 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2718 uint32 rate = buf->ReadDWord();
2726 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2733 uint16 options = buf->ReadWord();
2742 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2754 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2766 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2773 Year year_euro = buf->ReadWord();
2778 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2785 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2787 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2793 table[i][j] = buf->ReadByte();
2794 if (_cur.
grffile->grf_version >= 8) {
2797 if (table[i][j] >= 128) {
2819 uint curidx = gvid + i;
2821 if (lang ==
nullptr) {
2822 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2827 while (buf->ReadByte() != 0) {
2837 uint plural_form = buf->ReadByte();
2838 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2839 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2846 byte newgrf_id = buf->ReadByte();
2847 while (newgrf_id != 0) {
2848 const char *name = buf->ReadString();
2863 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2870 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2875 newgrf_id = buf->ReadByte();
2911 for (
int i = 0; i < numinfo; i++) {
2935 uint32 s = buf->ReadDWord();
2936 uint32 t = buf->ReadDWord();
2943 while (buf->ReadByte() != 0) {
2971 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2975 for (
int i = 0; i < numinfo; i++) {
2980 cs->
bitnum = buf->ReadByte();
3018 cs->
sprite = buf->ReadWord();
3022 cs->
weight = buf->ReadByte();
3026 cs->transit_days[0] = buf->ReadByte();
3030 cs->transit_days[1] = buf->ReadByte();
3038 cs->rating_colour = buf->ReadByte();
3042 cs->legend_colour = buf->ReadByte();
3050 cs->
classes = buf->ReadWord();
3054 cs->
label = buf->ReadDWord();
3059 uint8 substitute_type = buf->ReadByte();
3061 switch (substitute_type) {
3068 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3084 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3109 if (_cur.
grffile->sound_offset == 0) {
3110 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3115 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3119 for (
int i = 0; i < numinfo; i++) {
3124 sound->volume = buf->ReadByte();
3128 sound->priority = buf->ReadByte();
3132 SoundID orig_sound = buf->ReadByte();
3137 SoundEntry *old_sound = GetSound(orig_sound);
3140 *old_sound = *sound;
3182 buf->Skip(buf->ReadByte() * 2);
3210 if (_cur.
grffile->indtspec ==
nullptr) {
3214 for (
int i = 0; i < numinfo; i++) {
3217 if (prop != 0x08 && tsp ==
nullptr) {
3219 if (cir > ret) ret = cir;
3226 byte subs_id = buf->ReadByte();
3230 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3235 if (*tilespec ==
nullptr) {
3236 *tilespec = CallocT<IndustryTileSpec>(1);
3239 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3257 byte ovrid = buf->ReadByte();
3261 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3265 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3272 uint16 acctp = buf->ReadWord();
3304 byte num_cargoes = buf->ReadByte();
3307 error->param_value[1] = prop;
3311 if (i < num_cargoes) {
3378 byte num_table = buf->ReadByte();
3379 for (
byte j = 0; j < num_table; j++) {
3380 for (uint k = 0;; k++) {
3381 byte x = buf->ReadByte();
3382 if (x == 0xFE && k == 0) {
3388 byte y = buf->ReadByte();
3389 if (x == 0 && y == 0x80)
break;
3391 byte gfx = buf->ReadByte();
3392 if (gfx == 0xFE) buf->ReadWord();
3399 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3406 buf->Skip(buf->ReadByte());
3410 int num_inputs = buf->ReadByte();
3411 int num_outputs = buf->ReadByte();
3412 buf->Skip(num_inputs * num_outputs * 2);
3430 const size_t size = layout.size();
3431 if (size == 0)
return false;
3433 for (
size_t i = 0; i < size - 1; i++) {
3434 for (
size_t j = i + 1; j < size; j++) {
3435 if (layout[i].ti.x == layout[j].ti.x &&
3436 layout[i].ti.y == layout[j].ti.y) {
3442 bool have_regular_tile =
false;
3443 for (
size_t i = 0; i < size; i++) {
3445 have_regular_tile =
true;
3450 return have_regular_tile;
3471 if (_cur.
grffile->industryspec ==
nullptr) {
3475 for (
int i = 0; i < numinfo; i++) {
3478 if (prop != 0x08 && indsp ==
nullptr) {
3480 if (cir > ret) ret = cir;
3487 byte subs_id = buf->ReadByte();
3489 if (subs_id == 0xFF) {
3492 _industry_specs[indid + i].
enabled =
false;
3496 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3503 if (*indspec ==
nullptr) {
3507 *indsp = _origin_industry_specs[subs_id];
3510 indsp->
grf_prop.subst_id = subs_id;
3520 byte ovrid = buf->ReadByte();
3524 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3528 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3533 byte new_num_layouts = buf->ReadByte();
3534 uint32 definition_size = buf->ReadDWord();
3535 uint32 bytes_read = 0;
3536 std::vector<IndustryTileLayout> new_layouts;
3539 for (
byte j = 0; j < new_num_layouts; j++) {
3542 for (uint k = 0;; k++) {
3543 if (bytes_read >= definition_size) {
3544 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3546 definition_size = UINT32_MAX;
3552 it.ti.
x = buf->ReadByte();
3555 if (it.ti.
x == 0xFE && k == 0) {
3557 IndustryType type = buf->ReadByte();
3558 byte laynbr = buf->ReadByte();
3561 if (type >=
lengthof(_origin_industry_specs)) {
3562 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3566 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3567 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3571 layout = _origin_industry_specs[type].layouts[laynbr];
3575 it.ti.
y = buf->ReadByte();
3578 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3584 it.gfx = buf->ReadByte();
3587 if (it.gfx == 0xFE) {
3589 int local_tile_id = buf->ReadWord();
3593 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3596 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3602 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3603 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3612 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3618 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3622 new_layouts.push_back(layout);
3652 for (
byte j = 0; j < 2; j++) {
3658 for (
byte j = 0; j < 3; j++) {
3666 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3679 sounds[j] = buf->ReadByte();
3695 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3721 uint32 multiples = buf->ReadDWord();
3737 byte aflag = buf->ReadByte();
3747 uint16 str = buf->ReadWord();
3757 byte num_cargoes = buf->ReadByte();
3758 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3760 error->param_value[1] = prop;
3763 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3764 if (i < num_cargoes) {
3766 indsp->produced_cargo[i] = cargo;
3775 byte num_cargoes = buf->ReadByte();
3778 error->param_value[1] = prop;
3782 if (i < num_cargoes) {
3793 byte num_cargoes = buf->ReadByte();
3794 if (num_cargoes >
lengthof(indsp->production_rate)) {
3796 error->param_value[1] = prop;
3799 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3800 if (i < num_cargoes) {
3801 indsp->production_rate[i] = buf->ReadByte();
3803 indsp->production_rate[i] = 0;
3810 byte num_inputs = buf->ReadByte();
3811 byte num_outputs = buf->ReadByte();
3814 error->param_value[1] = prop;
3818 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3820 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3844 for (
int i = 0; i < as->
num_table; i++) {
3849 }
while ((++it)->ti.x != -0x80);
3850 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3853 as->
table = table_list;
3875 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3880 if (_cur.
grffile->airportspec ==
nullptr) {
3884 for (
int i = 0; i < numinfo; i++) {
3887 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3888 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3894 byte subs_id = buf->ReadByte();
3896 if (subs_id == 0xFF) {
3903 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3911 if (*spec ==
nullptr) {
3912 *spec = MallocT<AirportSpec>(1);
3921 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3933 uint32 defsize = buf->ReadDWord();
3939 for (
byte j = 0; j < as->
num_table; j++) {
3941 for (
int k = 0;; k++) {
3942 att[k].
ti.
x = buf->ReadByte();
3943 att[k].
ti.
y = buf->ReadByte();
3945 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3948 att[k].
ti.
x = -0x80;
3957 att[k].
gfx = buf->ReadByte();
3959 if (att[k].gfx == 0xFE) {
3961 int local_tile_id = buf->ReadWord();
3964 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3967 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3970 att[k].
gfx = tempid;
3972 }
else if (att[k].gfx == 0xFF) {
3973 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3974 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3985 tile_table[j] = CallocT<AirportTileTable>(size);
3986 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3989 for (
int j = 0; j < old_num_table; j++) {
3995 as->
table = tile_table;
3998 for (
int i = 0; i < as->
num_table; i++) {
3999 free(tile_table[i]);
4105 if (_cur.
grffile->objectspec ==
nullptr) {
4109 for (
int i = 0; i < numinfo; i++) {
4112 if (prop != 0x08 && spec ==
nullptr) {
4115 if (cir > ret) ret = cir;
4124 if (*ospec ==
nullptr) {
4125 *ospec = CallocT<ObjectSpec>(1);
4126 (*ospec)->views = 1;
4131 uint32 classid = buf->ReadDWord();
4132 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4133 (*ospec)->enabled =
true;
4148 spec->
climate = buf->ReadByte();
4152 spec->
size = buf->ReadByte();
4153 if (
GB(spec->
size, 0, 4) == 0 ||
GB(spec->
size, 4, 4) == 0) {
4154 grfmsg(0,
"ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->
size,
id + i);
4199 spec->
height = buf->ReadByte();
4203 spec->
views = buf->ReadByte();
4205 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4238 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4242 for (
int i = 0; i < numinfo; i++) {
4255 uint16 str = buf->ReadWord();
4257 if (_cur.
grffile->grf_version < 8) {
4287 int n = buf->ReadByte();
4288 for (
int j = 0; j != n; j++) {
4289 RailTypeLabel label = buf->ReadDWord();
4349 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4368 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4372 for (
int i = 0; i < numinfo; i++) {
4376 RailTypeLabel rtl = buf->ReadDWord();
4385 _cur.
grffile->railtype_map[
id + i] = rt;
4403 int n = buf->ReadByte();
4404 for (
int j = 0; j != n; j++) {
4409 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4416 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4457 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4461 for (
int i = 0; i < numinfo; i++) {
4474 uint16 str = buf->ReadWord();
4501 int n = buf->ReadByte();
4502 for (
int j = 0; j != n; j++) {
4503 RoadTypeLabel label = buf->ReadDWord();
4550 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4581 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4585 for (
int i = 0; i < numinfo; i++) {
4588 RoadTypeLabel rtl = buf->ReadDWord();
4595 }
else if (GetRoadTramType(rt) != rtt) {
4596 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4600 type_map[
id + i] = rt;
4617 int n = buf->ReadByte();
4618 for (
int j = 0; j != n; j++) {
4623 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4629 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4653 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4658 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4671 if (_cur.
grffile->airtspec ==
nullptr) {
4675 for (
int i = 0; i < numinfo; i++) {
4678 if (prop != 0x08 && tsp ==
nullptr) {
4679 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4686 byte subs_id = buf->ReadByte();
4690 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4695 if (*tilespec ==
nullptr) {
4696 *tilespec = CallocT<AirportTileSpec>(1);
4713 byte override = buf->ReadByte();
4717 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4721 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4751 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4754 default: NOT_REACHED();
4764 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4768 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4781 static void FeatureChangeInfo(
ByteReader *buf)
4794 static const VCI_Handler handler[] = {
4812 AirportTilesChangeInfo,
4816 static_assert(GSF_END ==
lengthof(handler));
4818 uint8 feature = buf->ReadByte();
4819 uint8 numprops = buf->ReadByte();
4820 uint numinfo = buf->ReadByte();
4821 uint engine = buf->ReadExtendedByte();
4823 if (feature >= GSF_END) {
4824 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4828 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4829 feature, numprops, engine, numinfo);
4831 if (handler[feature] ==
nullptr) {
4832 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4839 while (numprops-- && buf->HasData()) {
4840 uint8 prop = buf->ReadByte();
4843 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4850 uint8 feature = buf->ReadByte();
4851 uint8 numprops = buf->ReadByte();
4852 uint numinfo = buf->ReadByte();
4853 buf->ReadExtendedByte();
4855 if (feature == GSF_BRIDGES && numprops == 1) {
4856 uint8 prop = buf->ReadByte();
4859 if (prop == 0x0D)
return;
4860 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4861 uint8 prop = buf->ReadByte();
4864 bool is_safe =
true;
4865 for (uint i = 0; i < numinfo; i++) {
4866 uint32 s = buf->ReadDWord();
4874 if (is_safe)
return;
4885 static void ReserveChangeInfo(
ByteReader *buf)
4887 uint8 feature = buf->ReadByte();
4889 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4891 uint8 numprops = buf->ReadByte();
4892 uint8 numinfo = buf->ReadByte();
4893 uint8 index = buf->ReadExtendedByte();
4895 while (numprops-- && buf->HasData()) {
4896 uint8 prop = buf->ReadByte();
4900 default: NOT_REACHED();
4906 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4910 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4914 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4918 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4922 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4943 uint8 feature = buf->ReadByte();
4944 uint16 num_sets = buf->ReadByte();
4945 uint16 first_set = 0;
4947 if (num_sets == 0 && buf->HasData(3)) {
4950 first_set = buf->ReadExtendedByte();
4951 num_sets = buf->ReadExtendedByte();
4953 uint16 num_ents = buf->ReadExtendedByte();
4955 if (feature >= GSF_END) {
4957 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4963 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4964 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4967 for (
int i = 0; i < num_sets * num_ents; i++) {
4977 uint16 num_sets = buf->ReadByte();
4979 if (num_sets == 0 && buf->HasData(3)) {
4982 buf->ReadExtendedByte();
4983 num_sets = buf->ReadExtendedByte();
4985 uint16 num_ents = buf->ReadExtendedByte();
4994 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4996 if (
HasBit(groupid, 15)) {
5001 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5002 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
5006 return _cur.spritegroups[groupid];
5019 if (
HasBit(spriteid, 15)) {
5025 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
5030 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
5033 assert(spriteset_start + num_sprites <= _cur.
spriteid);
5054 uint8 feature = buf->ReadByte();
5055 if (feature >= GSF_END) {
5056 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5060 uint8 setid = buf->ReadByte();
5061 uint8 type = buf->ReadByte();
5085 switch (
GB(type, 2, 2)) {
5086 default: NOT_REACHED();
5087 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5088 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5089 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5099 adjust.variable = buf->ReadByte();
5100 if (adjust.variable == 0x7E) {
5102 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5107 varadjust = buf->ReadByte();
5108 adjust.shift_num =
GB(varadjust, 0, 5);
5109 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5110 adjust.and_mask = buf->ReadVarSize(varsize);
5112 if (adjust.type != DSGA_TYPE_NONE) {
5113 adjust.add_val = buf->ReadVarSize(varsize);
5114 adjust.divmod_val = buf->ReadVarSize(varsize);
5117 adjust.divmod_val = 0;
5121 }
while (
HasBit(varadjust, 5));
5123 std::vector<DeterministicSpriteGroupRange> ranges;
5124 ranges.resize(buf->ReadByte());
5125 for (uint i = 0; i < ranges.size(); i++) {
5126 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5127 ranges[i].low = buf->ReadVarSize(varsize);
5128 ranges[i].high = buf->ReadVarSize(varsize);
5131 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5132 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5134 group->calculated_result = ranges.size() == 0;
5137 std::vector<uint32> bounds;
5138 for (uint i = 0; i < ranges.size(); i++) {
5139 bounds.push_back(ranges[i].low);
5140 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5142 std::sort(bounds.begin(), bounds.end());
5143 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5145 std::vector<const SpriteGroup *> target;
5146 for (uint j = 0; j < bounds.size(); ++j) {
5147 uint32 v = bounds[j];
5149 for (uint i = 0; i < ranges.size(); i++) {
5150 if (ranges[i].low <= v && v <= ranges[i].high) {
5151 t = ranges[i].group;
5155 target.push_back(t);
5157 assert(target.size() == bounds.size());
5159 for (uint j = 0; j < bounds.size(); ) {
5160 if (target[j] != group->default_group) {
5162 r.group = target[j];
5164 while (j < bounds.size() && target[j] == r.group) {
5167 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5189 group->count = buf->ReadByte();
5192 uint8 triggers = buf->ReadByte();
5193 group->triggers =
GB(triggers, 0, 7);
5194 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5197 byte num_groups = buf->ReadByte();
5199 grfmsg(1,
"NewSpriteGroup: Random Action 2 nrand should be power of 2");
5202 for (uint i = 0; i < num_groups; i++) {
5203 group->
groups.push_back(GetGroupFromGroupID(setid, type, buf->ReadWord()));
5214 case GSF_ROADVEHICLES:
5225 byte num_loaded = type;
5226 byte num_loading = buf->ReadByte();
5229 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5233 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5234 setid, num_loaded, num_loading);
5236 if (num_loaded + num_loading == 0) {
5237 grfmsg(1,
"NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
5241 if (num_loaded + num_loading == 1) {
5243 uint16 spriteid = buf->ReadWord();
5245 grfmsg(8,
"NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
5249 std::vector<uint16> loaded;
5250 std::vector<uint16> loading;
5252 for (uint i = 0; i < num_loaded; i++) {
5253 loaded.push_back(buf->ReadWord());
5254 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, loaded[i]);
5257 for (uint i = 0; i < num_loading; i++) {
5258 loading.push_back(buf->ReadWord());
5259 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
5262 if (std::adjacent_find(loaded.begin(), loaded.end(), std::not_equal_to<>()) == loaded.end() &&
5263 std::adjacent_find(loading.begin(), loading.end(), std::not_equal_to<>()) == loading.end() &&
5264 loaded[0] == loading[0])
5268 grfmsg(8,
"NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
5277 for (uint16 spriteid : loaded) {
5279 group->
loaded.push_back(t);
5282 for (uint16 spriteid : loading) {
5291 case GSF_AIRPORTTILES:
5293 case GSF_INDUSTRYTILES: {
5294 byte num_building_sprites = std::max((uint8)1, type);
5302 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5306 case GSF_INDUSTRIES: {
5308 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5319 for (uint i = 0; i < 3; i++) {
5323 for (uint i = 0; i < 2; i++) {
5326 group->again = buf->ReadByte();
5327 }
else if (type == 1) {
5329 for (uint i = 0; i < 3; i++) {
5333 for (uint i = 0; i < 2; i++) {
5336 group->again = buf->ReadByte();
5337 }
else if (type == 2) {
5341 error->data =
"too many inputs (max 16)";
5344 for (uint i = 0; i < group->
num_input; i++) {
5345 byte rawcargo = buf->ReadByte();
5354 error->data =
"duplicate input cargo";
5363 error->data =
"too many outputs (max 16)";
5366 for (uint i = 0; i < group->
num_output; i++) {
5367 byte rawcargo = buf->ReadByte();
5374 error->data =
"duplicate output cargo";
5380 group->again = buf->ReadByte();
5388 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5393 _cur.spritegroups[setid] = act_group;
5396 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5398 if (feature == GSF_OBJECTS) {
5403 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5408 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5409 if (ctype == 0xFF)
return CT_PURCHASE;
5414 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5419 if (cs->bitnum == ctype) {
5420 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5425 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5431 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5438 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5444 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));
5448 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);
5453 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5455 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5456 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5463 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5466 static uint last_engines_count;
5467 bool wagover =
false;
5470 if (
HasBit(idcount, 7)) {
5473 idcount =
GB(idcount, 0, 7);
5475 if (last_engines_count == 0) {
5476 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5480 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5481 last_engines_count, idcount);
5483 if (last_engines_count != idcount) {
5484 last_engines =
ReallocT(last_engines, idcount);
5485 last_engines_count = idcount;
5490 for (uint i = 0; i < idcount; i++) {
5496 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5500 engines[i] = e->
index;
5501 if (!wagover) last_engines[i] = engines[i];
5504 uint8 cidcount = buf->ReadByte();
5505 for (uint c = 0; c < cidcount; c++) {
5506 uint8 ctype = buf->ReadByte();
5507 uint16 groupid = buf->ReadWord();
5508 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5510 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5512 ctype = TranslateCargo(feature, ctype);
5515 for (uint i = 0; i < idcount; i++) {
5518 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5521 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5523 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5528 uint16 groupid = buf->ReadWord();
5529 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5531 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5533 for (uint i = 0; i < idcount; i++) {
5537 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5539 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5546 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5549 for (uint i = 0; i < idcount; i++) {
5553 uint8 cidcount = buf->ReadByte();
5554 buf->Skip(cidcount * 3);
5556 uint16 groupid = buf->ReadWord();
5557 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5559 for (uint i = 0; i < idcount; i++) {
5563 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5573 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5575 if (_cur.
grffile->stations ==
nullptr) {
5576 grfmsg(1,
"StationMapSpriteGroup: No stations defined, skipping");
5580 uint8 *stations =
AllocaM(uint8, idcount);
5581 for (uint i = 0; i < idcount; i++) {
5582 stations[i] = buf->ReadByte();
5585 uint8 cidcount = buf->ReadByte();
5586 for (uint c = 0; c < cidcount; c++) {
5587 uint8 ctype = buf->ReadByte();
5588 uint16 groupid = buf->ReadWord();
5589 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5591 ctype = TranslateCargo(GSF_STATIONS, ctype);
5594 for (uint i = 0; i < idcount; i++) {
5597 if (statspec ==
nullptr) {
5598 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5606 uint16 groupid = buf->ReadWord();
5607 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5609 for (uint i = 0; i < idcount; i++) {
5612 if (statspec ==
nullptr) {
5613 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5618 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5625 StationClass::Assign(statspec);
5630 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5632 if (_cur.
grffile->housespec ==
nullptr) {
5633 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5637 uint8 *houses =
AllocaM(uint8, idcount);
5638 for (uint i = 0; i < idcount; i++) {
5639 houses[i] = buf->ReadByte();
5643 uint8 cidcount = buf->ReadByte();
5644 buf->Skip(cidcount * 3);
5646 uint16 groupid = buf->ReadWord();
5647 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5649 for (uint i = 0; i < idcount; i++) {
5652 if (hs ==
nullptr) {
5653 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5661 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5663 if (_cur.
grffile->industryspec ==
nullptr) {
5664 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5668 uint8 *industries =
AllocaM(uint8, idcount);
5669 for (uint i = 0; i < idcount; i++) {
5670 industries[i] = buf->ReadByte();
5674 uint8 cidcount = buf->ReadByte();
5675 buf->Skip(cidcount * 3);
5677 uint16 groupid = buf->ReadWord();
5678 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5680 for (uint i = 0; i < idcount; i++) {
5683 if (indsp ==
nullptr) {
5684 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5692 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5694 if (_cur.
grffile->indtspec ==
nullptr) {
5695 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5699 uint8 *indtiles =
AllocaM(uint8, idcount);
5700 for (uint i = 0; i < idcount; i++) {
5701 indtiles[i] = buf->ReadByte();
5705 uint8 cidcount = buf->ReadByte();
5706 buf->Skip(cidcount * 3);
5708 uint16 groupid = buf->ReadWord();
5709 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5711 for (uint i = 0; i < idcount; i++) {
5714 if (indtsp ==
nullptr) {
5715 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5723 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5726 for (uint i = 0; i < idcount; i++) {
5727 cargoes[i] = buf->ReadByte();
5731 uint8 cidcount = buf->ReadByte();
5732 buf->Skip(cidcount * 3);
5734 uint16 groupid = buf->ReadWord();
5735 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5737 for (uint i = 0; i < idcount; i++) {
5741 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5747 cs->group = _cur.spritegroups[groupid];
5751 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5753 if (_cur.
grffile->objectspec ==
nullptr) {
5754 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5758 uint8 *objects =
AllocaM(uint8, idcount);
5759 for (uint i = 0; i < idcount; i++) {
5760 objects[i] = buf->ReadByte();
5763 uint8 cidcount = buf->ReadByte();
5764 for (uint c = 0; c < cidcount; c++) {
5765 uint8 ctype = buf->ReadByte();
5766 uint16 groupid = buf->ReadWord();
5767 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5769 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5772 for (uint i = 0; i < idcount; i++) {
5775 if (spec ==
nullptr) {
5776 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5784 uint16 groupid = buf->ReadWord();
5785 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5787 for (uint i = 0; i < idcount; i++) {
5790 if (spec ==
nullptr) {
5791 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5796 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5806 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5808 uint8 *railtypes =
AllocaM(uint8, idcount);
5809 for (uint i = 0; i < idcount; i++) {
5810 uint8
id = buf->ReadByte();
5814 uint8 cidcount = buf->ReadByte();
5815 for (uint c = 0; c < cidcount; c++) {
5816 uint8 ctype = buf->ReadByte();
5817 uint16 groupid = buf->ReadWord();
5818 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5820 if (ctype >= RTSG_END)
continue;
5823 for (uint i = 0; i < idcount; i++) {
5828 rti->
group[ctype] = _cur.spritegroups[groupid];
5837 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5841 uint8 *roadtypes =
AllocaM(uint8, idcount);
5842 for (uint i = 0; i < idcount; i++) {
5843 uint8
id = buf->ReadByte();
5847 uint8 cidcount = buf->ReadByte();
5848 for (uint c = 0; c < cidcount; c++) {
5849 uint8 ctype = buf->ReadByte();
5850 uint16 groupid = buf->ReadWord();
5851 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5853 if (ctype >= ROTSG_END)
continue;
5856 for (uint i = 0; i < idcount; i++) {
5861 rti->
group[ctype] = _cur.spritegroups[groupid];
5870 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5872 if (_cur.
grffile->airportspec ==
nullptr) {
5873 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5877 uint8 *airports =
AllocaM(uint8, idcount);
5878 for (uint i = 0; i < idcount; i++) {
5879 airports[i] = buf->ReadByte();
5883 uint8 cidcount = buf->ReadByte();
5884 buf->Skip(cidcount * 3);
5886 uint16 groupid = buf->ReadWord();
5887 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5889 for (uint i = 0; i < idcount; i++) {
5892 if (as ==
nullptr) {
5893 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5901 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5903 if (_cur.
grffile->airtspec ==
nullptr) {
5904 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5908 uint8 *airptiles =
AllocaM(uint8, idcount);
5909 for (uint i = 0; i < idcount; i++) {
5910 airptiles[i] = buf->ReadByte();
5914 uint8 cidcount = buf->ReadByte();
5915 buf->Skip(cidcount * 3);
5917 uint16 groupid = buf->ReadWord();
5918 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5920 for (uint i = 0; i < idcount; i++) {
5923 if (airtsp ==
nullptr) {
5924 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5934 static void FeatureMapSpriteGroup(
ByteReader *buf)
5950 uint8 feature = buf->ReadByte();
5951 uint8 idcount = buf->ReadByte();
5953 if (feature >= GSF_END) {
5954 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5962 uint16 groupid = buf->ReadWord();
5963 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5965 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5974 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5978 case GSF_ROADVEHICLES:
5981 VehicleMapSpriteGroup(buf, feature, idcount);
5985 CanalMapSpriteGroup(buf, idcount);
5989 StationMapSpriteGroup(buf, idcount);
5993 TownHouseMapSpriteGroup(buf, idcount);
5996 case GSF_INDUSTRIES:
5997 IndustryMapSpriteGroup(buf, idcount);
6000 case GSF_INDUSTRYTILES:
6001 IndustrytileMapSpriteGroup(buf, idcount);
6005 CargoMapSpriteGroup(buf, idcount);
6009 AirportMapSpriteGroup(buf, idcount);
6013 ObjectMapSpriteGroup(buf, idcount);
6017 RailTypeMapSpriteGroup(buf, idcount);
6021 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
6025 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
6028 case GSF_AIRPORTTILES:
6029 AirportTileMapSpriteGroup(buf, idcount);
6033 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
6057 bool new_scheme = _cur.
grffile->grf_version >= 7;
6059 uint8 feature = buf->ReadByte();
6060 if (feature >= GSF_END && feature != 0x48) {
6061 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
6065 uint8 lang = buf->ReadByte();
6066 uint8 num = buf->ReadByte();
6067 bool generic =
HasBit(lang, 7);
6070 id = buf->ReadWord();
6071 }
else if (feature <= GSF_AIRCRAFT) {
6072 id = buf->ReadExtendedByte();
6074 id = buf->ReadByte();
6079 uint16 endid =
id + num;
6081 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
6082 id, endid, feature, lang);
6084 for (;
id < endid && buf->HasData();
id++) {
6085 const char *name = buf->ReadString();
6086 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6090 case GSF_ROADVEHICLES:
6095 if (e ==
nullptr)
break;
6109 switch (
GB(
id, 8, 8)) {
6112 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6121 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6129 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6137 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6144 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6163 if (offset >= max_sprites) {
6164 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6165 uint orig_num = num;
6170 if (offset + num > max_sprites) {
6171 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6172 uint orig_num = num;
6173 num = std::max(max_sprites - offset, 0);
6174 return orig_num - num;
6203 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6205 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6235 uint8 type = buf->ReadByte();
6236 uint16 num = buf->ReadExtendedByte();
6237 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6243 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6260 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6271 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6278 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);
6288 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);
6300 bool dup_oneway_sprites = ((type == 0x09) && (offset + num <= SPR_ONEWAY_SLOPE_N_OFFSET));
6302 for (; num > 0; num--) {
6304 int load_index = (replace == 0 ? _cur.
spriteid++ : replace++);
6306 if (dup_oneway_sprites) {
6307 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_N_OFFSET);
6308 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_S_OFFSET);
6378 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6408 *value = _game_mode;
6442 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6451 *value = _openttd_newgrf_version;
6466 default:
return false;
6470 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6488 if (cond_val ==
nullptr) {
6492 uint32 index = *cond_val / 0x20;
6508 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6529 size_t pos = file.
GetPos();
6532 byte *preload_sprite =
nullptr;
6536 preload_sprite = MallocT<byte>(num);
6541 file.
SeekTo(pos, SEEK_SET);
6544 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6545 free(preload_sprite);
6550 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6551 if (it != _grf_line_to_action6_sprite_override.end()) {
6552 free(preload_sprite);
6553 preload_sprite = _grf_line_to_action6_sprite_override[location];
6555 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6568 param_num = buf->ReadByte();
6569 if (param_num == 0xFF)
break;
6573 param_size = buf->ReadByte();
6577 add_value =
HasBit(param_size, 7);
6578 param_size =
GB(param_size, 0, 7);
6581 offset = buf->ReadExtendedByte();
6585 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6586 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6590 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6593 for (i = 0; i < param_size && offset + i < num; i++) {
6594 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6597 if (i % 4 == 0) carry =
false;
6600 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6601 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6603 carry = new_value >= 256;
6605 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6637 uint32 cond_val = 0;
6641 uint8 param = buf->ReadByte();
6642 uint8 paramsize = buf->ReadByte();
6643 uint8 condtype = buf->ReadByte();
6650 switch (paramsize) {
6651 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6652 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6653 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6654 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6658 if (param < 0x80 && _cur.grffile->param_end <= param) {
6659 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6663 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6668 if (condtype >= 0x0B) {
6699 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6701 }
else if (param == 0x88) {
6711 if (condtype != 10 && c ==
nullptr) {
6712 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6739 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6743 uint32 param_val = GetParamVal(param, &cond_val);
6745 case 0x00: result = !!(param_val & (1 << cond_val));
6747 case 0x01: result = !(param_val & (1 << cond_val));
6749 case 0x02: result = (param_val & mask) == cond_val;
6751 case 0x03: result = (param_val & mask) != cond_val;
6753 case 0x04: result = (param_val & mask) < cond_val;
6755 case 0x05: result = (param_val & mask) > cond_val;
6757 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6762 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6766 uint8 numsprites = buf->ReadByte();
6774 if (label.label != numsprites)
continue;
6777 if (choice ==
nullptr) choice = &label;
6779 if (label.nfo_line > _cur.
nfo_line) {
6785 if (choice !=
nullptr) {
6786 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6792 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6811 uint8 grf_version = buf->ReadByte();
6812 uint32 grfid = buf->ReadDWord();
6813 const char *name = buf->ReadString();
6817 if (grf_version < 2 || grf_version > 8) {
6819 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);
6827 if (buf->HasData()) {
6828 const char *info = buf->ReadString();
6846 uint8 version = buf->ReadByte();
6847 uint32 grfid = buf->ReadDWord();
6848 const char *name = buf->ReadString();
6851 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6855 if (_cur.
grffile->grfid != grfid) {
6856 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));
6860 _cur.
grffile->grf_version = version;
6878 uint8 num_sets = buf->ReadByte();
6880 for (uint i = 0; i < num_sets; i++) {
6881 uint8 num_sprites = buf->ReadByte();
6882 uint16 first_sprite = buf->ReadWord();
6884 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6885 i, num_sprites, first_sprite
6888 for (uint j = 0; j < num_sprites; j++) {
6889 int load_index = first_sprite + j;
6895 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6905 uint8 num_sets = buf->ReadByte();
6907 for (uint i = 0; i < num_sets; i++) {
6936 STR_NEWGRF_ERROR_VERSION_NUMBER,
6937 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6938 STR_NEWGRF_ERROR_UNSET_SWITCH,
6939 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6940 STR_NEWGRF_ERROR_LOAD_BEFORE,
6941 STR_NEWGRF_ERROR_LOAD_AFTER,
6942 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6946 STR_NEWGRF_ERROR_MSG_INFO,
6947 STR_NEWGRF_ERROR_MSG_WARNING,
6948 STR_NEWGRF_ERROR_MSG_ERROR,
6949 STR_NEWGRF_ERROR_MSG_FATAL
6952 byte severity = buf->ReadByte();
6953 byte lang = buf->ReadByte();
6954 byte message_id = buf->ReadByte();
6957 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6961 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6962 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6967 if (severity >=
lengthof(sevstr)) {
6968 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6970 }
else if (severity == 3) {
6980 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6981 grfmsg(7,
"GRFLoadError: Invalid message id.");
6985 if (buf->Remaining() <= 1) {
6986 grfmsg(7,
"GRFLoadError: No message data supplied.");
6995 if (message_id == 0xFF) {
6997 if (buf->HasData()) {
6998 const char *message = buf->ReadString();
7002 grfmsg(7,
"GRFLoadError: No custom message supplied.");
7003 error->custom_message.clear();
7006 error->message = msgstr[message_id];
7009 if (buf->HasData()) {
7010 const char *data = buf->ReadString();
7014 grfmsg(7,
"GRFLoadError: No message data supplied.");
7015 error->data.clear();
7019 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
7020 uint param_number = buf->ReadByte();
7034 if (!buf->HasData())
return;
7036 const char *text = buf->ReadString();
7037 grfmsg(2,
"GRFComment: %s", text);
7043 uint8 target = buf->ReadByte();
7046 if (target < 0x80 || target == 0x9E)
return;
7060 static uint32 GetPatchVariable(uint8 param)
7070 case 0x0F:
return 0;
7086 case 0x11:
return SPR_2CCMAP_BASE;
7103 byte max_edge = std::max(log_X, log_Y);
7105 if (log_X == log_Y) {
7108 if (max_edge == log_Y)
SetBit(map_bits, 1);
7111 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7112 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7121 return SPR_SLOPES_BASE;
7132 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7138 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7151 for (uint i = start; i < num_ids; i++) {
7155 if (op == 2 || op == 3)
break;
7160 if (size == count)
break;
7163 if (size == count) {
7165 if (op == 0 || op == 3) {
7166 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7167 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7173 if (op != 4 && op != 5) {
7175 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7180 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7210 uint8 target = buf->ReadByte();
7211 uint8 oper = buf->ReadByte();
7212 uint32 src1 = buf->ReadByte();
7213 uint32 src2 = buf->ReadByte();
7216 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7225 if (target < 0x80 && target < _cur.grffile->param_end) {
7226 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7230 oper =
GB(oper, 0, 7);
7234 if (
GB(data, 0, 8) == 0xFF) {
7235 if (data == 0x0000FFFF) {
7237 src1 = GetPatchVariable(src1);
7241 uint8 feature =
GB(data, 8, 8);
7242 uint16 count =
GB(data, 16, 16);
7244 if (_cur.
stage == GLS_RESERVE) {
7245 if (feature == 0x08) {
7249 if (_cur.
spriteid + count >= 16384) {
7250 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7256 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7263 }
else if (_cur.
stage == GLS_ACTIVATION) {
7292 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7300 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7311 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7328 }
else if (src1 == 0xFE) {
7340 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7341 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7363 res = (int32)src1 * (int32)src2;
7367 if ((int32)src2 < 0) {
7368 res = src1 >> -(int32)src2;
7370 res = src1 << (src2 & 0x1F);
7375 if ((int32)src2 < 0) {
7376 res = (int32)src1 >> -(int32)src2;
7378 res = (int32)src1 << (src2 & 0x1F);
7402 res = (int32)src1 / (int32)src2;
7418 res = (int32)src1 % (int32)src2;
7422 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7451 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7462 uint32 safe_bits = 0;
7463 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7472 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7476 if (target < 0x80) {
7477 _cur.
grffile->param[target] = res;
7481 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7495 uint8 num = buf->ReadByte();
7497 for (uint i = 0; i < num; i++) {
7498 uint32 grfid = buf->ReadDWord();
7520 uint8 num = buf->ReadByte();
7522 for (uint i = 0; i < num; i++) {
7523 uint32 grfid = buf->ReadDWord();
7527 if (file !=
nullptr && file != _cur.
grfconfig) {
7545 uint32 grfid = _cur.
grffile->grfid;
7549 byte id = buf->ReadByte();
7550 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7555 bool new_scheme = _cur.
grffile->grf_version >= 7;
7557 byte lang = buf->ReadByte();
7559 byte nb_gen = townname->nb_gen;
7563 const char *name = buf->ReadString();
7566 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7568 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7570 lang = buf->ReadByte();
7571 }
while (lang != 0);
7572 townname->id[nb_gen] = id;
7576 byte nb = buf->ReadByte();
7577 grfmsg(6,
"FeatureTownName: %u parts", nb);
7579 townname->nbparts[id] = nb;
7580 townname->partlist[id] = CallocT<NamePartList>(nb);
7582 for (
int i = 0; i < nb; i++) {
7583 byte nbtext = buf->ReadByte();
7584 townname->partlist[id][i].bitstart = buf->ReadByte();
7585 townname->partlist[id][i].bitcount = buf->ReadByte();
7586 townname->partlist[id][i].maxprob = 0;
7587 townname->partlist[id][i].partcount = nbtext;
7588 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7589 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);
7591 for (
int j = 0; j < nbtext; j++) {
7592 byte prob = buf->ReadByte();
7595 byte ref_id = buf->ReadByte();
7597 if (townname->nbparts[ref_id] == 0) {
7598 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7599 DelGRFTownName(grfid);
7604 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7605 townname->partlist[id][i].parts[j].data.
id = ref_id;
7607 const char *text = buf->ReadString();
7609 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7611 townname->partlist[id][i].parts[j].
prob = prob;
7612 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7614 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7626 byte nfo_label = buf->ReadByte();
7630 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", nfo_label);
7644 if (file ==
nullptr || file->sound_offset == 0) {
7645 grfmsg(1,
"ImportGRFSound: Source file not available");
7649 if (sound_id >= file->num_sounds) {
7650 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7654 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7656 *sound = *GetSound(file->sound_offset + sound_id);
7659 sound->volume = 128;
7660 sound->priority = 0;
7671 sound->volume = 0x80;
7672 sound->priority = 0;
7674 if (offs != SIZE_MAX) {
7676 sound->file = _cur.
file;
7677 sound->file_offset = offs;
7689 uint16 num = buf->ReadWord();
7690 if (num == 0)
return;
7693 if (_cur.
grffile->sound_offset == 0) {
7694 _cur.
grffile->sound_offset = GetNumSounds();
7695 _cur.
grffile->num_sounds = num;
7698 sound = GetSound(_cur.
grffile->sound_offset);
7703 for (
int i = 0; i < num; i++) {
7708 bool invalid = i >= _cur.
grffile->num_sounds;
7710 size_t offs = file.
GetPos();
7715 if (grf_container_version >= 2 && type == 0xFD) {
7718 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7720 }
else if (len != 4) {
7721 grfmsg(1,
"GRFSound: Invalid sprite section import");
7731 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7738 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7746 if (_cur.
stage == GLS_INIT) {
7747 if (grf_container_version >= 2) {
7748 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7757 if (_cur.
stage == GLS_ACTIVATION) {
7760 if (file.
ReadByte() != 0)
grfmsg(1,
"GRFSound: Import type mismatch");
7768 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7797 uint8 num_def = buf->ReadByte();
7799 for (uint i = 0; i < num_def; i++) {
7801 uint8 num_char = buf->ReadByte();
7802 uint16 base_char = buf->ReadWord();
7804 if (size >= FS_END) {
7805 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7808 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7810 for (uint c = 0; c < num_char; c++) {
7828 uint8 num_def = buf->ReadByte();
7830 for (uint i = 0; i < num_def; i++) {
7854 uint32 grfid = buf->ReadDWord();
7857 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7866 error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7876 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7877 byte num_strings = buf->ReadByte();
7878 uint16 first_id = buf->ReadWord();
7880 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7881 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7885 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7886 const char *
string = buf->ReadString();
7889 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7893 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7922 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7934 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7937 char data = buf->ReadByte();
7945 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7960 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7963 char data = buf->ReadByte();
7969 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7982 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7995 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
8000 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
8031 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
8038 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
8048 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
8050 }
else if (len != 8) {
8051 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
8054 uint32 min_value = buf->ReadDWord();
8055 uint32 max_value = buf->ReadDWord();
8056 if (min_value <= max_value) {
8060 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
8069 if (len < 1 || len > 3) {
8070 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
8073 byte param_nr = buf->ReadByte();
8075 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8091 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8127 this->handler.data = handler;
8139 this->handler.text = handler;
8151 this->handler.call_handler =
true;
8152 this->handler.u.branch = handler;
8164 this->handler.call_handler =
false;
8165 this->handler.u.subtags =
subtags;
8194 byte type = buf->ReadByte();
8196 uint32
id = buf->ReadDWord();
8198 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8200 type = buf->ReadByte();
8204 byte langid = buf->ReadByte();
8205 const char *name_string = buf->ReadString();
8216 type = buf->ReadByte();
8241 byte type = buf->ReadByte();
8243 uint32
id = buf->ReadDWord();
8245 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8247 type = buf->ReadByte();
8260 type = buf->ReadByte();
8297 byte new_type = buf->ReadByte();
8298 while (new_type != 0) {
8301 new_type = buf->ReadByte();
8312 uint16 size = buf->ReadWord();
8336 while ((tag = &subtags[i++])->type != 0) {
8339 default: NOT_REACHED();
8342 byte langid = buf->ReadByte();
8343 return tag->handler.
text(langid, buf->ReadString());
8347 size_t len = buf->ReadWord();
8348 if (buf->Remaining() < len)
return false;
8349 return tag->handler.
data(len, buf);
8354 return tag->handler.u.branch(buf);
8360 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8372 byte type = buf->ReadByte();
8374 uint32
id = buf->ReadDWord();
8375 if (!
HandleNode(type,
id, buf, subtags))
return false;
8376 type = buf->ReadByte();
8499 if (stations ==
nullptr)
continue;
8501 if (stations[i] ==
nullptr)
continue;
8518 HouseSpec **&housespec = file->housespec;
8519 if (housespec ==
nullptr)
continue;
8525 housespec =
nullptr;
8534 if (aslist !=
nullptr) {
8538 if (as !=
nullptr) {
8540 for (
int j = 0; j < as->
num_table; j++) {
8552 file->airportspec =
nullptr;
8556 if (airporttilespec !=
nullptr) {
8558 free(airporttilespec[i]);
8560 free(airporttilespec);
8561 airporttilespec =
nullptr;
8575 if (industryspec !=
nullptr) {
8582 industryspec =
nullptr;
8585 if (indtspec ==
nullptr)
continue;
8600 if (objectspec ==
nullptr)
continue;
8602 free(objectspec[i]);
8606 objectspec =
nullptr;
8638 CleanUpGRFTownNames();
8682 ObjectClass::Reset();
8687 StationClass::Reset();
8691 AirportClass::Reset();
8720 _grf_id_overrides.clear();
8722 InitializeSoundPool();
8770 if (newfile !=
nullptr) {
8776 newfile =
new GRFFile(config);
8794 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8799 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8806 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8810 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8826 free(this->filename);
8836 CargoTypes original_known_cargoes = 0;
8837 for (
int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
8845 bool only_defaultcargo;
8848 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
8851 static constexpr
byte T = 1 << LT_TEMPERATE;
8852 static constexpr
byte A = 1 << LT_ARCTIC;
8853 static constexpr
byte S = 1 << LT_TROPIC;
8854 static constexpr
byte Y = 1 << LT_TOYLAND;
8855 static const struct DefaultRefitMasks {
8858 CargoTypes cargo_allowed;
8859 CargoTypes cargo_disallowed;
8860 } _default_refit_masks[] = {
8862 {T | A | S , CT_MAIL,
CC_MAIL, 0},
8865 {T | A , CT_COAL,
CC_BULK, 0},
8866 { S , CT_COPPER_ORE,
CC_BULK, 0},
8881 switch (ei->cargo_type) {
8885 _gted[engine].cargo_disallowed = 0;
8890 _gted[engine].cargo_disallowed = 0;
8909 _gted[engine].cargo_disallowed = 0;
8912 for (
const auto &drm : _default_refit_masks) {
8914 if (drm.cargo_type != ei->cargo_type)
continue;
8916 _gted[engine].cargo_allowed = drm.cargo_allowed;
8917 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
8934 CargoTypes mask = 0;
8935 CargoTypes not_mask = 0;
8936 CargoTypes xor_mask = ei->refit_mask;
8942 if (
_gted[engine].cargo_allowed != 0) {
8945 if (
_gted[engine].cargo_allowed & cs->classes)
SetBit(mask, cs->Index());
8946 if (
_gted[engine].cargo_disallowed & cs->classes)
SetBit(not_mask, cs->Index());
8950 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8968 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8970 const uint8 *cargo_map_for_first_refittable =
nullptr;
8973 if (file ==
nullptr) file = e->
GetGRF();
8974 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8975 cargo_map_for_first_refittable = file->
cargo_map;
8979 if (cargo_map_for_first_refittable !=
nullptr) {
8981 byte best_local_slot = 0xFF;
8983 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8984 if (local_slot < best_local_slot) {
8985 best_local_slot = local_slot;
8986 ei->cargo_type = cargo_type;
9008 for (uint i = 0; i < CF_END; i++) {
9020 if (e->
GetGRF() ==
nullptr) {
9023 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
9059 default: NOT_REACHED();
9073 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
9074 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
9098 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
9108 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);
9116 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9123 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);
9142 if (hs ==
nullptr || !hs->
enabled)
continue;
9147 if (min_year == 0)
return;
9151 if (hs ==
nullptr || !hs->
enabled)
continue;
9175 HouseSpec **&housespec = file->housespec;
9176 if (housespec ==
nullptr)
continue;
9181 if (hs ==
nullptr)
continue;
9239 if (industryspec !=
nullptr) {
9243 if (indsp !=
nullptr && indsp->
enabled) {
9249 if (strid != STR_UNDEFINED) indsp->
name = strid;
9252 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9267 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9275 if (indtspec !=
nullptr) {
9278 if (indtsp !=
nullptr) {
9279 _industile_mngr.SetEntitySpec(indtsp);
9288 for (uint i = 0; i < 3; i++) {
9293 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9307 if (objectspec !=
nullptr) {
9309 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9326 if (airportspec !=
nullptr) {
9328 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9329 _airport_mngr.SetEntitySpec(airportspec[i]);
9335 if (airporttilespec !=
nullptr) {
9337 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9338 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9351 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9365 static const SpecialSpriteHandler handlers[][GLS_END] = {
9366 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9367 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9368 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9369 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9370 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9371 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9372 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9373 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9374 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9375 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9376 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9377 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9378 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9380 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9383 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9386 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9391 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9392 if (it == _grf_line_to_action6_sprite_override.end()) {
9398 buf = _grf_line_to_action6_sprite_override[location];
9399 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9409 byte action = bufp->ReadByte();
9411 if (action == 0xFF) {
9412 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9413 }
else if (action == 0xFE) {
9414 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9415 }
else if (action >=
lengthof(handlers)) {
9416 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9417 }
else if (handlers[action][stage] ==
nullptr) {
9418 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9420 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9421 handlers[action][stage](bufp);
9424 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9440 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config->
filename);
9443 if (grf_container_version == 0) {
9444 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9448 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9454 if (grf_container_version >= 2) file.
ReadDword();
9457 if (grf_container_version >= 2) {
9459 byte compression = file.
ReadByte();
9460 if (compression != 0) {
9461 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9470 if (num == 4 && file.
ReadByte() == 0xFF) {
9473 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9481 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
9487 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9498 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9499 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9503 if (grf_container_version >= 2 && type == 0xFD) {
9526 const char *filename = config->
filename;
9537 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9539 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9546 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
9600 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9601 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9602 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9603 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9604 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9605 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9616 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9620 int *grf_overrides =
AllocaM(
int, num_grfs);
9621 for (
int i = 0; i < num_grfs; i++) {
9622 grf_overrides[i] = -1;
9625 uint32
override = _grf_id_overrides[source->grfid];
9626 if (
override == 0)
continue;
9629 if (dest ==
nullptr)
continue;
9632 assert(grf_overrides[i] >= 0);
9636 for (
int i = 0; i < num_grfs; i++) {
9637 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9645 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9648 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
9654 for (
int i = num_grfs - 1; i >= 0; i--) {
9655 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9663 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9666 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
9672 for (
int i = 0; i < num_grfs; i++) {
9673 if (grf_overrides[i] < 0)
continue;
9681 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9682 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9684 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
9692 if (file->grf_version >= 8)
continue;
9693 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9694 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9696 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9699 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9706 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9707 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9708 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9710 price_base_multipliers[p] = 0;
9715 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file->
filename, p);
9717 price_base_multipliers[p] = 0;
9719 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file->
filename, p);
9734 _string_to_grf_mapping.clear();
9737 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9740 _grf_line_to_action6_sprite_override.clear();
9803 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9812 if (
_gted[e->
index].roadtramtype < list->size())
9814 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9843 _grm_sprites.clear();
9891 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9898 if (stage == GLS_RESERVE) {
9899 static const uint32 overrides[][2] = {
9900 { 0x44442202, 0x44440111 },
9901 { 0x6D620402, 0x6D620401 },
9902 { 0x4D656f20, 0x4D656F17 },
9904 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9910 uint num_non_static = 0;
9919 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->
filename);
9928 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9930 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9939 if (stage == GLS_RESERVE) {
9941 }
else if (stage == GLS_ACTIVATION) {
9946 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur.
spriteid);