52 #include "table/strings.h"
69 const std::vector<GRFFile *> &GetAllGRFFiles()
118 this->skip_sprites = 0;
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
124 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.
sprite = first_sprite + i * numents;
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
179 return this->spritesets[feature].find(set)->second.sprite;
191 return this->spritesets[feature].find(set)->second.num_sprites;
204 template <VehicleType T>
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
219 ByteReader(
byte *data,
byte *end) : data(data), end(end) { }
221 inline byte *ReadBytes(
size_t size)
223 if (data + size >= end) {
234 inline byte ReadByte()
236 if (data < end)
return *(data)++;
242 uint16 val = ReadByte();
243 return val | (ReadByte() << 8);
246 uint16 ReadExtendedByte()
248 uint16 val = ReadByte();
249 return val == 0xFF ? ReadWord() : val;
254 uint32 val = ReadWord();
255 return val | (ReadWord() << 16);
258 uint32 ReadVarSize(
byte size)
261 case 1:
return ReadByte();
262 case 2:
return ReadWord();
263 case 4:
return ReadDWord();
270 const char *ReadString()
272 char *
string =
reinterpret_cast<char *
>(data);
273 size_t string_length =
ttd_strnlen(
string, Remaining());
275 if (string_length == Remaining()) {
277 string[string_length - 1] =
'\0';
278 grfmsg(7,
"String was not terminated with a zero byte.");
288 inline size_t Remaining()
const
293 inline bool HasData(
size_t count = 1)
const
295 return data + count <= end;
303 inline void Skip(
size_t len)
312 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
325 uint16 cargo_allowed;
326 uint16 cargo_disallowed;
327 RailTypeLabel railtypelabel;
343 }
else if (this->refittability ==
UNSET) {
344 this->refittability =
EMPTY;
364 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
368 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
373 return this->grfid == other.grfid && this->nfoline == other.nfoline;
377 static std::map<GRFLocation, SpriteID> _grm_sprites;
378 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
379 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
391 void CDECL
grfmsg(
int severity,
const char *str, ...)
411 if (file->grfid == grfid)
return file;
424 if (strcmp(file->filename, filename) == 0)
return file;
444 if (config !=
nullptr) {
455 if (message != STR_NULL) {
456 delete config->error;
457 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
461 return config->error;
472 typedef std::vector<StringIDMapping> StringIDMappingVector;
473 static StringIDMappingVector _string_to_grf_mapping;
482 *target = STR_UNDEFINED;
483 _string_to_grf_mapping.push_back({_cur.
grffile->grfid, source, target});
496 static const StringID units_volume[] = {
497 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
498 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
499 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
500 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
501 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
502 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
503 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
504 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
510 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
511 static_assert(stringend - stringid == end - begin); \
512 if (str >= begin && str <= end) return str + (stringid - begin)
515 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
516 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
517 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
518 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
519 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
520 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
525 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
526 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
527 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
530 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
531 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
532 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
533 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
534 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
537 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
538 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
539 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
541 #undef TEXTID_TO_STRINGID
543 if (str == STR_NULL)
return STR_EMPTY;
545 Debug(grf, 0,
"Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
584 static std::map<uint32, uint32> _grf_id_overrides;
593 _grf_id_overrides[source_grfid] = target_grfid;
594 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
609 uint32 scope_grfid = INVALID_GRFID;
612 scope_grfid = file->grfid;
613 uint32
override = _grf_id_overrides[file->grfid];
615 scope_grfid =
override;
617 if (grf_match ==
nullptr) {
618 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
625 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
634 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
640 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
644 if (!static_access) {
646 eid->
grfid = scope_grfid;
652 if (static_access)
return nullptr;
655 grfmsg(0,
"Can't allocate any more engines");
666 assert(_engine_mngr.size() == e->
index);
667 _engine_mngr.push_back({
680 memset(
_gted + engine_pool_size, 0, len);
686 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
703 uint32 scope_grfid = INVALID_GRFID;
705 scope_grfid = file->grfid;
706 uint32
override = _grf_id_overrides[file->grfid];
707 if (
override != 0) scope_grfid =
override;
710 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
750 grf_sprite->
sprite = buf->ReadWord();
751 grf_sprite->
pal = buf->ReadWord();
756 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
760 uint index =
GB(grf_sprite->
sprite, 0, 14);
762 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
763 grf_sprite->
sprite = SPR_IMG_QUERY;
764 grf_sprite->
pal = PAL_NONE;
767 if (max_sprite_offset !=
nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
772 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
773 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
779 uint index =
GB(grf_sprite->
pal, 0, 14);
781 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
782 grf_sprite->
pal = PAL_NONE;
785 if (max_palette_offset !=
nullptr) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
790 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
791 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
820 regs.delta.
parent[0] = buf->ReadByte();
821 regs.delta.
parent[1] = buf->ReadByte();
833 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
842 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
861 bool has_flags =
HasBit(num_building_sprites, 6);
862 ClrBit(num_building_sprites, 6);
865 dts->
Allocate(num_building_sprites);
867 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
868 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
869 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
870 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
877 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
878 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
885 for (uint i = 0; i < num_building_sprites; i++) {
888 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
891 if (flags & ~valid_flags) {
892 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
893 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
897 seq->
delta_x = buf->ReadByte();
898 seq->delta_y = buf->ReadByte();
900 if (!no_z_position) seq->
delta_z = buf->ReadByte();
903 seq->size_x = buf->ReadByte();
904 seq->size_y = buf->ReadByte();
905 seq->size_z = buf->ReadByte();
913 bool is_consistent =
true;
915 for (uint i = 0; i < num_building_sprites + 1; i++) {
916 if (max_sprite_offset[i] > 0) {
920 is_consistent =
false;
924 if (max_palette_offset[i] > 0) {
928 is_consistent =
false;
937 if (!is_consistent || dts->registers !=
nullptr) {
941 for (uint i = 0; i < num_building_sprites + 1; i++) {
956 CargoTypes result = 0;
974 if (base_pointer == 0) {
975 *index = INVALID_PRICE;
979 static const uint32 start = 0x4B34;
980 static const uint32 size = 6;
982 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
983 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
987 *index = (
Price)((base_pointer - start) / size);
1016 ei->decay_speed = buf->ReadByte();
1033 ei->load_amount = buf->ReadByte();
1055 for (
int i = 0; i < numinfo; i++) {
1064 uint8 tracktype = buf->ReadByte();
1066 if (tracktype < _cur.grffile->railtype_list.size()) {
1071 switch (tracktype) {
1072 case 0:
_gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1073 case 1:
_gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1074 case 2:
_gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1076 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1089 uint16 speed = buf->ReadWord();
1090 if (speed == 0xFFFF) speed = 0;
1097 rvi->
power = buf->ReadWord();
1100 if (rvi->
power != 0) {
1118 uint8 spriteid = buf->ReadByte();
1119 uint8 orig_spriteid = spriteid;
1123 if (spriteid < 0xFD) spriteid >>= 1;
1125 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1126 rvi->image_index = spriteid;
1128 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1129 rvi->image_index = 0;
1135 uint8 dual = buf->ReadByte();
1140 rvi->railveh_type = rvi->
power == 0 ?
1152 uint8 ctype = buf->ReadByte();
1154 if (ctype == 0xFF) {
1157 }
else if (_cur.
grffile->grf_version >= 8) {
1162 ei->cargo_type = ctype;
1165 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1171 SB(rvi->
weight, 0, 8, buf->ReadByte());
1179 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1191 uint8 traction = buf->ReadByte();
1194 if (traction <= 0x07) {
1196 }
else if (traction <= 0x27) {
1198 }
else if (traction <= 0x31) {
1200 }
else if (traction <= 0x37) {
1202 }
else if (traction <= 0x41) {
1228 ei->refit_cost = buf->ReadByte();
1232 uint32 mask = buf->ReadDWord();
1270 byte weight = buf->ReadByte();
1273 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1294 _gted[e->
index].cargo_allowed = buf->ReadWord();
1300 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1314 uint8 count = buf->ReadByte();
1360 for (
int i = 0; i < numinfo; i++) {
1371 _gted[e->
index].roadtramtype = buf->ReadByte() + 1;
1379 rvi->running_cost = buf->ReadByte();
1387 uint8 spriteid = buf->ReadByte();
1388 uint8 orig_spriteid = spriteid;
1391 if (spriteid == 0xFF) spriteid = 0xFD;
1393 if (spriteid < 0xFD) spriteid >>= 1;
1395 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1396 rvi->image_index = spriteid;
1398 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1399 rvi->image_index = 0;
1405 rvi->capacity = buf->ReadByte();
1410 uint8 ctype = buf->ReadByte();
1412 if (ctype == 0xFF) {
1415 }
else if (_cur.
grffile->grf_version >= 8) {
1420 ei->cargo_type = ctype;
1423 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1429 rvi->cost_factor = buf->ReadByte();
1437 rvi->
power = buf->ReadByte();
1441 rvi->
weight = buf->ReadByte();
1449 uint32 mask = buf->ReadDWord();
1469 ei->refit_cost = buf->ReadByte();
1482 _gted[e->
index].cargo_allowed = buf->ReadWord();
1488 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1520 uint8 count = buf->ReadByte();
1562 for (
int i = 0; i < numinfo; i++) {
1571 uint8 spriteid = buf->ReadByte();
1572 uint8 orig_spriteid = spriteid;
1575 if (spriteid == 0xFF) spriteid = 0xFD;
1577 if (spriteid < 0xFD) spriteid >>= 1;
1579 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1580 svi->image_index = spriteid;
1582 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1583 svi->image_index = 0;
1593 svi->cost_factor = buf->ReadByte();
1602 uint8 ctype = buf->ReadByte();
1604 if (ctype == 0xFF) {
1607 }
else if (_cur.
grffile->grf_version >= 8) {
1612 ei->cargo_type = ctype;
1615 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1621 svi->capacity = buf->ReadWord();
1625 svi->running_cost = buf->ReadByte();
1633 uint32 mask = buf->ReadDWord();
1645 ei->refit_cost = buf->ReadByte();
1666 _gted[e->
index].cargo_allowed = buf->ReadWord();
1672 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1700 uint8 count = buf->ReadByte();
1742 for (
int i = 0; i < numinfo; i++) {
1751 uint8 spriteid = buf->ReadByte();
1752 uint8 orig_spriteid = spriteid;
1755 if (spriteid == 0xFF) spriteid = 0xFD;
1757 if (spriteid < 0xFD) spriteid >>= 1;
1759 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1760 avi->image_index = spriteid;
1762 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1763 avi->image_index = 0;
1769 if (buf->ReadByte() == 0) {
1777 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1781 avi->cost_factor = buf->ReadByte();
1785 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1789 avi->acceleration = buf->ReadByte();
1793 avi->running_cost = buf->ReadByte();
1809 uint32 mask = buf->ReadDWord();
1821 ei->refit_cost = buf->ReadByte();
1834 _gted[e->
index].cargo_allowed = buf->ReadWord();
1840 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1858 uint8 count = buf->ReadByte();
1912 for (
int i = 0; i < numinfo; i++) {
1916 if (statspec ==
nullptr && prop != 0x08) {
1917 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1929 uint32 classid = buf->ReadDWord();
1930 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1935 uint16 tiles = buf->ReadExtendedByte();
1939 for (uint t = 0; t < tiles; t++) {
1943 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1946 dts->
Clone(&_station_display_datas_rail[t % 8]);
1954 static std::vector<DrawTileSeqStruct> tmp_layout;
1961 dtss.
delta_x = buf->ReadByte();
1963 dtss.delta_y = buf->ReadByte();
1964 dtss.
delta_z = buf->ReadByte();
1965 dtss.size_x = buf->ReadByte();
1966 dtss.size_y = buf->ReadByte();
1967 dtss.size_z = buf->ReadByte();
1973 dts->
Clone(tmp_layout.data());
1978 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
1985 byte srcid = buf->ReadByte();
1988 if (srcstatspec ==
nullptr) {
1989 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1996 for (
const auto &it : srcstatspec->
renderdata) {
2016 while (buf->HasData()) {
2017 byte length = buf->ReadByte();
2018 byte number = buf->ReadByte();
2020 if (length == 0 || number == 0)
break;
2022 if (statspec->
layouts.size() < length) statspec->
layouts.resize(length);
2023 if (statspec->
layouts[length - 1].size() < number) statspec->
layouts[length - 1].resize(number);
2025 const byte *layout = buf->ReadBytes(length * number);
2026 statspec->
layouts[length - 1][number - 1].assign(layout, layout + length * number);
2029 for (
auto &tile : statspec->
layouts[length - 1][number - 1]) {
2030 if ((tile & 6) != tile) {
2031 grfmsg(1,
"StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
2039 byte srcid = buf->ReadByte();
2042 if (srcstatspec ==
nullptr) {
2043 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2056 statspec->
pylons = buf->ReadByte();
2060 if (_cur.
grffile->grf_version >= 7) {
2068 statspec->
flags = buf->ReadByte();
2072 statspec->
wires = buf->ReadByte();
2076 statspec->
blocked = buf->ReadByte();
2080 statspec->animation.
frames = buf->ReadByte();
2081 statspec->animation.
status = buf->ReadByte();
2085 statspec->animation.
speed = buf->ReadByte();
2089 statspec->animation.
triggers = buf->ReadWord();
2093 uint16 tiles = buf->ReadExtendedByte();
2097 for (uint t = 0; t < tiles; t++) {
2099 uint num_building_sprites = buf->ReadByte();
2106 grfmsg(1,
"StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
2133 if (
id + numinfo > CF_END) {
2134 grfmsg(1,
"CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring",
id + numinfo, CF_END);
2138 for (
int i = 0; i < numinfo; i++) {
2147 cp->
flags = buf->ReadByte();
2172 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2176 for (
int i = 0; i < numinfo; i++) {
2182 byte year = buf->ReadByte();
2197 bridge->
price = buf->ReadByte();
2201 bridge->
speed = buf->ReadWord();
2205 byte tableid = buf->ReadByte();
2206 byte numtables = buf->ReadByte();
2213 for (; numtables-- != 0; tableid++) {
2215 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2216 for (
byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2221 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2224 for (
byte sprite = 0; sprite < 32; sprite++) {
2238 bridge->
flags = buf->ReadByte();
2247 if (newone != STR_UNDEFINED) bridge->
material = newone;
2254 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2259 bridge->
price = buf->ReadWord();
2316 for (uint j = 0; j < 4; j++) buf->ReadByte();
2320 byte count = buf->ReadByte();
2321 for (
byte j = 0; j < count; j++) buf->ReadByte();
2326 buf->Skip(buf->ReadByte() * 2);
2349 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2354 if (_cur.
grffile->housespec ==
nullptr) {
2358 for (
int i = 0; i < numinfo; i++) {
2361 if (prop != 0x08 && housespec ==
nullptr) {
2364 if (cir > ret) ret = cir;
2371 byte subs_id = buf->ReadByte();
2373 if (subs_id == 0xFF) {
2376 HouseSpec::Get(hid + i)->
enabled =
false;
2380 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2385 if (*house ==
nullptr) *house = CallocT<HouseSpec>(1);
2389 MemCpyT(housespec, HouseSpec::Get(subs_id));
2393 housespec->
grf_prop.subst_id = subs_id;
2415 uint16 years = buf->ReadWord();
2435 int8 goods = buf->ReadByte();
2471 byte override = buf->ReadByte();
2475 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2479 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2488 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2510 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2518 uint32 cargotypes = buf->ReadDWord();
2521 if (cargotypes == 0xFFFFFFFF)
break;
2523 for (uint j = 0; j < 3; j++) {
2525 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2543 byte count = buf->ReadByte();
2544 for (
byte j = 0; j < count; j++) {
2552 housespec->
min_year = buf->ReadWord();
2556 housespec->
max_year = buf->ReadWord();
2560 uint count = buf->ReadByte();
2563 error->param_value[1] = prop;
2612 template <
typename T>
2616 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2620 translation_table.clear();
2621 for (
int i = 0; i < numinfo; i++) {
2622 uint32 item = buf->ReadDWord();
2623 translation_table.push_back(
BSWAP32(item));
2638 for (
int i = 0; i < 4; i++) output[i] = reader->ReadByte();
2642 return std::string(output);
2675 for (
int i = 0; i < numinfo; i++) {
2678 int factor = buf->ReadByte();
2679 uint price = gvid + i;
2681 if (price < PR_END) {
2684 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2693 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2701 uint32 rate = buf->ReadDWord();
2709 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2716 uint16 options = buf->ReadWord();
2725 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2737 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2749 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2756 Year year_euro = buf->ReadWord();
2761 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2768 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2770 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2776 table[i][j] = buf->ReadByte();
2777 if (_cur.
grffile->grf_version >= 8) {
2780 if (table[i][j] >= 128) {
2802 uint curidx = gvid + i;
2804 if (lang ==
nullptr) {
2805 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2810 while (buf->ReadByte() != 0) {
2820 uint plural_form = buf->ReadByte();
2821 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2822 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2829 byte newgrf_id = buf->ReadByte();
2830 while (newgrf_id != 0) {
2831 const char *name = buf->ReadString();
2846 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2853 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2858 newgrf_id = buf->ReadByte();
2894 for (
int i = 0; i < numinfo; i++) {
2918 uint32 s = buf->ReadDWord();
2919 uint32 t = buf->ReadDWord();
2926 while (buf->ReadByte() != 0) {
2954 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2958 for (
int i = 0; i < numinfo; i++) {
2963 cs->
bitnum = buf->ReadByte();
3001 cs->
sprite = buf->ReadWord();
3005 cs->
weight = buf->ReadByte();
3009 cs->transit_days[0] = buf->ReadByte();
3013 cs->transit_days[1] = buf->ReadByte();
3021 cs->rating_colour = buf->ReadByte();
3025 cs->legend_colour = buf->ReadByte();
3033 cs->
classes = buf->ReadWord();
3037 cs->
label = buf->ReadDWord();
3042 uint8 substitute_type = buf->ReadByte();
3044 switch (substitute_type) {
3051 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3067 cs->
multiplier = std::max<uint16>(1u, buf->ReadWord());
3092 if (_cur.
grffile->sound_offset == 0) {
3093 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3098 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3102 for (
int i = 0; i < numinfo; i++) {
3107 sound->volume = buf->ReadByte();
3111 sound->priority = buf->ReadByte();
3115 SoundID orig_sound = buf->ReadByte();
3120 SoundEntry *old_sound = GetSound(orig_sound);
3123 *old_sound = *sound;
3165 buf->Skip(buf->ReadByte() * 2);
3193 if (_cur.
grffile->indtspec ==
nullptr) {
3197 for (
int i = 0; i < numinfo; i++) {
3200 if (prop != 0x08 && tsp ==
nullptr) {
3202 if (cir > ret) ret = cir;
3209 byte subs_id = buf->ReadByte();
3213 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3218 if (*tilespec ==
nullptr) {
3219 *tilespec = CallocT<IndustryTileSpec>(1);
3222 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3240 byte ovrid = buf->ReadByte();
3244 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3248 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3255 uint16 acctp = buf->ReadWord();
3287 byte num_cargoes = buf->ReadByte();
3290 error->param_value[1] = prop;
3294 if (i < num_cargoes) {
3361 byte num_table = buf->ReadByte();
3362 for (
byte j = 0; j < num_table; j++) {
3363 for (uint k = 0;; k++) {
3364 byte x = buf->ReadByte();
3365 if (x == 0xFE && k == 0) {
3371 byte y = buf->ReadByte();
3372 if (x == 0 && y == 0x80)
break;
3374 byte gfx = buf->ReadByte();
3375 if (gfx == 0xFE) buf->ReadWord();
3382 for (
byte j = 0; j < 3; j++) buf->ReadByte();
3389 buf->Skip(buf->ReadByte());
3393 int num_inputs = buf->ReadByte();
3394 int num_outputs = buf->ReadByte();
3395 buf->Skip(num_inputs * num_outputs * 2);
3413 const size_t size = layout.size();
3414 if (size == 0)
return false;
3416 for (
size_t i = 0; i < size - 1; i++) {
3417 for (
size_t j = i + 1; j < size; j++) {
3418 if (layout[i].ti.x == layout[j].ti.x &&
3419 layout[i].ti.y == layout[j].ti.y) {
3425 bool have_regular_tile =
false;
3426 for (
size_t i = 0; i < size; i++) {
3428 have_regular_tile =
true;
3433 return have_regular_tile;
3454 if (_cur.
grffile->industryspec ==
nullptr) {
3458 for (
int i = 0; i < numinfo; i++) {
3461 if (prop != 0x08 && indsp ==
nullptr) {
3463 if (cir > ret) ret = cir;
3470 byte subs_id = buf->ReadByte();
3472 if (subs_id == 0xFF) {
3475 _industry_specs[indid + i].
enabled =
false;
3479 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3486 if (*indspec ==
nullptr) {
3490 *indsp = _origin_industry_specs[subs_id];
3493 indsp->
grf_prop.subst_id = subs_id;
3503 byte ovrid = buf->ReadByte();
3507 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3511 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3516 byte new_num_layouts = buf->ReadByte();
3517 uint32 definition_size = buf->ReadDWord();
3518 uint32 bytes_read = 0;
3519 std::vector<IndustryTileLayout> new_layouts;
3522 for (
byte j = 0; j < new_num_layouts; j++) {
3525 for (uint k = 0;; k++) {
3526 if (bytes_read >= definition_size) {
3527 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3529 definition_size = UINT32_MAX;
3535 it.ti.
x = buf->ReadByte();
3538 if (it.ti.
x == 0xFE && k == 0) {
3540 IndustryType type = buf->ReadByte();
3541 byte laynbr = buf->ReadByte();
3544 if (type >=
lengthof(_origin_industry_specs)) {
3545 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3549 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3550 grfmsg(1,
"IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3554 layout = _origin_industry_specs[type].layouts[laynbr];
3558 it.ti.
y = buf->ReadByte();
3561 if (it.ti.
x == 0 && it.ti.
y == 0x80) {
3567 it.gfx = buf->ReadByte();
3570 if (it.gfx == 0xFE) {
3572 int local_tile_id = buf->ReadWord();
3576 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3579 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3585 it.ti.
x = (int8)
GB(it.ti.
x, 0, 8);
3586 it.ti.
y = (int8)
GB(it.ti.
y, 0, 8);
3595 if (_cur.
grffile->grf_version < 8 && it.ti.
x < 0) it.ti.
y += 1;
3601 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3605 new_layouts.push_back(layout);
3635 for (
byte j = 0; j < 2; j++) {
3641 for (
byte j = 0; j < 3; j++) {
3649 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3662 sounds[j] = buf->ReadByte();
3678 for (
byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3704 uint32 multiples = buf->ReadDWord();
3720 byte aflag = buf->ReadByte();
3730 uint16 str = buf->ReadWord();
3740 byte num_cargoes = buf->ReadByte();
3741 if (num_cargoes >
lengthof(indsp->produced_cargo)) {
3743 error->param_value[1] = prop;
3746 for (uint i = 0; i <
lengthof(indsp->produced_cargo); i++) {
3747 if (i < num_cargoes) {
3749 indsp->produced_cargo[i] = cargo;
3758 byte num_cargoes = buf->ReadByte();
3761 error->param_value[1] = prop;
3765 if (i < num_cargoes) {
3776 byte num_cargoes = buf->ReadByte();
3777 if (num_cargoes >
lengthof(indsp->production_rate)) {
3779 error->param_value[1] = prop;
3782 for (uint i = 0; i <
lengthof(indsp->production_rate); i++) {
3783 if (i < num_cargoes) {
3784 indsp->production_rate[i] = buf->ReadByte();
3786 indsp->production_rate[i] = 0;
3793 byte num_inputs = buf->ReadByte();
3794 byte num_outputs = buf->ReadByte();
3797 error->param_value[1] = prop;
3801 for (uint j = 0; j <
lengthof(indsp->produced_cargo); j++) {
3803 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3827 for (
int i = 0; i < as->
num_table; i++) {
3832 }
while ((++it)->ti.x != -0x80);
3833 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3836 as->
table = table_list;
3858 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3863 if (_cur.
grffile->airportspec ==
nullptr) {
3867 for (
int i = 0; i < numinfo; i++) {
3870 if (as ==
nullptr && prop != 0x08 && prop != 0x09) {
3871 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3877 byte subs_id = buf->ReadByte();
3879 if (subs_id == 0xFF) {
3886 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3894 if (*spec ==
nullptr) {
3895 *spec = MallocT<AirportSpec>(1);
3904 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3916 uint32 defsize = buf->ReadDWord();
3922 for (
byte j = 0; j < as->
num_table; j++) {
3924 for (
int k = 0;; k++) {
3925 att[k].
ti.
x = buf->ReadByte();
3926 att[k].
ti.
y = buf->ReadByte();
3928 if (att[k].ti.x == 0 && att[k].
ti.
y == 0x80) {
3931 att[k].
ti.
x = -0x80;
3940 att[k].
gfx = buf->ReadByte();
3942 if (att[k].gfx == 0xFE) {
3944 int local_tile_id = buf->ReadWord();
3947 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3950 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3953 att[k].
gfx = tempid;
3955 }
else if (att[k].gfx == 0xFF) {
3956 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3957 att[k].
ti.
y = (int8)
GB(att[k].ti.y, 0, 8);
3968 tile_table[j] = CallocT<AirportTileTable>(size);
3969 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3972 for (
int j = 0; j < old_num_table; j++) {
3978 as->
table = tile_table;
3981 for (
int i = 0; i < as->
num_table; i++) {
3982 free(tile_table[i]);
4088 if (_cur.
grffile->objectspec ==
nullptr) {
4092 for (
int i = 0; i < numinfo; i++) {
4095 if (prop != 0x08 && spec ==
nullptr) {
4098 if (cir > ret) ret = cir;
4107 if (*ospec ==
nullptr) {
4108 *ospec = CallocT<ObjectSpec>(1);
4109 (*ospec)->views = 1;
4114 uint32 classid = buf->ReadDWord();
4115 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
4116 (*ospec)->enabled =
true;
4131 spec->
climate = buf->ReadByte();
4135 spec->
size = buf->ReadByte();
4136 if (
GB(spec->
size, 0, 4) == 0 ||
GB(spec->
size, 4, 4) == 0) {
4137 grfmsg(0,
"ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->
size,
id + i);
4182 spec->
height = buf->ReadByte();
4186 spec->
views = buf->ReadByte();
4188 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4221 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4225 for (
int i = 0; i < numinfo; i++) {
4238 uint16 str = buf->ReadWord();
4240 if (_cur.
grffile->grf_version < 8) {
4270 int n = buf->ReadByte();
4271 for (
int j = 0; j != n; j++) {
4272 RailTypeLabel label = buf->ReadDWord();
4332 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4351 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4355 for (
int i = 0; i < numinfo; i++) {
4359 RailTypeLabel rtl = buf->ReadDWord();
4368 _cur.
grffile->railtype_map[
id + i] = rt;
4386 int n = buf->ReadByte();
4387 for (
int j = 0; j != n; j++) {
4392 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4399 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4440 grfmsg(1,
"RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4444 for (
int i = 0; i < numinfo; i++) {
4457 uint16 str = buf->ReadWord();
4484 int n = buf->ReadByte();
4485 for (
int j = 0; j != n; j++) {
4486 RoadTypeLabel label = buf->ReadDWord();
4533 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4564 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring",
id + numinfo,
ROADTYPE_END);
4568 for (
int i = 0; i < numinfo; i++) {
4571 RoadTypeLabel rtl = buf->ReadDWord();
4578 }
else if (GetRoadTramType(rt) != rtt) {
4579 grfmsg(1,
"RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring",
id + numinfo);
4583 type_map[
id + i] = rt;
4600 int n = buf->ReadByte();
4601 for (
int j = 0; j != n; j++) {
4606 grfmsg(1,
"RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set",
id + i);
4612 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4636 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_ROAD);
4641 return RoadTypeReserveInfo(
id, numinfo, prop, buf, RTT_TRAM);
4654 if (_cur.
grffile->airtspec ==
nullptr) {
4658 for (
int i = 0; i < numinfo; i++) {
4661 if (prop != 0x08 && tsp ==
nullptr) {
4662 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4669 byte subs_id = buf->ReadByte();
4673 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4678 if (*tilespec ==
nullptr) {
4679 *tilespec = CallocT<AirportTileSpec>(1);
4696 byte override = buf->ReadByte();
4700 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4704 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4734 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4737 default: NOT_REACHED();
4747 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4751 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4764 static void FeatureChangeInfo(
ByteReader *buf)
4777 static const VCI_Handler handler[] = {
4795 AirportTilesChangeInfo,
4799 static_assert(GSF_END ==
lengthof(handler));
4801 uint8 feature = buf->ReadByte();
4802 uint8 numprops = buf->ReadByte();
4803 uint numinfo = buf->ReadByte();
4804 uint engine = buf->ReadExtendedByte();
4806 if (feature >= GSF_END) {
4807 grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4811 grfmsg(6,
"FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4812 feature, numprops, engine, numinfo);
4814 if (handler[feature] ==
nullptr) {
4815 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4822 while (numprops-- && buf->HasData()) {
4823 uint8 prop = buf->ReadByte();
4826 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4833 uint8 feature = buf->ReadByte();
4834 uint8 numprops = buf->ReadByte();
4835 uint numinfo = buf->ReadByte();
4836 buf->ReadExtendedByte();
4838 if (feature == GSF_BRIDGES && numprops == 1) {
4839 uint8 prop = buf->ReadByte();
4842 if (prop == 0x0D)
return;
4843 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4844 uint8 prop = buf->ReadByte();
4847 bool is_safe =
true;
4848 for (uint i = 0; i < numinfo; i++) {
4849 uint32 s = buf->ReadDWord();
4857 if (is_safe)
return;
4868 static void ReserveChangeInfo(
ByteReader *buf)
4870 uint8 feature = buf->ReadByte();
4872 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES)
return;
4874 uint8 numprops = buf->ReadByte();
4875 uint8 numinfo = buf->ReadByte();
4876 uint8 index = buf->ReadExtendedByte();
4878 while (numprops-- && buf->HasData()) {
4879 uint8 prop = buf->ReadByte();
4883 default: NOT_REACHED();
4889 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4893 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4897 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4901 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4905 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4926 uint8 feature = buf->ReadByte();
4927 uint16 num_sets = buf->ReadByte();
4928 uint16 first_set = 0;
4930 if (num_sets == 0 && buf->HasData(3)) {
4933 first_set = buf->ReadExtendedByte();
4934 num_sets = buf->ReadExtendedByte();
4936 uint16 num_ents = buf->ReadExtendedByte();
4938 if (feature >= GSF_END) {
4940 grfmsg(1,
"NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.
skip_sprites);
4946 grfmsg(7,
"New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4947 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4950 for (
int i = 0; i < num_sets * num_ents; i++) {
4960 uint16 num_sets = buf->ReadByte();
4962 if (num_sets == 0 && buf->HasData(3)) {
4965 buf->ReadExtendedByte();
4966 num_sets = buf->ReadExtendedByte();
4968 uint16 num_ents = buf->ReadExtendedByte();
4977 static const SpriteGroup *GetGroupFromGroupID(
byte setid,
byte type, uint16 groupid)
4979 if (
HasBit(groupid, 15)) {
4984 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
4985 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4989 return _cur.spritegroups[groupid];
5002 if (
HasBit(spriteid, 15)) {
5008 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
5013 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
5016 assert(spriteset_start + num_sprites <= _cur.
spriteid);
5037 uint8 feature = buf->ReadByte();
5038 if (feature >= GSF_END) {
5039 grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5043 uint8 setid = buf->ReadByte();
5044 uint8 type = buf->ReadByte();
5068 switch (
GB(type, 2, 2)) {
5069 default: NOT_REACHED();
5070 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
5071 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
5072 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
5082 adjust.variable = buf->ReadByte();
5083 if (adjust.variable == 0x7E) {
5085 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5090 varadjust = buf->ReadByte();
5091 adjust.shift_num =
GB(varadjust, 0, 5);
5092 adjust.type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
5093 adjust.and_mask = buf->ReadVarSize(varsize);
5095 if (adjust.type != DSGA_TYPE_NONE) {
5096 adjust.add_val = buf->ReadVarSize(varsize);
5097 adjust.divmod_val = buf->ReadVarSize(varsize);
5100 adjust.divmod_val = 0;
5104 }
while (
HasBit(varadjust, 5));
5106 std::vector<DeterministicSpriteGroupRange> ranges;
5107 ranges.resize(buf->ReadByte());
5108 for (uint i = 0; i < ranges.size(); i++) {
5109 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5110 ranges[i].low = buf->ReadVarSize(varsize);
5111 ranges[i].high = buf->ReadVarSize(varsize);
5114 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5115 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5117 group->calculated_result = ranges.size() == 0;
5120 std::vector<uint32> bounds;
5121 for (uint i = 0; i < ranges.size(); i++) {
5122 bounds.push_back(ranges[i].low);
5123 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5125 std::sort(bounds.begin(), bounds.end());
5126 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5128 std::vector<const SpriteGroup *> target;
5129 for (uint j = 0; j < bounds.size(); ++j) {
5130 uint32 v = bounds[j];
5132 for (uint i = 0; i < ranges.size(); i++) {
5133 if (ranges[i].low <= v && v <= ranges[i].high) {
5134 t = ranges[i].group;
5138 target.push_back(t);
5140 assert(target.size() == bounds.size());
5142 for (uint j = 0; j < bounds.size(); ) {
5143 if (target[j] != group->default_group) {
5145 r.group = target[j];
5147 while (j < bounds.size() && target[j] == r.group) {
5150 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5172 group->count = buf->ReadByte();
5175 uint8 triggers = buf->ReadByte();
5176 group->triggers =
GB(triggers, 0, 7);
5177 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5180 byte num_groups = buf->ReadByte();
5182 grfmsg(1,
"NewSpriteGroup: Random Action 2 nrand should be power of 2");
5185 for (uint i = 0; i < num_groups; i++) {
5186 group->
groups.push_back(GetGroupFromGroupID(setid, type, buf->ReadWord()));
5197 case GSF_ROADVEHICLES:
5208 byte num_loaded = type;
5209 byte num_loading = buf->ReadByte();
5212 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
5216 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5217 setid, num_loaded, num_loading);
5219 if (num_loaded + num_loading == 0) {
5220 grfmsg(1,
"NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
5224 if (num_loaded + num_loading == 1) {
5226 uint16 spriteid = buf->ReadWord();
5228 grfmsg(8,
"NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
5232 std::vector<uint16> loaded;
5233 std::vector<uint16> loading;
5235 for (uint i = 0; i < num_loaded; i++) {
5236 loaded.push_back(buf->ReadWord());
5237 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, loaded[i]);
5240 for (uint i = 0; i < num_loading; i++) {
5241 loading.push_back(buf->ReadWord());
5242 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
5245 if (std::adjacent_find(loaded.begin(), loaded.end(), std::not_equal_to<>()) == loaded.end() &&
5246 std::adjacent_find(loading.begin(), loading.end(), std::not_equal_to<>()) == loading.end() &&
5247 loaded[0] == loading[0])
5251 grfmsg(8,
"NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
5260 for (uint16 spriteid : loaded) {
5262 group->
loaded.push_back(t);
5265 for (uint16 spriteid : loading) {
5274 case GSF_AIRPORTTILES:
5276 case GSF_INDUSTRYTILES: {
5277 byte num_building_sprites = std::max((uint8)1, type);
5285 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
5289 case GSF_INDUSTRIES: {
5291 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5302 for (uint i = 0; i < 3; i++) {
5306 for (uint i = 0; i < 2; i++) {
5309 group->again = buf->ReadByte();
5310 }
else if (type == 1) {
5312 for (uint i = 0; i < 3; i++) {
5316 for (uint i = 0; i < 2; i++) {
5319 group->again = buf->ReadByte();
5320 }
else if (type == 2) {
5324 error->data =
"too many inputs (max 16)";
5327 for (uint i = 0; i < group->
num_input; i++) {
5328 byte rawcargo = buf->ReadByte();
5337 error->data =
"duplicate input cargo";
5346 error->data =
"too many outputs (max 16)";
5349 for (uint i = 0; i < group->
num_output; i++) {
5350 byte rawcargo = buf->ReadByte();
5357 error->data =
"duplicate output cargo";
5363 group->again = buf->ReadByte();
5371 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5376 _cur.spritegroups[setid] = act_group;
5379 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5381 if (feature == GSF_OBJECTS) {
5386 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5391 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
5392 if (ctype == 0xFF)
return CT_PURCHASE;
5397 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5402 if (cs->bitnum == ctype) {
5403 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5408 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5414 grfmsg(1,
"TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (
unsigned int)_cur.
grffile->
cargo_list.size() - 1);
5421 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5427 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));
5431 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);
5436 static bool IsValidGroupID(uint16 groupid,
const char *
function)
5438 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] ==
nullptr) {
5439 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
5446 static void VehicleMapSpriteGroup(
ByteReader *buf,
byte feature, uint8 idcount)
5449 static uint last_engines_count;
5450 bool wagover =
false;
5453 if (
HasBit(idcount, 7)) {
5456 idcount =
GB(idcount, 0, 7);
5458 if (last_engines_count == 0) {
5459 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5463 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5464 last_engines_count, idcount);
5466 if (last_engines_count != idcount) {
5467 last_engines =
ReallocT(last_engines, idcount);
5468 last_engines_count = idcount;
5473 for (uint i = 0; i < idcount; i++) {
5479 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
5483 engines[i] = e->
index;
5484 if (!wagover) last_engines[i] = engines[i];
5487 uint8 cidcount = buf->ReadByte();
5488 for (uint c = 0; c < cidcount; c++) {
5489 uint8 ctype = buf->ReadByte();
5490 uint16 groupid = buf->ReadWord();
5491 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
5493 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5495 ctype = TranslateCargo(feature, ctype);
5498 for (uint i = 0; i < idcount; i++) {
5501 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5504 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5506 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5511 uint16 groupid = buf->ReadWord();
5512 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5514 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5516 for (uint i = 0; i < idcount; i++) {
5520 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5522 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5529 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5532 for (uint i = 0; i < idcount; i++) {
5536 uint8 cidcount = buf->ReadByte();
5537 buf->Skip(cidcount * 3);
5539 uint16 groupid = buf->ReadWord();
5540 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5542 for (uint i = 0; i < idcount; i++) {
5546 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5556 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5558 uint8 *stations =
AllocaM(uint8, idcount);
5559 for (uint i = 0; i < idcount; i++) {
5560 stations[i] = buf->ReadByte();
5563 uint8 cidcount = buf->ReadByte();
5564 for (uint c = 0; c < cidcount; c++) {
5565 uint8 ctype = buf->ReadByte();
5566 uint16 groupid = buf->ReadWord();
5567 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5569 ctype = TranslateCargo(GSF_STATIONS, ctype);
5572 for (uint i = 0; i < idcount; i++) {
5575 if (statspec ==
nullptr) {
5576 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5584 uint16 groupid = buf->ReadWord();
5585 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5587 for (uint i = 0; i < idcount; i++) {
5590 if (statspec ==
nullptr) {
5591 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5596 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5603 StationClass::Assign(statspec);
5608 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5610 uint8 *houses =
AllocaM(uint8, idcount);
5611 for (uint i = 0; i < idcount; i++) {
5612 houses[i] = buf->ReadByte();
5616 uint8 cidcount = buf->ReadByte();
5617 buf->Skip(cidcount * 3);
5619 uint16 groupid = buf->ReadWord();
5620 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5622 if (_cur.
grffile->housespec ==
nullptr) {
5623 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5627 for (uint i = 0; i < idcount; i++) {
5630 if (hs ==
nullptr) {
5631 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5639 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5641 uint8 *industries =
AllocaM(uint8, idcount);
5642 for (uint i = 0; i < idcount; i++) {
5643 industries[i] = buf->ReadByte();
5647 uint8 cidcount = buf->ReadByte();
5648 buf->Skip(cidcount * 3);
5650 uint16 groupid = buf->ReadWord();
5651 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5653 if (_cur.
grffile->industryspec ==
nullptr) {
5654 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5658 for (uint i = 0; i < idcount; i++) {
5661 if (indsp ==
nullptr) {
5662 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5670 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5672 uint8 *indtiles =
AllocaM(uint8, idcount);
5673 for (uint i = 0; i < idcount; i++) {
5674 indtiles[i] = buf->ReadByte();
5678 uint8 cidcount = buf->ReadByte();
5679 buf->Skip(cidcount * 3);
5681 uint16 groupid = buf->ReadWord();
5682 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5684 if (_cur.
grffile->indtspec ==
nullptr) {
5685 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5689 for (uint i = 0; i < idcount; i++) {
5692 if (indtsp ==
nullptr) {
5693 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5701 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5704 for (uint i = 0; i < idcount; i++) {
5705 cargoes[i] = buf->ReadByte();
5709 uint8 cidcount = buf->ReadByte();
5710 buf->Skip(cidcount * 3);
5712 uint16 groupid = buf->ReadWord();
5713 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5715 for (uint i = 0; i < idcount; i++) {
5719 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5725 cs->group = _cur.spritegroups[groupid];
5729 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5731 if (_cur.
grffile->objectspec ==
nullptr) {
5732 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5736 uint8 *objects =
AllocaM(uint8, idcount);
5737 for (uint i = 0; i < idcount; i++) {
5738 objects[i] = buf->ReadByte();
5741 uint8 cidcount = buf->ReadByte();
5742 for (uint c = 0; c < cidcount; c++) {
5743 uint8 ctype = buf->ReadByte();
5744 uint16 groupid = buf->ReadWord();
5745 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5747 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5750 for (uint i = 0; i < idcount; i++) {
5753 if (spec ==
nullptr) {
5754 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5762 uint16 groupid = buf->ReadWord();
5763 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5765 for (uint i = 0; i < idcount; i++) {
5768 if (spec ==
nullptr) {
5769 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5774 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5784 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5786 uint8 *railtypes =
AllocaM(uint8, idcount);
5787 for (uint i = 0; i < idcount; i++) {
5788 uint8
id = buf->ReadByte();
5792 uint8 cidcount = buf->ReadByte();
5793 for (uint c = 0; c < cidcount; c++) {
5794 uint8 ctype = buf->ReadByte();
5795 uint16 groupid = buf->ReadWord();
5796 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5798 if (ctype >= RTSG_END)
continue;
5801 for (uint i = 0; i < idcount; i++) {
5806 rti->
group[ctype] = _cur.spritegroups[groupid];
5815 static void RoadTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount, RoadTramType rtt)
5819 uint8 *roadtypes =
AllocaM(uint8, idcount);
5820 for (uint i = 0; i < idcount; i++) {
5821 uint8
id = buf->ReadByte();
5825 uint8 cidcount = buf->ReadByte();
5826 for (uint c = 0; c < cidcount; c++) {
5827 uint8 ctype = buf->ReadByte();
5828 uint16 groupid = buf->ReadWord();
5829 if (!IsValidGroupID(groupid,
"RoadTypeMapSpriteGroup"))
continue;
5831 if (ctype >= ROTSG_END)
continue;
5834 for (uint i = 0; i < idcount; i++) {
5839 rti->
group[ctype] = _cur.spritegroups[groupid];
5848 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5850 uint8 *airports =
AllocaM(uint8, idcount);
5851 for (uint i = 0; i < idcount; i++) {
5852 airports[i] = buf->ReadByte();
5856 uint8 cidcount = buf->ReadByte();
5857 buf->Skip(cidcount * 3);
5859 uint16 groupid = buf->ReadWord();
5860 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5862 if (_cur.
grffile->airportspec ==
nullptr) {
5863 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5867 for (uint i = 0; i < idcount; i++) {
5870 if (as ==
nullptr) {
5871 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5879 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5881 uint8 *airptiles =
AllocaM(uint8, idcount);
5882 for (uint i = 0; i < idcount; i++) {
5883 airptiles[i] = buf->ReadByte();
5887 uint8 cidcount = buf->ReadByte();
5888 buf->Skip(cidcount * 3);
5890 uint16 groupid = buf->ReadWord();
5891 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5893 if (_cur.
grffile->airtspec ==
nullptr) {
5894 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5898 for (uint i = 0; i < idcount; i++) {
5901 if (airtsp ==
nullptr) {
5902 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5912 static void FeatureMapSpriteGroup(
ByteReader *buf)
5928 uint8 feature = buf->ReadByte();
5929 uint8 idcount = buf->ReadByte();
5931 if (feature >= GSF_END) {
5932 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5940 uint16 groupid = buf->ReadWord();
5941 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5943 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5952 grfmsg(6,
"FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5956 case GSF_ROADVEHICLES:
5959 VehicleMapSpriteGroup(buf, feature, idcount);
5963 CanalMapSpriteGroup(buf, idcount);
5967 StationMapSpriteGroup(buf, idcount);
5971 TownHouseMapSpriteGroup(buf, idcount);
5974 case GSF_INDUSTRIES:
5975 IndustryMapSpriteGroup(buf, idcount);
5978 case GSF_INDUSTRYTILES:
5979 IndustrytileMapSpriteGroup(buf, idcount);
5983 CargoMapSpriteGroup(buf, idcount);
5987 AirportMapSpriteGroup(buf, idcount);
5991 ObjectMapSpriteGroup(buf, idcount);
5995 RailTypeMapSpriteGroup(buf, idcount);
5999 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
6003 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
6006 case GSF_AIRPORTTILES:
6007 AirportTileMapSpriteGroup(buf, idcount);
6011 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
6035 bool new_scheme = _cur.
grffile->grf_version >= 7;
6037 uint8 feature = buf->ReadByte();
6038 if (feature >= GSF_END && feature != 0x48) {
6039 grfmsg(1,
"FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
6043 uint8 lang = buf->ReadByte();
6044 uint8 num = buf->ReadByte();
6045 bool generic =
HasBit(lang, 7);
6048 id = buf->ReadWord();
6049 }
else if (feature <= GSF_AIRCRAFT) {
6050 id = buf->ReadExtendedByte();
6052 id = buf->ReadByte();
6057 uint16 endid =
id + num;
6059 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
6060 id, endid, feature, lang);
6062 for (;
id < endid && buf->HasData();
id++) {
6063 const char *name = buf->ReadString();
6064 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
6068 case GSF_ROADVEHICLES:
6073 if (e ==
nullptr)
break;
6087 switch (
GB(
id, 8, 8)) {
6089 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6090 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6098 if (_cur.
grffile->stations ==
nullptr || _cur.
grffile->stations[
GB(
id, 0, 8)] ==
nullptr) {
6099 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
6106 if (_cur.
grffile->airtspec ==
nullptr || _cur.
grffile->airtspec[
GB(
id, 0, 8)] ==
nullptr) {
6107 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
6114 if (_cur.
grffile->housespec ==
nullptr || _cur.
grffile->housespec[
GB(
id, 0, 8)] ==
nullptr) {
6115 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
6122 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
6141 if (offset >= max_sprites) {
6142 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6143 uint orig_num = num;
6148 if (offset + num > max_sprites) {
6149 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
6150 uint orig_num = num;
6151 num = std::max(max_sprites - offset, 0);
6152 return orig_num - num;
6181 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
6183 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
6213 uint8 type = buf->ReadByte();
6214 uint16 num = buf->ReadExtendedByte();
6215 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6221 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6238 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6249 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
6256 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);
6266 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);
6278 bool dup_oneway_sprites = ((type == 0x09) && (offset + num <= SPR_ONEWAY_SLOPE_N_OFFSET));
6280 for (; num > 0; num--) {
6282 int load_index = (replace == 0 ? _cur.
spriteid++ : replace++);
6284 if (dup_oneway_sprites) {
6285 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_N_OFFSET);
6286 DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_S_OFFSET);
6356 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6386 *value = _game_mode;
6420 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
6429 *value = _openttd_newgrf_version;
6444 default:
return false;
6448 static uint32 GetParamVal(
byte param, uint32 *cond_val)
6466 if (cond_val ==
nullptr) {
6470 uint32 index = *cond_val / 0x20;
6486 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
6507 size_t pos = file.
GetPos();
6510 byte *preload_sprite =
nullptr;
6514 preload_sprite = MallocT<byte>(num);
6519 file.
SeekTo(pos, SEEK_SET);
6522 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
6523 free(preload_sprite);
6528 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6529 if (it != _grf_line_to_action6_sprite_override.end()) {
6530 free(preload_sprite);
6531 preload_sprite = _grf_line_to_action6_sprite_override[location];
6533 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6546 param_num = buf->ReadByte();
6547 if (param_num == 0xFF)
break;
6551 param_size = buf->ReadByte();
6555 add_value =
HasBit(param_size, 7);
6556 param_size =
GB(param_size, 0, 7);
6559 offset = buf->ReadExtendedByte();
6563 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6564 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6568 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6571 for (i = 0; i < param_size && offset + i < num; i++) {
6572 uint32 value = GetParamVal(param_num + i / 4,
nullptr);
6575 if (i % 4 == 0) carry =
false;
6578 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6579 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6581 carry = new_value >= 256;
6583 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6615 uint32 cond_val = 0;
6619 uint8 param = buf->ReadByte();
6620 uint8 paramsize = buf->ReadByte();
6621 uint8 condtype = buf->ReadByte();
6628 switch (paramsize) {
6629 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6630 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6631 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6632 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6636 if (param < 0x80 && _cur.grffile->param_end <= param) {
6637 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6641 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6646 if (condtype >= 0x0B) {
6677 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6679 }
else if (param == 0x88) {
6689 if (condtype != 10 && c ==
nullptr) {
6690 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6717 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6721 uint32 param_val = GetParamVal(param, &cond_val);
6723 case 0x00: result = !!(param_val & (1 << cond_val));
6725 case 0x01: result = !(param_val & (1 << cond_val));
6727 case 0x02: result = (param_val & mask) == cond_val;
6729 case 0x03: result = (param_val & mask) != cond_val;
6731 case 0x04: result = (param_val & mask) < cond_val;
6733 case 0x05: result = (param_val & mask) > cond_val;
6735 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6740 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6744 uint8 numsprites = buf->ReadByte();
6752 if (label.label != numsprites)
continue;
6755 if (choice ==
nullptr) choice = &label;
6757 if (label.nfo_line > _cur.
nfo_line) {
6763 if (choice !=
nullptr) {
6764 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6770 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6789 uint8 grf_version = buf->ReadByte();
6790 uint32 grfid = buf->ReadDWord();
6791 const char *name = buf->ReadString();
6795 if (grf_version < 2 || grf_version > 8) {
6797 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);
6805 if (buf->HasData()) {
6806 const char *info = buf->ReadString();
6824 uint8 version = buf->ReadByte();
6825 uint32 grfid = buf->ReadDWord();
6826 const char *name = buf->ReadString();
6829 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6833 if (_cur.
grffile->grfid != grfid) {
6834 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));
6838 _cur.
grffile->grf_version = version;
6856 uint8 num_sets = buf->ReadByte();
6858 for (uint i = 0; i < num_sets; i++) {
6859 uint8 num_sprites = buf->ReadByte();
6860 uint16 first_sprite = buf->ReadWord();
6862 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6863 i, num_sprites, first_sprite
6866 for (uint j = 0; j < num_sprites; j++) {
6867 int load_index = first_sprite + j;
6873 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6883 uint8 num_sets = buf->ReadByte();
6885 for (uint i = 0; i < num_sets; i++) {
6914 STR_NEWGRF_ERROR_VERSION_NUMBER,
6915 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6916 STR_NEWGRF_ERROR_UNSET_SWITCH,
6917 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6918 STR_NEWGRF_ERROR_LOAD_BEFORE,
6919 STR_NEWGRF_ERROR_LOAD_AFTER,
6920 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6924 STR_NEWGRF_ERROR_MSG_INFO,
6925 STR_NEWGRF_ERROR_MSG_WARNING,
6926 STR_NEWGRF_ERROR_MSG_ERROR,
6927 STR_NEWGRF_ERROR_MSG_FATAL
6930 byte severity = buf->ReadByte();
6931 byte lang = buf->ReadByte();
6932 byte message_id = buf->ReadByte();
6935 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6939 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6940 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6945 if (severity >=
lengthof(sevstr)) {
6946 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6948 }
else if (severity == 3) {
6958 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6959 grfmsg(7,
"GRFLoadError: Invalid message id.");
6963 if (buf->Remaining() <= 1) {
6964 grfmsg(7,
"GRFLoadError: No message data supplied.");
6973 if (message_id == 0xFF) {
6975 if (buf->HasData()) {
6976 const char *message = buf->ReadString();
6980 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6981 error->custom_message.clear();
6984 error->message = msgstr[message_id];
6987 if (buf->HasData()) {
6988 const char *data = buf->ReadString();
6992 grfmsg(7,
"GRFLoadError: No message data supplied.");
6993 error->data.clear();
6997 for (uint i = 0; i <
lengthof(
error->param_value) && buf->HasData(); i++) {
6998 uint param_number = buf->ReadByte();
7012 if (!buf->HasData())
return;
7014 const char *text = buf->ReadString();
7015 grfmsg(2,
"GRFComment: %s", text);
7021 uint8 target = buf->ReadByte();
7024 if (target < 0x80 || target == 0x9E)
return;
7038 static uint32 GetPatchVariable(uint8 param)
7048 case 0x0F:
return 0;
7064 case 0x11:
return SPR_2CCMAP_BASE;
7081 byte max_edge = std::max(log_X, log_Y);
7083 if (log_X == log_Y) {
7086 if (max_edge == log_Y)
SetBit(map_bits, 1);
7089 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7090 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7099 return SPR_SLOPES_BASE;
7110 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
7116 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
7129 for (uint i = start; i < num_ids; i++) {
7133 if (op == 2 || op == 3)
break;
7138 if (size == count)
break;
7141 if (size == count) {
7143 if (op == 0 || op == 3) {
7144 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7145 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
7151 if (op != 4 && op != 5) {
7153 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7158 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
7188 uint8 target = buf->ReadByte();
7189 uint8 oper = buf->ReadByte();
7190 uint32 src1 = buf->ReadByte();
7191 uint32 src2 = buf->ReadByte();
7194 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7203 if (target < 0x80 && target < _cur.grffile->param_end) {
7204 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
7208 oper =
GB(oper, 0, 7);
7212 if (
GB(data, 0, 8) == 0xFF) {
7213 if (data == 0x0000FFFF) {
7215 src1 = GetPatchVariable(src1);
7219 uint8 feature =
GB(data, 8, 8);
7220 uint16 count =
GB(data, 16, 16);
7222 if (_cur.
stage == GLS_RESERVE) {
7223 if (feature == 0x08) {
7227 if (_cur.
spriteid + count >= 16384) {
7228 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7234 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
7241 }
else if (_cur.
stage == GLS_ACTIVATION) {
7270 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7278 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
7289 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
7306 }
else if (src1 == 0xFE) {
7318 src1 = (src1 == 0xFF) ? data : GetParamVal(src1,
nullptr);
7319 src2 = (src2 == 0xFF) ? data : GetParamVal(src2,
nullptr);
7341 res = (int32)src1 * (int32)src2;
7345 if ((int32)src2 < 0) {
7346 res = src1 >> -(int32)src2;
7348 res = src1 << (src2 & 0x1F);
7353 if ((int32)src2 < 0) {
7354 res = (int32)src1 >> -(int32)src2;
7356 res = (int32)src1 << (src2 & 0x1F);
7380 res = (int32)src1 / (int32)src2;
7396 res = (int32)src1 % (int32)src2;
7400 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
7429 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7440 uint32 safe_bits = 0;
7441 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7450 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
7454 if (target < 0x80) {
7455 _cur.
grffile->param[target] = res;
7459 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
7473 uint8 num = buf->ReadByte();
7475 for (uint i = 0; i < num; i++) {
7476 uint32 grfid = buf->ReadDWord();
7498 uint8 num = buf->ReadByte();
7500 for (uint i = 0; i < num; i++) {
7501 uint32 grfid = buf->ReadDWord();
7505 if (file !=
nullptr && file != _cur.
grfconfig) {
7523 uint32 grfid = _cur.
grffile->grfid;
7527 byte id = buf->ReadByte();
7528 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
7533 bool new_scheme = _cur.
grffile->grf_version >= 7;
7535 byte lang = buf->ReadByte();
7537 byte nb_gen = townname->nb_gen;
7541 const char *name = buf->ReadString();
7544 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7546 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
7548 lang = buf->ReadByte();
7549 }
while (lang != 0);
7550 townname->id[nb_gen] = id;
7554 byte nb = buf->ReadByte();
7555 grfmsg(6,
"FeatureTownName: %u parts", nb);
7557 townname->nbparts[id] = nb;
7558 townname->partlist[id] = CallocT<NamePartList>(nb);
7560 for (
int i = 0; i < nb; i++) {
7561 byte nbtext = buf->ReadByte();
7562 townname->partlist[id][i].bitstart = buf->ReadByte();
7563 townname->partlist[id][i].bitcount = buf->ReadByte();
7564 townname->partlist[id][i].maxprob = 0;
7565 townname->partlist[id][i].partcount = nbtext;
7566 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7567 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);
7569 for (
int j = 0; j < nbtext; j++) {
7570 byte prob = buf->ReadByte();
7573 byte ref_id = buf->ReadByte();
7575 if (townname->nbparts[ref_id] == 0) {
7576 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7577 DelGRFTownName(grfid);
7582 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7583 townname->partlist[id][i].parts[j].data.
id = ref_id;
7585 const char *text = buf->ReadString();
7587 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7589 townname->partlist[id][i].parts[j].
prob = prob;
7590 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7592 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7604 byte nfo_label = buf->ReadByte();
7608 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", nfo_label);
7622 if (file ==
nullptr || file->sound_offset == 0) {
7623 grfmsg(1,
"ImportGRFSound: Source file not available");
7627 if (sound_id >= file->num_sounds) {
7628 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7632 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7634 *sound = *GetSound(file->sound_offset + sound_id);
7637 sound->volume = 128;
7638 sound->priority = 0;
7649 sound->volume = 0x80;
7650 sound->priority = 0;
7652 if (offs != SIZE_MAX) {
7654 sound->file = _cur.
file;
7655 sound->file_offset = offs;
7667 uint16 num = buf->ReadWord();
7668 if (num == 0)
return;
7671 if (_cur.
grffile->sound_offset == 0) {
7672 _cur.
grffile->sound_offset = GetNumSounds();
7673 _cur.
grffile->num_sounds = num;
7676 sound = GetSound(_cur.
grffile->sound_offset);
7681 for (
int i = 0; i < num; i++) {
7686 bool invalid = i >= _cur.
grffile->num_sounds;
7688 size_t offs = file.
GetPos();
7693 if (grf_container_version >= 2 && type == 0xFD) {
7696 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7698 }
else if (len != 4) {
7699 grfmsg(1,
"GRFSound: Invalid sprite section import");
7709 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7716 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7724 if (_cur.
stage == GLS_INIT) {
7725 if (grf_container_version >= 2) {
7726 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7735 if (_cur.
stage == GLS_ACTIVATION) {
7738 if (file.
ReadByte() != 0)
grfmsg(1,
"GRFSound: Import type mismatch");
7746 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7775 uint8 num_def = buf->ReadByte();
7777 for (uint i = 0; i < num_def; i++) {
7779 uint8 num_char = buf->ReadByte();
7780 uint16 base_char = buf->ReadWord();
7782 if (size >= FS_END) {
7783 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7786 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7788 for (uint c = 0; c < num_char; c++) {
7806 uint8 num_def = buf->ReadByte();
7808 for (uint i = 0; i < num_def; i++) {
7832 uint32 grfid = buf->ReadDWord();
7835 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7844 error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7854 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7855 byte num_strings = buf->ReadByte();
7856 uint16 first_id = buf->ReadWord();
7858 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7859 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7863 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7864 const char *
string = buf->ReadString();
7867 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7871 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7900 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7912 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7915 char data = buf->ReadByte();
7923 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7938 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7941 char data = buf->ReadByte();
7947 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7960 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7973 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7978 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
8009 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
8016 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
8026 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
8028 }
else if (len != 8) {
8029 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
8032 uint32 min_value = buf->ReadDWord();
8033 uint32 max_value = buf->ReadDWord();
8034 if (min_value <= max_value) {
8038 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
8047 if (len < 1 || len > 3) {
8048 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
8051 byte param_nr = buf->ReadByte();
8053 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
8069 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
8105 this->handler.data = handler;
8117 this->handler.text = handler;
8129 this->handler.call_handler =
true;
8130 this->handler.u.branch = handler;
8142 this->handler.call_handler =
false;
8143 this->handler.u.subtags =
subtags;
8172 byte type = buf->ReadByte();
8174 uint32
id = buf->ReadDWord();
8176 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8178 type = buf->ReadByte();
8182 byte langid = buf->ReadByte();
8183 const char *name_string = buf->ReadString();
8194 type = buf->ReadByte();
8219 byte type = buf->ReadByte();
8221 uint32
id = buf->ReadDWord();
8223 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8225 type = buf->ReadByte();
8238 type = buf->ReadByte();
8275 byte new_type = buf->ReadByte();
8276 while (new_type != 0) {
8279 new_type = buf->ReadByte();
8290 uint16 size = buf->ReadWord();
8314 while ((tag = &subtags[i++])->type != 0) {
8317 default: NOT_REACHED();
8320 byte langid = buf->ReadByte();
8321 return tag->handler.
text(langid, buf->ReadString());
8325 size_t len = buf->ReadWord();
8326 if (buf->Remaining() < len)
return false;
8327 return tag->handler.
data(len, buf);
8332 return tag->handler.u.branch(buf);
8338 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
8350 byte type = buf->ReadByte();
8352 uint32
id = buf->ReadDWord();
8353 if (!
HandleNode(type,
id, buf, subtags))
return false;
8354 type = buf->ReadByte();
8476 if (stations ==
nullptr)
continue;
8478 if (stations[i] ==
nullptr)
continue;
8495 HouseSpec **&housespec = file->housespec;
8496 if (housespec ==
nullptr)
continue;
8502 housespec =
nullptr;
8511 if (aslist !=
nullptr) {
8515 if (as !=
nullptr) {
8517 for (
int j = 0; j < as->
num_table; j++) {
8529 file->airportspec =
nullptr;
8533 if (airporttilespec !=
nullptr) {
8535 free(airporttilespec[i]);
8537 free(airporttilespec);
8538 airporttilespec =
nullptr;
8552 if (industryspec !=
nullptr) {
8559 industryspec =
nullptr;
8562 if (indtspec ==
nullptr)
continue;
8577 if (objectspec ==
nullptr)
continue;
8579 free(objectspec[i]);
8583 objectspec =
nullptr;
8615 CleanUpGRFTownNames();
8659 ObjectClass::Reset();
8664 StationClass::Reset();
8668 AirportClass::Reset();
8697 _grf_id_overrides.clear();
8699 InitializeSoundPool();
8747 if (newfile !=
nullptr) {
8753 newfile =
new GRFFile(config);
8771 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8776 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map),
INVALID_RAILTYPE);
8783 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map),
INVALID_ROADTYPE);
8787 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map),
INVALID_ROADTYPE);
8803 free(this->filename);
8813 CargoTypes original_known_cargoes = 0;
8814 for (
int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
8822 bool only_defaultcargo;
8825 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
8828 static constexpr
byte T = 1 << LT_TEMPERATE;
8829 static constexpr
byte A = 1 << LT_ARCTIC;
8830 static constexpr
byte S = 1 << LT_TROPIC;
8831 static constexpr
byte Y = 1 << LT_TOYLAND;
8832 static const struct DefaultRefitMasks {
8835 CargoTypes cargo_allowed;
8836 CargoTypes cargo_disallowed;
8837 } _default_refit_masks[] = {
8839 {T | A | S , CT_MAIL,
CC_MAIL, 0},
8842 {T | A , CT_COAL,
CC_BULK, 0},
8843 { S , CT_COPPER_ORE,
CC_BULK, 0},
8858 switch (ei->cargo_type) {
8862 _gted[engine].cargo_disallowed = 0;
8867 _gted[engine].cargo_disallowed = 0;
8886 _gted[engine].cargo_disallowed = 0;
8889 for (
const auto &drm : _default_refit_masks) {
8891 if (drm.cargo_type != ei->cargo_type)
continue;
8893 _gted[engine].cargo_allowed = drm.cargo_allowed;
8894 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
8911 CargoTypes mask = 0;
8912 CargoTypes not_mask = 0;
8913 CargoTypes xor_mask = ei->refit_mask;
8919 if (
_gted[engine].cargo_allowed != 0) {
8922 if (
_gted[engine].cargo_allowed & cs->classes)
SetBit(mask, cs->Index());
8923 if (
_gted[engine].cargo_disallowed & cs->classes)
SetBit(not_mask, cs->Index());
8927 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8945 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8947 const uint8 *cargo_map_for_first_refittable =
nullptr;
8950 if (file ==
nullptr) file = e->
GetGRF();
8951 if (file !=
nullptr && file->grf_version >= 8 && file->
cargo_list.size() != 0) {
8952 cargo_map_for_first_refittable = file->
cargo_map;
8956 if (cargo_map_for_first_refittable !=
nullptr) {
8958 byte best_local_slot = 0xFF;
8960 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8961 if (local_slot < best_local_slot) {
8962 best_local_slot = local_slot;
8963 ei->cargo_type = cargo_type;
8985 for (uint i = 0; i < CF_END; i++) {
8997 if (e->
GetGRF() ==
nullptr) {
9000 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
9033 default: NOT_REACHED();
9047 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
9048 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
9072 if (filename !=
nullptr)
Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
9082 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);
9090 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
9097 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);
9116 if (hs ==
nullptr || !hs->
enabled)
continue;
9121 if (min_year == 0)
return;
9125 if (hs ==
nullptr || !hs->
enabled)
continue;
9149 HouseSpec **&housespec = file->housespec;
9150 if (housespec ==
nullptr)
continue;
9155 if (hs ==
nullptr)
continue;
9213 if (industryspec !=
nullptr) {
9217 if (indsp !=
nullptr && indsp->
enabled) {
9223 if (strid != STR_UNDEFINED) indsp->
name = strid;
9226 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
9241 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
9249 if (indtspec !=
nullptr) {
9252 if (indtsp !=
nullptr) {
9253 _industile_mngr.SetEntitySpec(indtsp);
9262 for (uint i = 0; i < 3; i++) {
9267 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9281 if (objectspec !=
nullptr) {
9283 if (objectspec[i] !=
nullptr && objectspec[i]->grf_prop.grffile !=
nullptr && objectspec[i]->
enabled) {
9300 if (airportspec !=
nullptr) {
9302 if (airportspec[i] !=
nullptr && airportspec[i]->enabled) {
9303 _airport_mngr.SetEntitySpec(airportspec[i]);
9309 if (airporttilespec !=
nullptr) {
9311 if (airporttilespec[i] !=
nullptr && airporttilespec[i]->enabled) {
9312 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9325 static void DecodeSpecialSprite(
byte *buf, uint num, GrfLoadingStage stage)
9339 static const SpecialSpriteHandler handlers[][GLS_END] = {
9340 {
nullptr, SafeChangeInfo,
nullptr,
nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9341 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9342 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, NewSpriteGroup, },
9343 {
nullptr,
GRFUnsafe,
nullptr,
nullptr,
nullptr, FeatureMapSpriteGroup, },
9344 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, FeatureNewName, },
9345 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9346 {
nullptr,
nullptr,
nullptr, CfgApply, CfgApply, CfgApply, },
9347 {
nullptr,
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, },
9348 { ScanInfo,
nullptr,
nullptr, GRFInfo, GRFInfo, GRFInfo, },
9349 {
nullptr,
nullptr,
nullptr, SkipIf, SkipIf, SkipIf, },
9350 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9351 {
nullptr,
nullptr,
nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9352 {
nullptr,
nullptr,
nullptr, GRFComment,
nullptr, GRFComment, },
9354 {
nullptr, SafeGRFInhibit,
nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9357 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9360 {
StaticGRFInfo,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, },
9365 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9366 if (it == _grf_line_to_action6_sprite_override.end()) {
9372 buf = _grf_line_to_action6_sprite_override[location];
9373 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
9383 byte action = bufp->ReadByte();
9385 if (action == 0xFF) {
9386 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
9387 }
else if (action == 0xFE) {
9388 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
9389 }
else if (action >=
lengthof(handlers)) {
9390 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9391 }
else if (handlers[action][stage] ==
nullptr) {
9392 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9394 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9395 handlers[action][stage](bufp);
9398 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9414 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config->
filename);
9417 if (grf_container_version == 0) {
9418 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9422 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9428 if (grf_container_version >= 2) file.
ReadDword();
9431 if (grf_container_version >= 2) {
9433 byte compression = file.
ReadByte();
9434 if (compression != 0) {
9435 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
9444 if (num == 4 && file.
ReadByte() == 0xFF) {
9447 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
9455 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
9461 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
9472 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
9473 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9477 if (grf_container_version >= 2 && type == 0xFD) {
9500 const char *filename = config->
filename;
9511 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9513 if (_cur.
grffile ==
nullptr)
usererror(
"File '%s' lost in cache.\n", filename);
9520 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
9574 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
9575 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9576 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2);
9577 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9578 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9579 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9590 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9594 int *grf_overrides =
AllocaM(
int, num_grfs);
9595 for (
int i = 0; i < num_grfs; i++) {
9596 grf_overrides[i] = -1;
9599 uint32
override = _grf_id_overrides[source->grfid];
9600 if (
override == 0)
continue;
9603 if (dest ==
nullptr)
continue;
9606 assert(grf_overrides[i] >= 0);
9610 for (
int i = 0; i < num_grfs; i++) {
9611 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9619 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9622 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
9628 for (
int i = num_grfs - 1; i >= 0; i--) {
9629 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9637 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9640 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
9646 for (
int i = 0; i < num_grfs; i++) {
9647 if (grf_overrides[i] < 0)
continue;
9655 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9656 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9658 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
9666 if (file->grf_version >= 8)
continue;
9667 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9668 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9670 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9673 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9680 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9681 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9682 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9684 price_base_multipliers[p] = 0;
9689 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file->
filename, p);
9691 price_base_multipliers[p] = 0;
9693 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file->
filename, p);
9708 _string_to_grf_mapping.clear();
9711 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9714 _grf_line_to_action6_sprite_override.clear();
9777 if (file ==
nullptr ||
_gted[e->
index].roadtramtype == 0) {
9786 if (
_gted[e->
index].roadtramtype < list->size())
9788 RoadTypeLabel rtl = (*list)[
_gted[e->
index].roadtramtype];
9806 e->u.rail.railtype = railtype;
9816 _grm_sprites.clear();
9864 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9871 if (stage == GLS_RESERVE) {
9872 static const uint32 overrides[][2] = {
9873 { 0x44442202, 0x44440111 },
9874 { 0x6D620402, 0x6D620401 },
9875 { 0x4D656f20, 0x4D656F17 },
9877 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9883 uint num_non_static = 0;
9892 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->
filename);
9901 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9903 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9912 if (stage == GLS_RESERVE) {
9914 }
else if (stage == GLS_ACTIVATION) {
9919 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur.
spriteid);